/*
 * home.css — die oeffentliche KUNDEN-Startseite (Route "/").
 *
 * Warum eine eigene Datei und nicht landing.css: die beiden Seiten sprechen zwei
 * verschiedene Zielgruppen und haben deshalb zwei verschiedene Rhythmen. landing.css
 * ist 113 KB fuer eine Seite mit vierzehn Modulkarten; hier traegt die erste
 * Bildschirmseite ein Formular mit drei Feldern. Eine gemeinsame Datei haette beiden
 * Seiten die Zwaenge der jeweils anderen auferlegt.
 *
 * DIE TOKENS SIND ABSICHTLICH DIESELBEN WIE IN templates/directory.html. Die
 * Kundenkette ist "/" -> "/djs" -> "/dj/{slug}" -> Anfrage; sie muss sich wie EINE
 * Oberflaeche anfuehlen. Die DJ-Verkaufsseite (/fuer-djs) behaelt ihre eigene Palette,
 * weil sie ein anderes Publikum bedient.
 */

/* Die Schrift wird im <head> per <link> geladen, NICHT hier per @import.
   Ein @import am Kopf einer Stylesheet-Datei ist ein SERIELLER Wasserfall: der
   Browser muss erst home.css holen und parsen, dann das Font-CSS, dann die
   Schriftdateien - drei Runden hintereinander, bevor der erste Buchstabe in der
   richtigen Schrift steht. Als <link> laufen die ersten beiden parallel. */

:root {
  --bg: #07070b;
  --bg-raised: #0d0d14;
  --bg-white: rgba(255, 255, 255, 0.055);
  --bg-white-2: rgba(255, 255, 255, 0.085);
  --border: rgba(255, 255, 255, 0.1);
  --border-strong: rgba(255, 255, 255, 0.18);
  --text: #f7f7fb;
  --text-secondary: #c7c5d0;
  --text-muted: #8f8a9b;

  --accent: #8B1538;
  --accent-hover: #a41a44;
  --accent-soft: rgba(139, 21, 56, 0.22);
  /* Der Akzent als TEXT. #8B1538 auf #07070b misst 2,2:1 und faellt damit durch AA;
     die aufgehellte Stufe derselben Farbe misst 8,4:1. Es ist kein zweiter Akzent,
     sondern derselbe Farbton in der Helligkeit, die lesbarer Text braucht. Auf
     getoenten Flaechen gilt weiterhin: weisses Label, nicht Akzent-auf-Akzent. */
  --accent-ink: #e08199;

  --radius: 14px;
  --radius-lg: 24px;
  --radius-pill: 999px;
  --shadow-md: 0 18px 58px rgba(0, 0, 0, 0.28);
  --shadow-lg: 0 28px 90px rgba(0, 0, 0, 0.38);

  --shell: 1200px;
  --header-h: 72px;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* KEIN `overflow-x: hidden` hier. Es wuerde waagerechten Ueberlauf nicht
     verhindern, sondern verstecken - und damit den rendernden Waechter
     (tests-visual/oeffentliche-flaechen.spec.mjs) fuer die ganze Seite blind
     machen: unter einem klemmenden Body gilt jedes Element als beschnitten.
     Ueberlauf wird dort behoben, wo er entsteht. */
}

img { max-width: 100%; }

a { color: var(--accent-ink); }

:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 3px;
  border-radius: 6px;
}

.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;
}

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--accent); color: #fff;
  padding: 12px 18px; border-radius: 10px;
  font-weight: 600; text-decoration: none;
  transition: top .18s ease;
}
.skip-link:focus { top: 12px; }

.shell {
  width: 100%;
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 22px;
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  font-family: inherit; font-weight: 600; font-size: 15px;
  padding: 12px 22px;
  min-height: 48px;
  border-radius: 12px;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background .2s ease, border-color .2s ease, transform .2s ease;
}
.btn-primary { background: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); color: #fff; }
.btn-secondary {
  background: var(--bg-white); color: var(--text); border-color: var(--border);
}
.btn-secondary:hover { background: var(--bg-white-2); border-color: var(--border-strong); color: var(--text); }
.btn-large { padding: 15px 28px; font-size: 16px; min-height: 54px; }
.btn-header { min-height: 42px; padding: 9px 18px; font-size: 14px; }

/* ── Kopfzeile ────────────────────────────────────────────────────────────── */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(7, 7, 11, 0.86);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--border);
}
.header-shell {
  display: flex; align-items: center; gap: 18px;
  min-height: var(--header-h);
}
.brand {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: var(--text);
  /* Hier stand bis 2026-08-27 die Zusicherung, der Tap-Diebstahl unter 356px sei
     mit `flex: 0 1 auto; min-width: 0` behoben. Er war es nicht - die Zusicherung
     war das eigentliche Problem, weil sie die naechste Messung ueberfluessig
     erscheinen liess. Gemessen bei 320px: a.brand hatte Breite 0, das 34px-Logobild
     wurde ausserhalb seines Kastens gezeichnet (x 16..50), und div.lang-switch
     begann bei x 26. Ein Klick auf die Logomitte schaltete die SPRACHE um statt zu
     navigieren - in DE bis 344px, in EN bis 342px, in ES bis 348px hinauf.
     `min-width: 0` war dabei NICHT die Ursache: die Kopfzeile war ueberbucht
     (Bedarf 342px gegen 288px Inhaltsbreite bei 320px in ES), und der Markenblock
     war nur das einzige nachgiebige Kind. Behoben wird das dort, wo die
     Ueberbuchung entsteht - siehe die 420px-Regel weiter unten.
     `min-width: auto` steht hier nur noch, weil es der Standardwert fuer Flex-Kinder
     ist und damit nichts behauptet - das vorherige `min-width: 0` sah nach Absicht
     aus, ohne je eine zu haben. WIRKUNG HAT ES KEINE: eine Gegenprobe hat die Regel
     entfernt und dieselbe Seite gemessen, das Ergebnis war identisch. Hier stand
     bis 2026-08-27 die Behauptung, sie sei ein "harter Boden" gegen kuenftige
     Stauchung; sie war es nicht, und eine Zusicherung ohne Messung ist genau der
     Fehler, den der Absatz darueber beschreibt.
     Was diese Klasse WIRKLICH deckt, ist ein Waechter, nicht eine CSS-Zeile:
     tests-visual/kopfzeile-drei-sprachen.spec.mjs prueft drei Seiten x drei Sprachen
     ueber ein dichtes Breitenraster von 280 bis 1920 auf drei Formen - was an der
     Stelle des Logos wirklich getroffen wird, ob ein Block aus seiner eigenen Spur
     quillt, und ob zwei Kopfzeilenbloecke einander ueberlappen. Die frueher hier
     genannte tests-visual/oeffentliche-flaechen.spec.mjs kann es nicht: sie faehrt
     zwei Breiten und nur Deutsch.
     Widerlegen: node tests-visual/kopfzeile-drei-sprachen-probe.mjs (beide
     Richtungen, `fail=0`). */
  flex: 0 1 auto; min-width: auto;
}
.brand-mark { display: flex; flex: none; }
.brand-mark img { border-radius: 8px; display: block; }
.brand-copy { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.brand-copy strong { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.brand-copy span {
  font-size: 11px; color: var(--text-muted);
  letter-spacing: .06em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.site-nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.nav-link {
  color: var(--text-secondary); text-decoration: none;
  font-size: 14px; font-weight: 500;
  white-space: nowrap;
  padding: 9px 12px; border-radius: 9px;
  min-height: 44px; display: inline-flex; align-items: center;
  transition: color .2s ease, background .2s ease;
}
.nav-link:hover { color: var(--text); background: var(--bg-white); }

.header-actions { display: flex; align-items: center; gap: 10px; flex: none; }
.nav-crossdoor {
  color: var(--text-muted); text-decoration: none;
  /* Gleiche Groesse wie der Knopf daneben (.btn-header, 14px). Unterschieden wird
     ueber Gewicht und Farbe, nicht ueber die Groesse - ein kleinerer Text neben
     einem Knopf liest sich als Fussnote, nicht als zweite Tuer. */
  font-size: 14px; font-weight: 500;
  padding: 9px 10px; border-radius: 9px;
  min-height: 44px; display: inline-flex; align-items: center;
  white-space: nowrap;
  transition: color .2s ease;
}
.nav-crossdoor:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }

.menu-toggle {
  display: none;
  width: 44px; height: 44px;
  flex: none;
  background: var(--bg-white); border: 1px solid var(--border);
  border-radius: 10px;
  cursor: pointer;
  padding: 0;
  align-items: center; justify-content: center;
  flex-direction: column; gap: 5px;
}
.menu-toggle span {
  display: block; width: 17px; height: 2px;
  background: var(--text); border-radius: 2px;
  transition: transform .22s ease, opacity .22s ease;
}
.menu-toggle.is-open span:first-child { transform: translateY(3.5px) rotate(45deg); }
.menu-toggle.is-open span:last-child { transform: translateY(-3.5px) rotate(-45deg); }

.mobile-menu {
  display: none;
  border-top: 1px solid var(--border);
  background: var(--bg);
}
.mobile-menu.is-open {
  display: block;
  /* CM501: the open menu locks the page (body.menu-open) -- so it has to scroll itself.
     Without a bound it grew past a low viewport (812x375 landscape: "Du bist DJ?" at
     y 384-434) and nothing could bring its last link into view. The header column below
     caps header + menu at the viewport height; the menu takes the rest and scrolls. */
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.mobile-menu-inner {
  display: flex; flex-direction: column; gap: 4px;
  padding: 14px 22px 20px;
  max-width: var(--shell); margin: 0 auto;
}
.mobile-link {
  color: var(--text); text-decoration: none;
  font-size: 16px; font-weight: 500;
  padding: 13px 4px; min-height: 48px;
  display: flex; align-items: center;
  border-bottom: 1px solid var(--border);
}
.mobile-link--crossdoor { color: var(--text-muted); font-size: 15px; border-bottom: none; }
.mobile-actions { display: flex; flex-direction: column; gap: 10px; padding-top: 14px; }
.mobile-actions .btn { width: 100%; }
body.menu-open { overflow: hidden; }
body.menu-open .site-header {
  display: flex;
  flex-direction: column;
  max-height: 100vh;
  max-height: 100dvh;
}
body.menu-open .header-shell { flex: none; }

/* ── Hero ─────────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  padding: 72px 0 64px;
  /* Die Bildflaeche liegt HINTER dem Text, nicht daneben. Das Motiv traegt seinen
     Inhalt rechts und ist links fast schwarz; der Verlauf darueber zieht die linke
     Haelfte zusaetzlich auf fast volle Deckung, damit die Ueberschrift dort auf
     einer ruhigen Flaeche steht statt auf Bilddetail.
     Reihenfolge beachten: der Verlauf steht VOR dem Bild, liegt also darueber. */
  background-color: var(--bg);
  /* `background-image` steht NICHT hier, sondern im <style>-Block von home.html.
     Grund: die Bild-URL braucht eine inhaltsabgeleitete Versionsmarke (`?v=`), und
     `static/` wird als Datei ausgeliefert, bekommt also keine Token ersetzt. Der
     Umweg ueber eine Custom Property scheidet aus - eine `url()` darin wird dort
     aufgeloest, wo sie BENUTZT wird, also gegen diese Datei, und landete gemessen
     auf `/static/static/img/...`. Die Verlaeufe muessen mitwandern, weil sie
     Ebenen DERSELBEN Eigenschaft sind. */
  background-size: cover, cover, cover;
  background-position: center, center, center right;
  background-repeat: no-repeat;
}
.hero-shell { display: flex; flex-direction: column; gap: 20px; }
.hero-eyebrow {
  margin: 0;
  font-size: 12px; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent-ink);
}
.hero h1 {
  margin: 0;
  font-size: clamp(2.1rem, 6.2vw, 3.6rem);
  line-height: 1.08;
  letter-spacing: -.03em;
  font-weight: 800;
  max-width: 17ch;
  text-wrap: balance;
}
.hero-lead {
  margin: 0;
  font-size: clamp(1rem, 2.2vw, 1.18rem);
  color: var(--text-secondary);
  /* 52ch statt 60ch: auf Tablet reichte der Satz bis 78 % der Breite und damit in
     die hellste Zone des Motivs - gemessen 3,82:1, also unter AA. Schmaler ist
     hier beides, lesbarer UND besser gesetzt. */
  max-width: 52ch;
}

/* ── Suchleiste ───────────────────────────────────────────────────────────── */
.finder {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr) minmax(0, 1.1fr) auto;
  gap: 10px;
  align-items: end;
  padding: 14px;
  margin-top: 6px;
  background: var(--bg-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}
.finder-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.finder-field label {
  font-size: 11px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-muted);
  padding-left: 2px;
}
.finder-field input,
.finder-field select {
  font-family: inherit; font-size: 15px;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 11px;
  padding: 12px 14px;
  min-height: 50px;
  width: 100%;
  min-width: 0;
  appearance: none;
  -webkit-appearance: none;
}
/* Ohne diese Regel rendert Chrome das Kalendersymbol fast schwarz auf fast
   schwarz — auf einer dunklen Flaeche ist das Feld dann scheinbar leer. */
.finder-field input[type="date"]::-webkit-calendar-picker-indicator {
  filter: invert(1);
  opacity: .7;
  cursor: pointer;
}
.finder-field select {
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238f8a9b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 18px;
  padding-right: 38px;
}
.finder-field select option { background: var(--bg-raised); color: var(--text); }
.finder-field input::placeholder { color: var(--text-muted); }
.finder-field input:focus, .finder-field select:focus { border-color: var(--accent-ink); }
.finder-submit { min-height: 50px; }

.hero-note {
  margin: 0;
  font-size: 13.5px;
  color: var(--text-muted);
  max-width: 68ch;
}

.hero-proof {
  list-style: none; margin: 8px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px 22px;
}
.hero-proof li {
  display: flex; align-items: center; gap: 9px;
  font-size: 14px; color: var(--text-secondary);
}
.proof-ico { width: 17px; height: 17px; color: var(--accent-ink); flex: none; }

/* ── Sektionen ────────────────────────────────────────────────────────────── */
.section { padding: 72px 0; }
.section-kicker {
  margin: 0 0 10px;
  font-size: 12px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-ink);
}
.section h2 {
  margin: 0 0 14px;
  font-size: clamp(1.6rem, 3.6vw, 2.35rem);
  line-height: 1.16;
  letter-spacing: -.024em;
  font-weight: 700;
  max-width: 22ch;
  text-wrap: balance;
}
.section p { color: var(--text-secondary); max-width: 65ch; }

/* ── Ablauf ───────────────────────────────────────────────────────────────── */
.steps {
  list-style: none; margin: 32px 0 0; padding: 0;
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}
.step {
  background: var(--bg-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 26px 24px 28px;
  display: flex; flex-direction: column; gap: 10px;
}
.step-num {
  font-size: 13px; font-weight: 700;
  letter-spacing: .12em;
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
}
.step h3 { margin: 0; font-size: 1.18rem; font-weight: 700; letter-spacing: -.012em; }
.step p { margin: 0; font-size: 14.5px; }

/* ── Warum ────────────────────────────────────────────────────────────────── */
.why-shell {
  display: grid; gap: 32px;
  grid-template-columns: 1fr;
  align-items: start;
}
.why-copy { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; }
.why-copy h2 { margin: 0; }
.why-copy p { margin: 0; }
.why-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 12px;
}
.why-list li {
  background: var(--bg-white);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 6px var(--radius) var(--radius) 6px;
  padding: 18px 20px;
  display: flex; flex-direction: column; gap: 5px;
}
.why-list strong { font-size: 15px; font-weight: 700; }
.why-list span { font-size: 14px; color: var(--text-secondary); }

/* ── Roster ───────────────────────────────────────────────────────────────── */
.roster-head {
  display: flex; flex-wrap: wrap; gap: 12px 20px;
  align-items: flex-end; justify-content: space-between;
  margin-bottom: 26px;
}
.roster-head h2 { margin: 0; }
.roster-all {
  color: var(--text-secondary); text-decoration: none;
  font-size: 14px; font-weight: 600;
  padding: 11px 16px; min-height: 44px;
  display: inline-flex; align-items: center;
  border: 1px solid var(--border); border-radius: 11px;
}
.roster-all:hover { color: var(--text); border-color: var(--border-strong); }

.roster {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
}
/* Unterhalb der Schwelle laeuft das Raster als Streifen. Warum ueberhaupt zwei
   Darstellungen: ein dreispaltiges Raster mit zwei Karten zeigt eine leere dritte
   Spalte und behauptet damit ein Angebot, das es nicht gibt. Der Streifen behauptet
   nichts. Die Umschaltung entscheidet home.js an der ECHTEN Zahl. */
.roster.is-strip {
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 340px));
  justify-content: start;
}
.roster-loading, .roster-empty {
  grid-column: 1 / -1;
  margin: 0; padding: 34px 20px;
  text-align: center;
  color: var(--text-muted);
  background: var(--bg-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}

.dj-card {
  display: flex; flex-direction: column;
  background: var(--bg-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: border-color .2s ease, transform .2s ease;
}
.dj-card:hover { border-color: var(--border-strong); transform: translateY(-2px); }
.dj-card-media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--bg-raised);
  overflow: hidden;
}
/* Zwei Ebenen, wie im Verzeichnis: der unscharfe Hintergrund fuellt die Kachel,
   das eigentliche Bild bleibt VOLLSTAENDIG sichtbar. Ein `cover` allein schneidet
   Koepfe ab, und ein Portraitbild ist das einzige Bild, das dieser DJ hat. */
.dj-card-backdrop {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: blur(22px) saturate(1.15);
  transform: scale(1.18);
  opacity: .55;
}
.dj-card-photo {
  position: relative;
  width: 100%; height: 100%;
  object-fit: contain;
  object-position: center top;
}
.dj-card-fallback {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 2.1rem; font-weight: 800; letter-spacing: .04em;
  color: var(--text-muted);
  background: linear-gradient(160deg, rgba(139, 21, 56, 0.22), rgba(255, 255, 255, 0.04));
}
.dj-card-body { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 9px; flex: 1; }
.dj-card-name { margin: 0; font-size: 1.12rem; font-weight: 700; letter-spacing: -.012em; }
.dj-card-tagline {
  margin: 0; font-size: 14px; color: var(--text-secondary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  line-clamp: 2;
  overflow: hidden;
}
.dj-card-meta {
  margin: 0; font-size: 13px; color: var(--text-muted);
  display: flex; flex-wrap: wrap; gap: 4px 12px;
}
.dj-card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; padding-top: 4px; }
.dj-tag {
  font-size: 11.5px; font-weight: 600;
  letter-spacing: .03em;
  padding: 5px 9px;
  border-radius: var(--radius-pill);
  background: var(--bg-white-2);
  border: 1px solid var(--border);
  color: var(--text-secondary);
}
/* Weisses Label auf getoenter Flaeche — Akzent-Text auf Akzent-Tint faellt bei
   dieser Groesse durch WCAG AA. */
.dj-tag--match { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ── FAQ ──────────────────────────────────────────────────────────────────── */
.faq-shell { display: grid; gap: 28px; grid-template-columns: 1fr; align-items: start; }
.faq-intro h2 { margin: 0; }
.faq-list { display: grid; gap: 10px; }
.faq-item {
  background: var(--bg-white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0 20px;
}
.faq-item summary {
  cursor: pointer;
  list-style: none;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 18px 0;
  min-height: 44px;
  font-size: 16px; font-weight: 600;
  color: var(--text);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-sign { position: relative; width: 14px; height: 14px; flex: none; }
.faq-sign::before, .faq-sign::after {
  content: ""; position: absolute; background: var(--accent-ink);
  border-radius: 2px;
  transition: transform .2s ease, opacity .2s ease;
}
.faq-sign::before { left: 0; top: 6px; width: 14px; height: 2px; }
/* Ein echtes Plus/Minus: der senkrechte Strich verschwindet beim Oeffnen. Bewusst
   zwei Striche und kein Textzeichen — "+"/"−" rendern je nach Plattform anders. */
.faq-sign::after { left: 6px; top: 0; width: 2px; height: 14px; }
.faq-item[open] .faq-sign::after { transform: scaleY(0); opacity: 0; }
.faq-item > p { margin: 0; padding: 0 0 20px; font-size: 15px; max-width: 68ch; }

/* ── Band fuer DJs ────────────────────────────────────────────────────────── */
.dj-band-section { padding-bottom: 88px; }
.dj-band {
  display: flex; flex-wrap: wrap; gap: 24px;
  align-items: center; justify-content: space-between;
  background: linear-gradient(150deg, rgba(139, 21, 56, 0.20), rgba(255, 255, 255, 0.04));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 34px 32px;
}
.dj-band > div { flex: 1 1 420px; min-width: 0; }
.dj-band h2 { margin: 0 0 10px; font-size: clamp(1.4rem, 3vw, 1.9rem); }
.dj-band p { margin: 0; font-size: 15px; }
.dj-band .btn { flex: none; }

/* ── Fusszeile ────────────────────────────────────────────────────────────── */
.site-footer { border-top: 1px solid var(--border); padding: 40px 0 48px; }
.footer-shell { display: flex; flex-direction: column; gap: 18px; }
.footer-links { display: flex; flex-wrap: wrap; gap: 6px 22px; }
.footer-links a {
  color: var(--text-secondary); text-decoration: none;
  font-size: 14px;
  padding: 10px 0; min-height: 44px;
  display: inline-flex; align-items: center;
}
.footer-links a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.footer-brand { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--text-muted); }
.footer-brand img { border-radius: 6px; }
.footer-copy { margin: 0; font-size: 13px; color: var(--text-muted); }

/* ── Breiten ──────────────────────────────────────────────────────────────── */
@media (min-width: 880px) {
  .why-shell { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; }
  .why-list { grid-template-columns: 1fr; }
  .faq-shell { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: 48px; }
  .faq-intro { position: sticky; top: calc(var(--header-h) + 24px); }
}

@media (max-width: 1024px) {
  .finder { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .finder-submit { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
  .site-nav { display: none; }
  .menu-toggle { display: flex; }
  .header-actions { margin-left: auto; }
  /* Unter 900px hat die Kopfzeile Platz fuer genau EINE Textzeile neben Marke und
     Menueknopf. Die zweite Tuer wandert ins Menue, wo sie unverkuerzt steht — sie
     abzuschneiden waere schlimmer als sie zu verschieben. */
  .nav-crossdoor { display: none; }
}

@media (max-width: 620px) {
  .shell { padding: 0 16px; }
  .hero { padding: 44px 0 48px; }
  .section { padding: 52px 0; }
  .dj-band-section { padding-bottom: 64px; }
  .finder { grid-template-columns: 1fr; padding: 12px; gap: 12px; }
  .btn-header { padding: 9px 14px; }
  /* Unter dieser Breite passen Wortmarke, Sprachumschalter und Hauptaktion nicht
     mehr nebeneinander. Der Zusatz allein auszublenden reicht NICHT: `.brand-copy`
     ist ein Flex-Kind und wird dann auf 0 px gestaucht, waehrend "Crewmate" mangels
     `overflow` weiter gezeichnet wird - gemessen bei 375 px 0 px Kastenbreite gegen
     79 px Textbreite, der Schriftzug lag also quer ueber dem Sprachumschalter.
     `/fuer-djs` blendet an derselben Stelle den ganzen Block aus; diese Seite tat es
     nicht. Der Logo-Klotz traegt die Marke in dieser Breite allein. */
  .brand-copy { display: none; }
  .dj-band { padding: 26px 22px; }
  .dj-band .btn { width: 100%; }
  .faq-item { padding: 0 16px; }
  .hero-proof { gap: 8px 16px; }
  .mobile-menu-inner { padding: 12px 16px 18px; }
}

/* BEFUND 1 (gemessen 2026-08-27, lokal und live): unterhalb dieser Breite ist die
   Kopfzeile der Kundenseite UEBERBUCHT, und sie war es unbemerkt, weil der einzige
   nachgiebige Teil - der Markenblock - lautlos auf 0px fiel, waehrend sein
   34px-Logobild weiter gezeichnet wurde. Der Sprachumschalter (144px, per
   PublicI18n.mount an .header-actions gehaengt) lag darueber und fing den Tap ab:
   ein Klick auf die Logomitte kippte documentElement.lang von en auf de, statt zur
   Startseite zu navigieren.

   Die Zahlen bei 320px (Inhaltsbreite 288px = 320 minus 2x16 Schalenpolsterung):
     Bedarf = 34 (Logo) + 10 (gap) + 240/238/244 (Aktionsblock DE/EN/ES)
              + 10 (gap) + 44 (Menueknopf) = 338/336/342.
   Es fehlen also 48 bis 54px. Kein Kuerzen von Abstaenden holt das herein - drei
   44px-Tap-Ziele plus Knopf plus Logo passen dort schlicht nicht nebeneinander.

   Also gibt EIN Posten nach, und zwar der groesste UND der einzige, der
   unverkuerzt eine Zeile tiefer weitersteht: das Mobilmenue traegt denselben
   Umschalter in voller Breite (PublicI18n.mount('.mobile-menu-inner',
   {variant:'block'}) in templates/home.html). Er wandert also, er verschwindet
   nicht. /fuer-djs faellt dieselbe Entscheidung seit jeher
   (landing.css: `.header-actions > *:not(.btn-primary) { display: none }`);
   die Kundenseite hatte sie nur nie uebernommen. Die Hauptaktion bleibt bewusst
   stehen - sie ist der Zweck der Seite, die Sprachwahl eine Einmalhandlung.

   Die Schwelle ist gemessen, und das KRITERIUM gehoert dazu - ohne es ist eine
   Schwellenzahl nicht nachpruefbar, und zwei Leser messen zwei verschiedene Dinge.
   Hier stand zuerst "erstmals bei 399px (ES)"; diese Zahl hat keine der beiden
   Nachmessungen reproduziert.
   KRITERIUM: ein Klick auf die Logomitte trifft die Marke UND das Dokument laeuft
   nicht waagerecht ueber. Gemessen mit entfernter 420er-Regel, 1-px-Schritte,
   zwoelf saubere Breiten am Stueck als Bestaetigung:
       de 345px · en 343px · es 341px
   420px liegt ueber allen dreien und zugleich oberhalb der 380px-Schwelle, an der
   der gap von 10 auf 18px waechst - sonst entstuende ein Negativsprung, die Seite
   wuerde beim BREITERWERDEN enger (derselbe Fehler, den landing.css bei 359/360px
   schon einmal bezahlt hat).

   Widerlegbar - und zwar am VERHALTEN, nicht an der Geometrie (Sprache auf EN,
   Logomitte antippen, ueber das ganze Band). Vor dieser Regel meldete er
   280..344 (DE), 280..342 (EN), 280..348 (ES); danach nichts:
     node -e "const{chromium}=require('@playwright/test');(async()=>{const b=await chromium.launch();for(const l of['de','en','es']){const c=await b.newContext();await c.addInitScript(x=>localStorage.setItem('lang',x),l);const p=await c.newPage();await p.goto('http://127.0.0.1:8099/');await p.waitForTimeout(900);for(let w=280;w<=460;w+=2){await p.setViewportSize({width:w,height:900});const t=await p.evaluate(()=>{const a=document.querySelector('a.brand'),r=a.querySelector('img').getBoundingClientRect(),e=document.elementFromPoint(r.left+r.width/2,r.top+r.height/2);return a.contains(e)});if(!t)console.log('LOGO VERDECKT '+l+' @'+w)}await c.close()}await b.close()})()" */
@media (max-width: 420px) {
  .header-actions .lang-switch { display: none; }
}

@media (max-width: 380px) {
  /* Bei 375px ist die Kopfzeile die engste Stelle der Seite. Der Knopftext wird
     kuerzer, damit der Aktionsblock nicht weiter gegen die Marke draengt.
     Hier stand bis 2026-08-27 "bevor irgendetwas ueberlappt" - das war zur selben
     Zeit falsch, in der es dastand: bei 375px lag der Sprachumschalter auf dem
     Logo. Die Ueberlappung verhindert die 420px-Regel darueber, nicht diese. */
  .btn-header { padding: 9px 12px; font-size: 13px; }
  .header-shell { gap: 10px; }
}

/* BEFUND 3: das zweite Nadeloehr liegt NICHT am unteren Rand, sondern unmittelbar
   oberhalb der Mobilschwelle. Ab 901px erscheint die Desktop-Navigation
   (380/376/371px DE/EN/ES) ZUSAETZLICH zu Marke und Aktionsblock, und die Reihe
   ist erneut ueberbucht: gemessen bei 904px steht eine Inhaltsbreite von 860px
   gegen einen Bedarf von 975/938/981px. Nachgegeben hat wieder der einzige
   nachgiebige Teil: .brand-copy hatte bei 901px 34px Kastenbreite gegen 79px
   Textbreite, "Crewmate" wurde also ausserhalb seines Kastens gezeichnet
   (overflow-x: visible), bis 944/952/928px hinauf.

   Der Ausweg ist derselbe wie bei 620px und derselbe, den /fuer-djs in seinem
   engsten Desktopband nimmt: der Schriftzug gibt nach, die Logomarke traegt die
   Marke allein, und JEDES Bedienelement bleibt vollstaendig und antippbar.
   Bewusst KEIN overflow:hidden auf .brand-copy: das wuerde die Stauchung
   verstecken statt sie zu verhindern und den rendernden Waechter fuer die
   naechste blind machen - dieselbe Begruendung wie beim fehlenden
   `overflow-x: hidden` am body weiter oben.

   Beide Kanten sind gemessen. Untere: ohne den Schriftzug braucht die Reihe bei
   901px nur 813/809/798px von 857px. Obere: die VOLLE Reihe passt erst ab
   1019/982/1025px (Inhaltsbreite = Fensterbreite minus 44px Schalenpolsterung),
   also gibt 1060px 35px Luft im schlechtesten Fall (ES).

   Wer diese Regel zum Pruefen herausnimmt, bekommt heute ein SCHWAECHERES Rot als
   die Zahlen oben - und das gehoert dazu, sonst haelt der naechste Leser die Sonde
   fuer defekt: der harte Boden an .brand (min-width: auto, siehe dort) hebt den
   gestauchten Kasten von 34px auf 118/71/139px, damit deckt er "Crewmate" (79px)
   in DE und ES bereits ab. Gemessen ohne diese Regel bleibt EN uebrig, 902..954px
   mit bis zu 8px. Zwei Regeln, zwei verschiedene Haelften desselben Fehlers - die
   eine hebt den Boden, die andere nimmt die Last weg. */
@media (min-width: 901px) and (max-width: 1059px) {
  .brand-copy { display: none; }
}


/* ── Anlaesse ──────────────────────────────────────────────────────────────
   Vier Kacheln, die zugleich vier Einstiege in den Verzeichnis-Filter sind.
   Das Bild ist dekorativ (alt="" + aria-hidden): die Beschriftung steht als
   echter Text daneben, ein wiederholender alt-Text waere fuer Screenreader
   nur Laerm. */
.anlass-grid {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  display: grid;
  gap: 14px;
  /* Feste Spaltenzahlen statt auto-fit: bei SECHS Kacheln laesst auto-fit auf
     breiten Schirmen vier in der ersten und zwei in der zweiten Reihe stehen -
     eine halb leere Reihe liest sich wie ein Fehler. 3x2 / 2x3 / 6x1 geht auf. */
  grid-template-columns: 1fr;
}
@media (min-width: 640px) { .anlass-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .anlass-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.anlass-tile {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  color: var(--text);
  background: var(--bg-raised);
  transition: border-color .2s ease, transform .2s ease;
}
.anlass-tile:hover { border-color: var(--accent); transform: translateY(-2px); }
.anlass-tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .35s ease;
}
.anlass-tile:hover img { transform: scale(1.04); }
.anlass-copy {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 46px 18px 16px;
  /* Der Verlauf ist die Lesbarkeit, nicht die Deko: ohne ihn steht weisser Text
     auf wechselndem Bildinhalt und faellt je nach Kachel durch AA. */
  background: linear-gradient(to top, rgba(7, 7, 11, 0.94) 0%, rgba(7, 7, 11, 0.78) 45%, transparent 100%);
}
.anlass-copy strong { font-size: 1.02rem; font-weight: 700; letter-spacing: -.01em; }
.anlass-copy span { font-size: 13px; color: var(--text-secondary); }
.anlass-note { margin: 16px 0 0; font-size: 14px; color: var(--text-muted); }

@media (max-width: 620px) {
  .anlass-grid { gap: 12px; }
  .anlass-tile { aspect-ratio: 16 / 9; }
}
