/* ============================================================================
   Emsland Beach Festival — Design und Layout
   ----------------------------------------------------------------------------
   **Systemstylesheet aus baggi-hp, nur die Marke getauscht.** Token (Farben,
   Schriften) stehen weiter unten mit Emsland-Werten; die Bausteine selbst
   sind unverändert die der Vorlage. Wo ein Kommentar von „der bestehenden
   Seite" oder „dem Original" spricht und Maße begründet, meint er die
   Vorlage baggi-hp — das sind Systemmaße, hier nicht nachgemessen.

   Neu in diesem Projekt: `.hero--vollbild` (Abschnitt Hero) und
   `body:not(:has(.kopf))` (Grundlage). Beides zurück in die Vorlage.

   Keine Inline-Styles. Die Content-Security-Policy fuehrt style-src 'self'
   ohne unsafe-inline; was aus der API kommt, wird als <img> oder
   textContent gesetzt, nie als style-Attribut.
   ========================================================================== */

/* ------------------------------------------------------------- Schriften -- */

/* **Zwei Familien mit klarer Aufgabenteilung**, beide variabel, zusammen
   105 KB.

   Die Displayschrift (hier Nexa, in baggi-hp Montserrat) ist als geometrische Display-Schrift gezeichnet und traegt
   grosse Versalien — Ueberschriften, Knoepfe, Navigation und die fetten
   Etiketten. Inter ist als Oberflaechenschrift gezeichnet und bleibt im
   Absatz ruhig; Montserrat wirkt dort auf Dauer unruhig, weil ihre runden
   Formen und weiten Punzen fuer grosse Grade gemacht sind.

   Die bestehende WordPress-Seite nennt im `body` die Familie „Titillium",
   laedt aber nie eine passende Datei — gerendert wird dort ueberall
   Montserrat, auch im Fliesstext.

   **Beide Dateien werden vorgeladen.** Fliesstext und Hero-Titel stehen
   gleichzeitig ueber der Falz; eine der beiden nachzuladen hiesse, dass
   genau dort umgebrochen wird. Wer die Familien tauscht, muss die
   `<link rel="preload">` in allen Seiten **und** in `tools/build.py`
   mitziehen — sonst laedt die Seite eine Datei vor, die sie nicht nutzt,
   und die, die sie braucht, erst spaet.

   Nicht enthalten sind Emoji; die kommen ohnehin aus der Systemschrift.
   Ebenso wenig der Pfeil U+2192, deshalb zeichnet das CSS ihn selbst
   (siehe `.knopf::after`). Kyrillisch fehlt in beiden Dateien gleichermassen
   — einzelne Eventtexte aus Clubinio fallen dort auf die Systemschrift,
   wie bisher schon. */
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Nexa Text Black — die Displayschrift der bestehenden Seite, von dort
   übernommen (wp-content/uploads/2025/09/). Nur der schwarze Schnitt: Er
   ist der einzige, den Überschriften tragen. Lizenz liegt beim
   Veranstalter, siehe fonts/LIZENZEN.md. */
@font-face {
  font-family: 'Nexa';
  src: url('../fonts/nexa-black.woff2') format('woff2');
  font-weight: 800 900;
  font-style: normal;
  font-display: swap;
}

/* ----------------------------------------------------------------- Token -- */

:root {
  /* Flaechen. Die Werte stammen aus dem Elementor-Kit der bestehenden Seite. */
  /* Seitengrund. **Nicht reines Schwarz.** Die bestehende Seite fuehrt
     durchgehend ein sehr dunkles Grau; reines #000 wirkt besonders auf
     OLED-Displays wie ein Loch, weil die Pixel dort wirklich aus sind und
     es keinerlei Abstufung zum Inhalt gibt. Ein paar Punkte Helligkeit
     geben der Flaeche Tiefe, ohne sie aufzuhellen. */
  /* Emsland Beach Festival: Grund und Box aus den Clubinio-Designwerten
     (designBackgroundColor / designBoxColor). Die bestehende Seite ist auf
     der Startseite vollflächig pink; Impressum und Datenschutz stehen hier
     dunkel, weil weiße Fließschrift auf dem Pink nur 3,93:1 erreicht. */
  --nacht:        #0a0a0f;   /* Seitengrund — Clubinio designBackgroundColor */
  --box:          #16161d;   /* Karten, Kaesten — Clubinio designBoxColor */
  --box-hell:     #202028;   /* abgesetzte Flaeche in einer Box */
  --flaeche:      #16161d;   /* Abschnittsgrund, wo er sich abheben soll */
  --karte:        #16161d;   /* Eventkarten */
  --kopf:         #0a0a0f;   /* Kopfzeile, sobald sie deckend wird */
  --linie:        #2a2a33;   /* Trenner und Rahmen */

  /* Schrift: zwei Ebenen mit klarer Aufgabe. */
  --schrift-display: 'Nexa', 'Inter', system-ui, sans-serif;
  --schrift-text:    'Inter', system-ui, -apple-system, sans-serif;

  /* Schrift. */
  --tinte:        #ffffff;
  --tinte-leise:  #b4b4b4;
  --tinte-still:  #7d7d7d;
  /* Dieselbe Tinte als Zahlentripel. Getoente Flaechen — der graue
     Zweitknopf, Eingabefelder — mischen sich daraus mit Alpha, statt
     festes Weiss zu nennen. Dieselbe Rolle wie in top10-balingen-hp. */
  --tinte-rgb:    255 255 255;

  /* Akzent der Marke. */
  /* **Zwei Rottoene im Bestand.** Clubinio fuehrt fuer diesen Shop
     `#F0011D`, die Knoepfe der bestehenden Seite messen `#cc2026`. Hier
     gilt der gemessene Knopfwert, weil er das ist, was ein Gast sieht;
     der Clubinio-Wert steuert nur Widgets, die wir nicht benutzen. */
  /* Emsland Beach Festival: **gemessen** `rgb(238 48 124)` als Seitengrund
     von emslandbeachfestival.de. Clubinio führt `#EB3E77` — dieselbe Farbe
     einen Hauch heller; es gilt der gemessene Wert, weil ihn der Gast sieht.
     Weiß darauf: 3,93:1 — reicht für große Schrift und Knöpfe in Versalien
     nicht für Fließtext. Deshalb der Schleier in `.hero--vollbild`. */
  --akzent:       #ee307c;
  /* Schrift auf dem Akzent — Schwarz, weil Gelbgruen sonst nichts traegt. */
  --akzent-tinte: #ffffff;
  /* Derselbe Akzent als reines Zahlentripel. `rgb()` mit Alpha laesst sich
     nicht aus einem Hex-Token bauen — ohne das hier stuenden Verlaeufe und
     Fokusringe mit fest verdrahteter Farbe im Stylesheet und blieben beim
     naechsten Projekt gelbgruen stehen. */
  --akzent-rgb:   238 48 124;

  /* **Derselbe Akzent als Schriftfarbe — und das ist nicht derselbe Wert.**

     Als Flaeche traegt `#cc2026` muehelos: Weiss darauf messe ich 5,52:1.
     Als Schrift auf dem Seitengrund kippt es: 3,52:1 gegen `#0d0d0d`,
     3,02:1 gegen den Fuss `#1e1e1e` — beides unter den 4,5:1, die WCAG AA
     fuer Fliesstext fordert. Das steht an 25 Stellen im Stylesheet, vom
     Fussverweis bis zum Pflichtsternchen.

     Deshalb zwei Token statt einem Kompromiss. Gleicher Farbton (358 Grad),
     gleiche Saettigung, nur angehoben: 5,46:1 auf dem Grund, 4,69:1 im
     Fuss. Wer eine Flaeche faerbt, nimmt `--akzent`; wer Schrift faerbt,
     `--akzent-text`. Ein einziger Wert fuer beides geht nicht, ohne dass
     eine der beiden Rollen leidet. */
  /* Emsland: #ff5c9a — 6,82:1 auf --nacht, 6,21:1 auf --box. */
  --akzent-text:  #ff5c9a;

  /* **Die zweite Markenfarbe.** Die bestehende Seite fuehrt den Clubbetrieb
     in Rot und die Vermietung in Gruen — im geteilten Hero stehen beide
     nebeneinander, Augenbraue und Knopf je Haelfte. Gemessen `#00a878`.

     Weiss darauf ergibt **3,06:1** — zu wenig fuer die 14px-Knopfschrift,
     die das Original dort setzt. Die Fuellung bleibt der gemessene Wert,
     die Schrift darauf wird der Seitengrund: **6,36:1**. Derselbe Griff
     wie beim Partnerknopf auf /business/.

     Als Schriftfarbe auf dem abgedunkelten Foto braucht `#00a878` dagegen
     keine Korrektur — gegen `#0d0d0d` sind es ebenfalls 6,36:1. Es gibt
     hier also kein `--gruen-text`; anders als beim Rot faellt Fuellung und
     Schrift zusammen. */
  --gruen:        #00a878;
  --gruen-rgb:    0 168 120;
  --gruen-tinte:  #0d0d0d;
  /* Gruen des Veranstaltungspartners Trend ID. Siehe `.knopf-partner`:
     gemessen `#4caf50`, hier eine Stufe dunkler, damit weisse Schrift
     darauf traegt (5,13:1 statt 2,78:1). */
  --gruen-partner: #2e7d32;

  /* Rundungen. Gestaffelt nach Flaechengroesse — ein einheitlicher Radius
     laesst kleine Elemente verspielt und grosse Flaechen hart wirken. */
  /* **Scharfe Ecken, durchgehend.** Die bestehende Seite setzt ueberall
     `border-radius: 0` — Knoepfe, Eventkarten, Eingabefelder. Das ist kein
     Versehen, sondern der Charakter der Marke: kantig statt freundlich.
     Die Token bleiben trotzdem stehen, damit eine spaetere Rundung an
     einer Stelle entschieden wird und nicht an fuenfzig. */
  --r-knopf:      0;
  --r-feld:       0;
  --r-karte:      0;
  --r-klein:      0;

  /* Weiche Schatten statt Rahmen, wo etwas abheben soll. */
  --schatten:     0 1px 2px rgb(0 0 0 / 30%), 0 8px 24px rgb(0 0 0 / 35%);
  --schatten-hoch: 0 2px 4px rgb(0 0 0 / 35%), 0 16px 40px rgb(0 0 0 / 45%);

  /* Deckung des dunklen Schleiers ueber dem Bildabschnitt.

     **Projekteigen, weil das Foto es ist.** Die Regel in `.abschnitt-bild`
     ist in allen Projekten dieselbe; wie stark sie abdunkeln muss, haengt
     am Bild darunter und an der Farbe der Schrift darauf.
     Wert der bestehenden Seite. */
  --bild-schleier: 48%;

  /* Uebergang mit leichtem Ueberschwingen — nicht linear, nicht traege. */
  --kurve:        cubic-bezier(0.32, 0.72, 0, 1);

  /* Haken fuer die eigenen Kaestchen. Als data:-Adresse im Stylesheet und
     nicht als eigene Datei: 200 Byte sind keinen zweiten Abruf wert. */
  /* Gegenstueck zum Haken, fuer die Fehlermeldung. */
  --ausruf: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23ffffff' d='M7 2h2v7H7zM7 11h2v2H7z'/%3E%3C/svg%3E");
  --haken: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round' d='M3.2 8.6l3.1 3.1 6.5-6.9'/%3E%3C/svg%3E");

  /* Masse. */
  /* **Gemessen, nicht uebernommen.** Die bestehende Seite fuehrt eine
     Spalte von 1280px mit 32px Polster — innen also 1216px, linke Kante
     bei 144px in einem 1504er Fenster. Mit den 1200/40 der Vorlage waren
     es 1120px innen und die Kante bei 156: der ganze Inhalt stand 12
     Pixel weiter innen und war 96 Pixel schmaler. Das faellt auf jeder
     Seite auf, auch ohne Vergleichsbild daneben. */
  --breite:       1280px;
  --breite-schmal: 760px;
  --gutter:       clamp(1rem, 4vw, 2rem);
  /* Hoehe der Kopfzeile. Hero, Bannerversatz, Menue und Ankersprung
     rechnen damit — weicht der Wert von der tatsaechlichen Hoehe ab,
     verschiebt sich der Inhalt um die Differenz.

     **Zwei Werte, weil die Zeile nicht ueberall gleich hoch ist.** Ihre
     Hoehe ergibt sich aus dem hoechsten Kind plus Polster: auf dem
     Schreibtisch das Logo (46px), auf dem Telefon der Menueknopf (44px).
     Mit einem einzigen Wert klaffte zwischen Kopfzeile und aufgeklapptem
     Menue eine Luecke von 2px, durch die das Bild schien.
     Nachgemessen: 82px / 80px. */
  --kopf-hoehe:   80px;

  /* Typografie. Die Skala ist die der bestehenden Seite (36/50/60/85 px),
     hier als clamp(), damit sie auf dem Telefon nicht ueberlaeuft. */
  /* Gemessen auf baggi-hp: Hero und Seitentitel 72px,
     Abschnittsueberschriften 60px, Fliesstext-Ueberschriften 36px,
     Kartentitel 20px. Als clamp(), damit nichts auf dem Telefon
     ueberlaeuft. */
  --t-hero:   clamp(2.75rem, 8vw, 4.5rem);      /* bis 72px */
  --t-h1:     clamp(2.25rem, 7vw, 4.5rem);      /* bis 72px */
  --t-h2:     clamp(1.75rem, 5.5vw, 3.75rem);   /* bis 60px */
  /* **Zweite H2-Groesse fuer Ueberschriften im Fliesstext.** Die lange
     Satzueberschrift in baggi-hp ist ein ganzer Satz; auf 60px nimmt er sieben Zeilen ein und
     erschlaegt den Absatz, den er einleitet. Das Original setzt ihn auf
     36px — eine halb so grosse Stufe fuer eine andere Aufgabe. */
  --t-h2-text: clamp(1.5rem, 3.6vw, 2.25rem);   /* bis 36px */
  --t-h3:     clamp(1.125rem, 3vw, 1.25rem);    /* bis 20px */
  --t-text:   1rem;        /* 16px — gemessen */
  --t-klein:  0.875rem;
}

/* --------------------------------------------------------------- Grundlage -- */

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

/* Gegenstueck zur festen Kopfzeile: Sie belegt keinen Platz im Fluss, also
   muss der Inhalt ihn selbst mitbringen. Die beiden Werte gehoeren
   zusammen — siehe `.kopf`. */
body { padding-top: var(--kopf-hoehe); }
/* Seite ohne Kopfzeile (emslandbeach-hp, `.hero--vollbild`): kein Versatz. */
body:not(:has(.kopf)) { padding-top: 0; }

/* Sicherheitsnetz gegen seitliches Verschieben. Die randlose Bildstrecke
   rechnet die Scrollleiste bereits heraus (`--sb`); das hier faengt ab, was
   kuenftig dazukommt, ohne dass es jemandem auffaellt.

   `clip`, nicht `hidden`: `overflow: hidden` an einem Vorfahren setzt
   `position: sticky` ausser Kraft, und die Kopfzeile klebt. */
html, body { overflow-x: clip; }

/* `hidden` muss gewinnen. Der Browser setzt dafuer nur `display: none` mit
   schwacher Spezifitaet — jede eigene display-Regel schlaegt es. Genau das
   ist passiert: `.knopf { display: inline-flex }` hat ein `hidden` am
   Lounge-Knopf ueberstimmt, und der stand auf jeder Eventseite, obwohl ihn
   nichts eingeblendet hatte. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  /* Anker sollen nicht unter der festen Kopfzeile landen. */
  scroll-padding-top: calc(var(--kopf-hoehe) + 1rem);
}

/* Wer Bewegung abbestellt hat, bekommt auch kein sanftes Scrollen. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--nacht);
  color: var(--tinte);
  font-family: var(--schrift-text);
  font-size: var(--t-text);
  /* 26px auf 16px — gemessen. Vorher 1,7, was bei 15px 25,5px ergab und
     den Text zugleich kleiner und luftiger machte als im Original. */
  line-height: 1.625;
  -webkit-font-smoothing: antialiased;
}

/* Menue offen oder Lightbox aktiv: der Hintergrund darf nicht mitscrollen. */
html.menu-offen, html.lb-aktiv { overflow: hidden; }

img, video { max-width: 100%; height: auto; display: block; }

a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible, summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--akzent);
  outline-offset: 3px;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--schrift-display);
  /* **800, nicht 900.**

     Die bestehende Seite laedt die Schnittdatei unter dem eigenen Namen
     „Montserrat-ExtraBold" und setzt sie mit `font-weight: 400` — das
     sieht nach Normalgewicht aus, ist aber ExtraBold, also 800. Wir
     fahren dieselbe Familie als variable Schrift und mussten die Stufe
     deshalb selbst benennen; die Vorlage nannte 900.

     Nachgemessen in baggi-hp bei 36px: live 366,7px, bei
     uns 370,5px mit 900 und **366,7px mit 800** — auf die Nachkommastelle
     derselbe Wert. Das ist der Unterschied, der die Ueberschriften breiter
     und schwerer wirken liess, ohne dass man sagen konnte, woran es liegt. */
  font-weight: 800;
  /* **Zwei Zeilenhoehen, nach Aufgabe getrennt.**

     Grosse Ueberschriften stehen im Original auf **1,0** — „EVENTS" mit
     72px/72px, „DEMNÄCHST" mit 60px/60px. Das sind ein bis zwei Woerter,
     die als Block wirken sollen.

     Ueberschriften im Fliesstext stehen auf **1,25** (36px/45px), ebenso
     die Kartentitel (20px/25px). Das sind ganze Saetze, und auf 1,0
     kleben ihre Zeilen aneinander.

     Die Vorlage fuhr pauschal 1,08 — zu eng fuer die Saetze und zu weit
     fuer die Schlagworte. Der Grundwert hier ist die kleine Stufe; die
     grossen setzen ihn bei sich auf 1 zurueck. */
  line-height: 1.25;
  text-transform: uppercase;
  /* **Positiv gesperrt, nicht negativ.** Die Geschwisterprojekte ziehen
     ihre Versalueberschriften mit `-0.02em` zusammen, weil Montserrat im
     schwersten Schnitt breit laeuft. Die Vorlage baggi-hp macht das
     Gegenteil und sperrt auf: gemessen 3,6px auf 72px und 3px auf 60px —
     beides 0,05em. Das ist der Charakter der Marke, kein Versehen, und
     einer der Unterschiede, die man sofort sieht. */
  letter-spacing: 0.05em;
}

/* **Fette Etiketten tragen ebenfalls Montserrat.**

   Die Ueberschriftenregel oben deckt nur h1 bis h4. Alles andere, was fett
   und in Versalien steht, haengt sonst am Fliesstext und faellt auf Inter —
   still, weil es weiter fett bleibt und nur die Formen wechseln.

   **`.infokasten dd` gehoert nicht dazu.** Das sind die Werte — „21.
   November 2026", „Einlass ab 18 Jahren", die Anschrift —, also
   Fliesstext in ganzen Woertern. Die bestehende Seite setzt sie in
   Inter; nur die Beschriftung darueber ist Montserrat. Mit der
   Vorlagenregel standen hier drei Zeilen Anschrift in einer Schrift, die
   fuer kurze Versalien gezeichnet ist.

   Was bleibt: der Termin und der Ort auf der Eventkarte, die Datumszeile
   der Eventseite, die Feldbeschriftung im Infokasten, die FAQ-Frage, der
   Zurueck-Verweis, die Kennzahl der Fehlerseite und der Sprunglink.
   Alles kurze, laute Zeilen — genau das, wofuer Montserrat gezeichnet
   ist. */
.karte-datum,
.karte-ort,
.karte-mehr,
.event-datum,
.infokasten dt,
.faq summary,
.zurueck,
.fehlerseite .kennzahl,
.sprung {
  font-family: var(--schrift-display);
}

/* Gegenstueck dazu: Der Infokasten erbt seine Schrift sonst vom Etikett
   darueber, sobald jemand die Liste oben wieder ergaenzt. */
.infokasten dd { font-family: var(--schrift-text); }

/* 20px zwischen Absaetzen — gemessen. Die Vorlage fuhr 16px; bei drei
   Absaetzen untereinander summiert sich das sichtbar. */
p { margin: 0 0 1.25rem; }
p:last-child { margin-bottom: 0; }

/* Nur fuer Lesegeraete — etwa die H1 der Startseite. */
.nur-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.sprung {
  position: absolute;
  left: -9999px;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--akzent);
  color: var(--akzent-tinte);
  font-weight: 700;
}
.sprung:focus { left: 1rem; top: 1rem; }

/* ---------------------------------------------------------------- Raster -- */

.huelle {
  width: 100%;
  max-width: var(--breite);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.huelle-schmal { max-width: var(--breite-schmal); }

.abschnitt { padding-block: clamp(3.5rem, 9vw, 7rem); }
.abschnitt-flaeche { background: var(--flaeche); }

/* Der Eventabschnitt liegt im Original auf einem Clubfoto mit dunklem
   Schleier (Deckung 0,48). Das Bild steht im CSS und nicht als <img> im
   Markup, weil es Zierde ist und keinen Inhalt traegt. */
.abschnitt-bild {
  position: relative;
  padding-block: clamp(3.5rem, 9vw, 6.25rem);
  /* Dasselbe Foto wie der Seitenkopf von /events/ — eine Datei, zwei
     Verwendungen. Wer von der Startseite weitergeht, hat sie schon. */
  background: url('../img/banner/events.webp') center center / cover no-repeat;
  isolation: isolate;
}
.abschnitt-bild::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgb(0 0 0 / var(--bild-schleier));
}

/* Abschnittskopf: Ueberschrift plus Unterzeile, zentriert. */
.kopfzeile { text-align: center; margin-bottom: clamp(2rem, 5vw, 3.5rem); }
.kopfzeile h2 { font-size: var(--t-h2); line-height: 1; }
.kopfzeile p {
  margin: 0.75rem 0 0;
  color: var(--tinte-leise);
  text-transform: none;
}
/* Die Unterzeilen unter „Next Events" und „Einblick" stehen im Original in
   der Akzentfarbe, nicht gedaempft. */
.kopfzeile .unterzeile { color: var(--akzent-text); font-weight: 400; }

/* ---------------------------------------------------------------- Knoepfe -- */

.knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  /* 12px/24px Polster, Zeilenhoehe 20px, **kein Rahmen** — alles gemessen.
     Zusammen ergibt das die 44px Hoehe des Originals; mit dem 1,5px-Rahmen
     der Vorlage waren es 50.

     Die beiden helleren Varianten unten brauchen trotzdem eine Kante. Die
     bekommen sie als `box-shadow: inset` statt als `border` — ein Rahmen
     wuerde sie wieder hoeher machen als den gefuellten Knopf daneben, und
     dann stehen zwei Knoepfe einer Reihe nicht mehr auf einer Linie. */
  padding: 0.75rem 1.5rem;
  border: 0;
  border-radius: var(--r-knopf);
  background: var(--akzent);
  color: var(--akzent-tinte);
  font: inherit;
  font-family: var(--schrift-display);
  /* **Nach `font: inherit`, nicht davor.** Die Kurzschreibweise setzt
     `line-height` mit zurueck — davor notiert, erbte der Knopf wieder die
     1,625 des Fliesstexts und war 47 statt 44 Pixel hoch. */
  line-height: 20px;
  font-weight: 800;
  font-size: var(--t-klein);
  text-transform: uppercase;
  /* Weniger Sperrung als vorher: in der Pille wirkt enge Laufweite ruhiger. */
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: transform 0.25s var(--kurve), box-shadow 0.25s var(--kurve),
              background 0.2s ease, color 0.2s ease;
}
/* **Beim Ueberfahren nur abdunkeln, nicht entleeren.**

   Die Vorlage nimmt dem Knopf die Fuellung und laesst einen Umriss
   stehen. Auf dieser durchgehend dunklen Seite heisst das: Aus einem
   roten Knopf wird fast-schwarz mit duennem Rand — der Betreiber hat es
   als „grau auf grau" beschrieben, und das trifft es.

   Die bestehende Seite setzt `hover:bg-accent/90`, dunkelt also
   dieselbe Farbe leicht ab. `filter: brightness(0.9)` macht genau das
   und gilt zugleich fuer alle Spielarten — rot, gruen, weiss —, ohne
   dass jede ihren eigenen Hoverwert braucht.

   Die beiden helleren Varianten bringen ihre eigenen Regeln mit: Auf
   einer fast durchsichtigen Flaeche richtet Abdunkeln nichts aus. */
.knopf:hover {
  filter: brightness(0.9);
  transform: translateY(-1px);
  box-shadow: var(--schatten);
}
/* Beim Druecken wieder herunter — das macht den Knopf greifbar. */
.knopf:active { transform: translateY(0) scale(0.98); box-shadow: none; }

/* Pfeil am Ende, wie bei allen Knoepfen des Originals. Als ::after und nicht
   im Markup: eine Zierde gehoert nicht in den Quelltext, und Lesegeraete
   sollen „Alle Events ansehen" vorlesen, nicht „Alle Events ansehen Pfeil".

   **Gezeichnet, nicht gesetzt.** Inter fuehrt U+2192 nicht; als Textzeichen
   fiele der Pfeil auf die Systemschrift zurueck und passte in Strichstaerke
   und Groesse nicht zur Beschriftung daneben. Als Maske uebernimmt er
   `currentColor` und skaliert mit der Schriftgroesse. */
.knopf::after {
  content: '';
  width: 1em;
  height: 1em;
  flex: none;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 11h12.17l-5.58-5.59L12 4l8 8-8 8-1.41-1.41L16.17 13H4v-2Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4 11h12.17l-5.58-5.59L12 4l8 8-8 8-1.41-1.41L16.17 13H4v-2Z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.knopf-ohne-pfeil::after { content: none; }

/* **Zwei Stufen unter dem Hauptknopf, nicht eine.**

   Vorher trugen beide Zweitknoepfe dieselbe getoente Akzentflaeche. Auf
   der hellen Eventseite standen „Lounge reservieren" und „U18-Formular"
   damit nebeneinander in demselben blassen Ton — als Flaeche zu schwach,
   als Umriss zu unruhig, und ununterscheidbar.

   Jetzt: grau gefuellt fuer die zweite Handlung, reiner Umriss fuer die
   dritte. Beide aus `--tinte-rgb`, also tonabhaengig — auf hellem Grund
   ein helles Grau, auf dunklem ein aufgehelltes. */
/* **Deckend, nicht durchscheinend.** Gemessen am Lounge-Knopf der
   bestehenden Eventseite: `#1e1e1e` als volle Flaeche, Rahmen in
   derselben Farbe. Eine Flaeche aus 10 % Weiss nimmt die Farbe dessen
   an, was dahinter liegt — auf einem Flyerbild sah derselbe Knopf anders
   aus als auf dem Seitengrund.

   Die Kante kommt als `box-shadow: inset`, nicht als `border` — sonst
   waeren diese Knoepfe 3px hoeher als der gefuellte daneben. Siehe
   `.knopf`. */
.knopf-leer {
  background: #1e1e1e;
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px rgb(var(--tinte-rgb) / 12%);
}
.knopf-leer:hover {
  filter: none;
  background: #2a2a2a;
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px rgb(var(--tinte-rgb) / 24%);
}

/* Dritte Stufe: nur Umriss. Fuer Wege, die daneben stehen duerfen, ohne
   um Aufmerksamkeit zu werben — das U18-Formular etwa, das nur eine
   Minderheit der Gaeste braucht. */
.knopf-umriss {
  background: transparent;
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px rgb(var(--tinte-rgb) / 28%);
}
.knopf-umriss:hover {
  filter: none;
  background: rgb(var(--tinte-rgb) / 7%);
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px rgb(var(--tinte-rgb) / 45%);
}

/* Knopf mit eigenem Symbol davor — dann entfaellt der Pfeil dahinter.
   Beides zusammen waere ein Knopf mit zwei Zeichen fuer eine Handlung. */
.knopf-ohne-pfeil::after { content: none; }
.knopf-symbol { display: inline-flex; margin-right: 0.125rem; }

/* **Der Ticketknopf ist der einzige mit Rundung.**

   Gemessen auf der Eventseite der bestehenden Seite: volle Spaltenbreite,
   16px Polster oben und unten (52px hoch), `rounded-lg` = 8px, Sperrung
   0,1em. Die Klasse stand bisher im Markup, ohne dass irgendeine Regel
   daran hing — `tools/build.py` setzt sie seit jeher, das Stylesheet
   kannte sie nicht. */
.knopf-ticket {
  width: 100%;
  padding-block: 1rem;
  border-radius: 8px;
  letter-spacing: 0.1em;
}

.knopf[disabled] { opacity: 0.5; cursor: not-allowed; }
.knopf[disabled]:hover { filter: none; background: var(--akzent); color: var(--akzent-tinte); }

.knopf-reihe {
  display: flex;
  flex-wrap: wrap;
  gap: 0.875rem;
}

/* Die Absendeknoepfe laufen im Original ueber die volle Formularbreite. */
.form .knopf-reihe { display: block; }
.form .knopf-reihe .knopf { width: 100%; }

.icon { flex: none; }

/* ---------------------------------------------------------------- Kopf --- */

/* **Die Kopfzeile steht fest und ist immer deckend.**

   Die Geschwisterprojekte lassen sie ueber dem Hero frei im Bild stehen
   und erst beim Scrollen einen Grund bekommen. Die Vorlage baggi-hp
   macht das nicht: Dort ist die Leiste von der ersten Bildschirmzeile an
   schwarz, 80px hoch und bleibt beim Scrollen stehen (gemessen: `fixed`,
   `rgb(0,0,0)`, `blur(8px)`).

   `fixed` statt `sticky` bedeutet, dass sie keinen Platz im Fluss belegt —
   deshalb das `padding-top` auf `body` weiter unten. Beides gehoert
   zusammen; wer eines aendert, muss das andere mitziehen. */
.kopf {
  position: fixed;
  top: 0;
  inset-inline: 0;
  z-index: 50;
  background: #000;
  /* Der Weichzeichner traegt bei deckendem Schwarz nichts bei, steht aber
     im Original und kostet nichts. Er bleibt, damit eine spaetere
     Durchsichtigkeit nur eine Zeile braucht. */
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  isolation: isolate;
}

/* **Kein `[data-fest]`-Umschalter.** `page-common.js` setzt das Attribut
   beim Scrollen weiterhin, aber hier haengt nichts mehr daran: Die Leiste
   ist oben wie unten dieselbe. Das Attribut bleibt im Markup, weil andere
   Projekte dieselbe Datei benutzen — eine tote Regel im Stylesheet waere
   schlechter als ein ungenutztes Attribut im DOM.

   **Der Weichzeichner muss aus, solange das Menue offen ist.** Nicht aus
   Geschmack, sondern weil `backdrop-filter` — wie `transform`, `filter`
   und `perspective` — einen umgebenden Block fuer `position: fixed`
   erzeugt. `.menu` liegt im Markup innerhalb von `.kopf`; mit
   Weichzeichner bezieht sich sein `inset: var(--kopf-hoehe) 0 0` nicht
   mehr auf das Sichtfeld, sondern auf die 80 Pixel hohe Kopfzeile. Das
   Menue waere dann 0 statt 759 Pixel hoch und der Seiteninhalt schiene
   darunter durch. */
.kopf[data-offen='ja'] {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* Die Leiste darunter ist halbdurchsichtig, damit das Bild durchscheint —
   deckend wuerde sie zusammen mit dem Streifen daruber einen dicken Block
   ergeben. */
/* Kein Grund, kein Schatten — die Zeile steht frei im Bild. Stattdessen
   Luft nach oben: Sie rueckt vom Fensterrand weg und bekommt Raum, statt
   sich mit einer Flaeche vom Bild abzusetzen.

   Oben mehr als unten, damit die Zeile optisch nicht klebt und der Blick
   trotzdem zuerst aufs Bild faellt. */
/* Genau `--kopf-hoehe` hoch, Polster symmetrisch. Die Leiste hat oben wie
   unten denselben Grund — die Asymmetrie der Geschwisterprojekte war fuer
   eine frei im Bild stehende Zeile gedacht und wirkt auf einer Flaeche wie
   ein Fehler. */
.kopf-innen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: var(--kopf-hoehe);
}

/* `.huelle` begrenzt die Breite, die Flaeche soll aber ueber die ganze
   Fensterbreite laufen. Statt der Begrenzung uebernimmt das Polster die
   Zentrierung: Es ist so breit wie der Rand neben der Inhaltsspalte, und
   faellt nie unter den Seitenabstand.

   **Mit `+ var(--gutter)`.** Die Vorlage laesst ihn weg, weil ihre
   Kopfzeile eine schmale, schwebende Pille ist, die bewusst weiter aussen
   sitzt als der Inhalt. Hier ist die Leiste eine durchgehende Flaeche, und
   die bestehende Seite setzt Marke und Inhalt auf **dieselbe** Kante
   (beide bei 144px). Ohne den Zuschlag stand unser Logo 32 Pixel weiter
   links als alles darunter. */
.kopf-innen {
  max-width: none;
  padding-inline: max(var(--gutter),
                      calc((100% - var(--breite)) / 2 + var(--gutter)));
}

.logo { display: flex; align-items: center; }
/* Auf dem Telefon deutlich kleiner — bei voller Groesse nimmt die Wortmarke
   dort die halbe Kopfzeile ein. */
/* 40px — gemessen. Die Vorlage fuehrt 46, was die Wortmarke in der 80px
   hohen Leiste zu breit werden liess (192 statt 167 Pixel). */
.logo img { height: 40px; width: auto; }
/* Emsland: Das Festivallogo ist fast quadratisch (813 x 510) und steht
   bei 40px Höhe unleserlich klein. 56px passen noch in --kopf-hoehe. */
.logo img { height: 56px; }
@media (max-width: 899px) {
  .logo img { height: 34px; }
}

.menu-knopf {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 6px;
  /* 44px bleibt die Trefferflaeche — die Balken sind schmaler. Ohne eigene
     Breite zogen sie sich auf die vollen 44px und das Kreuz wirkte wie ein
     Scheibenwischer. */
  width: 44px; height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.menu-knopf span {
  display: block;
  width: 26px;
  height: 2px;
  border-radius: 2px;
  background: var(--tinte);
  transition: transform 0.28s var(--kurve), opacity 0.2s ease;
}
/* 8px = halbe Balkenhoehe plus Abstand — so treffen sich beide in der Mitte. */
.kopf[data-offen='ja'] .menu-knopf span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.kopf[data-offen='ja'] .menu-knopf span:nth-child(2) { opacity: 0; transform: scaleX(0.4); }
.kopf[data-offen='ja'] .menu-knopf span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* **Der Abstand steckt im Punkt, nicht zwischen den Punkten.**

   Gemessen am Original: „Home" ist 88px breit bei 55,7px reiner Schrift —
   also **16px** Polster je Seite — und zwischen zwei Punkten bleiben nur
   5px, in denen der Trennstrich sitzt. (Die Schriftbreite ist auf beiden
   Seiten dieselbe 55,7px; nachgemessen mit einem Range um den Textknoten,
   nicht aus der Kastenbreite geschaetzt.)

   Das ist nicht dasselbe wie eine grosse `gap`: Die Flaeche zum Anklicken
   reicht bis dicht an den Nachbarn, statt dass zwischen zwei Punkten ein
   toter Streifen liegt. Mit der `gap` der Vorlage (28px, plus 28px vor dem
   Strich) war unser Menue 43 Pixel breiter als das Original. */
.menu ul {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0; padding: 0;
  list-style: none;
}

/* **Trennstriche zwischen den Punkten.**

   Die Geschwisterprojekte haben sie abgeschafft, weil ihre Kopfzeile eine
   schmale Pille ist, in der Striche den knappen Raum zerhacken. Hier ist
   die Leiste wieder ueber die volle Breite schwarz, und die bestehende
   Seite setzt die Striche — in einer langen Zeile geben sie den Punkten
   Halt.

   Als `::after` und nicht als Zeichen im Markup: ein Lesegeraet soll
   „Events" vorlesen und nicht „Events senkrechter Strich". */
@media (min-width: 900px) {
  .menu li:not(:last-child)::after {
    content: '';
    width: 1px;
    /* 24px hoch, mittig in der 5px-Luecke — beides gemessen. */
    height: 24px;
    margin-inline: 2px;
    background: rgb(var(--tinte-rgb) / 22%);
  }

  /* Drei Spalten mit gleich breiten Aussenspalten — nur so stehen die
     Punkte wirklich mittig in der Pille. Mit `space-between` verteilten
     sie sich zwischen schmalem Logo und breitem Knopf und landeten
     rechts; die Marke wirkte dadurch eingequetscht.

     Die dritte Spalte bleibt leer: Sie haelt den Platz, den die Marke
     links einnimmt, und haelt damit die Mitte. */
  /* Punkte rechtsbuendig. Die Grundregel traegt das bereits
     (`justify-content: space-between` mit Marke und Navigation als
     einzigen Kindern) — hier stand vorher eine Rasterueberschreibung fuer
     die mittige Fassung. */
  .menu li { display: flex; align-items: center; }

}

/* **`.menu ul a`, nicht `.menu a`.**

   Der Menuefuss mit Anschrift und Social-Symbolen liegt im Markup
   innerhalb von `.menu`. Mit dem weiteren Selektor bekamen auch seine
   Verweise das Polster der Menuepunkte (8px/16px) — und weil die
   Symbolkreise 40px breit sind, blieben davon 8px Innenbreite uebrig.
   Das 20px-Symbol lief ueber, und Chrome setzte es wie beim Hero auf
   linksbuendig statt mittig: alle drei Zeichen sassen 6 Pixel zu weit
   rechts in ihrem Kreis.

   Derselbe Mechanismus, derselbe Tag — es lohnt, danach zu suchen, wenn
   etwas „verschoben" aussieht statt falsch bemessen. */
.menu ul a {
  font-family: var(--schrift-display);
  font-size: 1rem;
  font-weight: 800;
  text-transform: uppercase;
  /* 0,8px auf 16px — gemessen am Original. */
  letter-spacing: 0.05em;
  /* 16px seitlich — siehe `.menu ul`. */
  padding: 0.5rem 1rem;
  transition: color 0.15s ease;
}
/* Keine Unterstreichung — weder fest noch beim Darueberfahren. Der aktive
   Punkt ist eingefaerbt, das genuegt als Signal. */
.menu ul a:hover { color: var(--akzent-text); }
.menu ul a[aria-current='page'] { color: var(--akzent-text); }

/* Der Menuefuss gehoert nur ins aufgeklappte Menue auf schmalen Geraeten.
   Ohne diese Zeile laeuft er auf dem Schreibtisch ungestaltet im Fluss
   unter den Punkten mit — dort gibt es kein Vollbildmenue, in das er
   gehoerte. Die Mobilabfrage schaltet ihn wieder ein. */
.menu-fuss { display: none; }

/* Schmale Geraete: das Menue fuellt den Bildschirm. */

@media (max-width: 899px) {
  :root { --kopf-hoehe: 80px; }

  /* Solange das Menue offen ist, muss die Kopfzeile decken. Auf der
     Startseite ist sie ueber dem Hero durchsichtig — ohne das hier stand
     ueber dem Menue ein Streifen, durch den das Hero-Video schien. */
  .kopf[data-offen='ja'] { background: var(--kopf); }

  .menu {
    position: fixed;
    inset: var(--kopf-hoehe) 0 0;
    background: var(--kopf);
    padding: 1rem var(--gutter) 3rem;
    /* Statt von rechts einzuschieben: aufblenden und leicht aufziehen. Das
       Einschieben liess den Inhalt dahinter kurz wandern. */
    opacity: 0;
    transform: scale(1.03);
    /* Geschlossen auch fuer Tastatur und Lesegeraet weg — sonst wandert der
       Fokus in Menuepunkte, die niemand sieht. */
    visibility: hidden;
    transition: opacity 0.28s ease, transform 0.35s var(--kurve),
                visibility 0.28s ease;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
  }
  /* Punkte und Fuss bilden einen Block, den die Flaeche mittig setzt.
     Vorher nahm die Liste per `flex: 1` den ganzen Raum und schob den Fuss
     an den unteren Rand — dazwischen klaffte ein Loch. */
  .menu { justify-content: center; }
  .menu ul { flex: none; }
  .kopf[data-offen='ja'] .menu {
    opacity: 1;
    transform: none;
    visibility: visible;
  }

  /* Punkte mittig, gross und untereinander — mit Platz, nicht gedraengt. */
  /* Punkte oben beginnen lassen, nicht im freien Raum zentrieren.
     Mit `flex: 1` nimmt die Liste die ganze Hoehe zwischen Kopfzeile und
     Fuss ein; zentriert darin rutschten die Punkte in die Mitte dieser
     Flaeche und standen dadurch weit unterhalb der Kopfzeile.

     `min-height: 100%` ist raus — zusammen mit `flex: 1` zog es die Liste
     zusaetzlich auf und verstaerkte den Effekt. */
  .menu ul {
    flex-direction: column;
    align-items: center;
    gap: 1.5rem;
  }
  .menu li { justify-content: center; }
  .menu ul a {
    font-size: clamp(1.75rem, 7vw, 2.25rem);
    letter-spacing: 0.05em;
  }
  /* U18 steht auf dem Telefon in der Kopfzeile neben der Marke, nicht im
     aufgeklappten Menue — es braucht dort also keine eigene Regel. */

  /* Fuss im aufgeklappten Menue: Anschrift und Symbole. Vier Punkte
     allein lassen die Vollbildflaeche leer wirken — hier steht, was man
     sonst erst im Seitenfuss findet. */
  .menu-fuss {
    margin-top: 2.5rem;
    display: grid;
    justify-items: center;
    gap: 0.35rem;
    text-align: center;
  }
  .menu-fuss p { color: var(--tinte-still); font-size: var(--t-klein); margin: 0; }
  .menu-fuss a { font-size: var(--t-klein); color: var(--tinte-leise); }
  .menu-fuss .fuss-social { margin-top: 0.75rem; }

  /* Ein sehr leiser Schein in der Markenfarbe nimmt der Flaeche das
     Tafelhafte, ohne sie einzufaerben. */
  .menu {
    background-image: radial-gradient(70% 40% at 50% 0%,
      rgb(var(--akzent-rgb) / 7%), transparent 70%);
  }

  /* Die Punkte laufen nacheinander ein, statt alle gleichzeitig
     aufzutauchen. Die Verzoegerung steht je Position im CSS, weil ein
     Inline-Style unter `style-src 'self'` nicht erlaubt ist. */
  .menu li {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.3s ease, transform 0.4s var(--kurve);
  }
  .kopf[data-offen='ja'] .menu li { opacity: 1; transform: none; }
  .kopf[data-offen='ja'] .menu li:nth-child(1) { transition-delay: 0.08s; }
  .kopf[data-offen='ja'] .menu li:nth-child(2) { transition-delay: 0.13s; }
  .kopf[data-offen='ja'] .menu li:nth-child(3) { transition-delay: 0.18s; }
  .kopf[data-offen='ja'] .menu li:nth-child(4) { transition-delay: 0.23s; }
  .kopf[data-offen='ja'] .menu li:nth-child(5) { transition-delay: 0.28s; }

  /* Wer Bewegung abbestellt hat, bekommt sie auch hier nicht. */
  @media (prefers-reduced-motion: reduce) {
    .menu li { opacity: 1; transform: none; transition: none; }
    .menu { transition: visibility 0.01s; transform: none; }
  }
}
@media (min-width: 900px) {
  .menu-knopf { display: none; }
}

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

.hero {
  position: relative;
  /* Feste Hoehe als `height`, nicht als `aspect-ratio` mit `max-height`:
     bei dieser Kombination zieht Chrome die Breite mit und laesst auf einem
     breiten, flachen Fenster rechts eine dunkle Flaeche stehen.
     Auch keine `vh`-Einheiten — sonst springt die Hoehe auf dem Telefon,
     wenn die Adressleiste ein- und ausfaehrt. */
  height: clamp(500px, 71svh, 790px);
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--nacht);
  text-align: center;
}

.hero-medium {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.hero-medium img, .hero-medium video {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Schleier, damit die Schrift auf dem Video traegt. Dunkel, nicht hell —
   die bestehende Seite setzt weisse Schrift auf das Clubvideo. */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgb(0 0 0 / 55%) 0%, rgb(0 0 0 / 35%) 45%, rgb(0 0 0 / 75%) 100%);
}

/* **Variante: wechselnder Hintergrund** — aus excalibur-hp zurueck in die
   Vorlage (Auftrag R9). Hier ungenutzt. Elementors Hintergrund-Diashow
   als reines CSS: Bilder als <img> uebereinander in `.hero-medium`, jedes
   mit derselben Animation, um ein Viertel versetzt (5 s Standzeit, 0,5 s
   Blende). Ohne Bewegungswunsch steht das erste Bild allein. */
.hero--diashow .hero-medium img {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: hero-diashow 20s linear infinite;
}
.hero--diashow .hero-medium img:first-child { opacity: 1; }
.hero--diashow .hero-medium img:nth-child(2) { animation-delay: 5s; }
.hero--diashow .hero-medium img:nth-child(3) { animation-delay: 10s; }
.hero--diashow .hero-medium img:nth-child(4) { animation-delay: 15s; }
@keyframes hero-diashow {
  0%     { opacity: 0; }
  2.5%   { opacity: 1; }
  25%    { opacity: 1; }
  27.5%  { opacity: 0; }
  100%   { opacity: 0; }
}
/* `animation: none`, nicht nur kurz: Die allgemeine Regel kuerzt jede
   Animation auf 0,01 ms — sie liefe sofort bis 100 % durch und liesse auch
   das erste Bild auf Deckung 0 stehen. */
@media (prefers-reduced-motion: reduce) {
  .hero--diashow .hero-medium img { animation: none; }
}

/* **Variante: Vollbild-Pause** — aus emslandbeach-hp (01.11.2026), Auftrag
   R9. Für eine Seite, die nur aus dem Hero besteht: zwischen zwei
   Festivals, vor dem ersten Termin. Füllt den Bildschirm, steht auf der
   Markenfarbe statt auf `--nacht`, und der Knopf dreht sich um — ein
   Akzentknopf auf Akzentgrund wäre unsichtbar.

   Der Schleier ist dunkel und gleichmäßig, nicht der Verlauf von `.hero`:
   Das Foto ist schon in die Markenfarbe eingefärbt. Er hebt weiße Schrift
   auf dem Pink von 3,93:1 über 4,5:1. Die Startseite hat keine
   Kopfzeile — siehe `body:not(:has(.kopf))` in der Grundlage. */
.hero--vollbild {
  height: auto;
  min-height: 100svh;
  padding-block: clamp(3rem, 8vw, 5rem);
  background: var(--akzent);
}
.hero--vollbild .hero-medium img { object-position: left top; }
.hero--vollbild::after { background: rgb(0 0 0 / 24%); }
.hero--vollbild .hero-logo {
  width: min(420px, 78%);
  min-width: 0;
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}
.hero--vollbild .hero-satz {
  max-width: 34rem;
  margin: 0 auto 2rem;
  font-size: 1.0625rem;
  line-height: 1.6;
  /* Volle Tinte statt `--tinte-leise`: Das Grau verschwimmt auf dem
     Foto. Der Schatten trägt die Zeilen dort, wo sie auf dem Telefon über
     der hellen Bühne liegen — der Schleier allein reicht da nicht. */
  color: var(--tinte);
  text-shadow: 0 1px 12px rgb(0 0 0 / 55%);
}
.hero--vollbild .hero-titel { text-shadow: 0 2px 24px rgb(0 0 0 / 35%); }
.hero--vollbild .knopf {
  background: var(--tinte);
  color: var(--nacht);
}
.hero--vollbild .knopf:hover { background: var(--tinte); color: var(--akzent); }

.hero-text {
  position: relative;
  z-index: 2;
}

/* Logo ueber der Ueberschrift. Die Breiten sind die des Originals: 10 % der
   Spalte auf dem Schreibtisch, 28 % ab Tablet abwaerts. */
.hero-logo {
  width: 8%;
  min-width: 78px;
  margin: 0 auto 1rem;
}
@media (max-width: 1024px) {
  .hero-logo { width: 28%; }
}
/* Der Hero-Titel ist ein <p>, kein <h1> — die H1 der Seite steht statisch
   und fuer Lesegeraete unsichtbar im Markup. Sonst waeren es zwei. */
.hero-titel {
  margin: 0 0 1.25rem;
  font-family: var(--schrift-display);
  font-size: var(--t-hero);
  font-weight: 800;
  line-height: 1;
  text-transform: uppercase;
  /* 3,6px auf 72px — gemessen. Dieselbe Sperrung wie bei h1–h4. */
  letter-spacing: 0.05em;
}
.hero-titel span { display: block; }

/* **Groesser als die uebrigen Knoepfe, nicht kleiner.**

   Die Vorlage macht Heroknoepfe knapper, weil dort eine sehr grosse
   Ueberschrift darueber steht. Die Vorlage baggi-hp macht das
   Gegenteil: 16px/32px statt 12px/24px, also 54 statt 44 Pixel hoch.
   Im Hero ist der Knopf die eigentliche Handlung der Seite. */
.hero-text .knopf {
  padding: 1rem 2rem;
  font-size: var(--t-klein);
}

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

/* Die bestehende Seite teilt den Einstieg in zwei gleich grosse Haelften:
   links der Clubbetrieb, rechts die Vermietung. Gemessen 716 x 900 px bei
   1432 px Fensterbreite — also je halbe Fensterbreite, Hoehe fest.

   **Beide Haelften sind gleichrangig.** Deshalb traegt keine von beiden die
   H1; die steht unsichtbar im Markup darueber. Eine der beiden zur
   Hauptueberschrift zu machen hiesse, die andere abzuwerten — und
   Vermietung ist fuer diesen Betrieb kein Nebengeschaeft.

   Der Knopf in jeder Haelfte ist ein <span>, kein <a>: die ganze Haelfte
   ist bereits ein Verweis, und ein Verweis im Verweis ist nicht erlaubt. */
.hero-zwei {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--nacht);
}

.hero-haelfte {
  position: relative;
  display: grid;
  place-items: center;
  /* Feste Hoehe als `height`, keine `vh`-Einheit — aus demselben Grund wie
     beim einteiligen Hero der Geschwisterprojekte: auf dem Telefon springt
     `vh`, wenn die Adressleiste ein- und ausfaehrt. */
  /* **Genau bis zur Falte, nicht darueber hinaus.** Das Original setzt
     `100vh` auf einen Hero, der 64px unterhalb einer 80px hohen Leiste
     beginnt — er ragt dadurch 64 Pixel unter den Fensterrand, und beim
     ersten Scrollen rutscht ein Reststreifen Foto vorbei, bevor etwas
     Neues kommt. Hier wird die Leiste abgezogen, damit die Unterkante des
     Heros die Falte trifft.

     `svh` und nicht `vh`: auf dem Telefon springt `vh`, wenn die
     Adressleiste ein- und ausfaehrt. */
  height: calc(100svh - var(--kopf-hoehe));
  min-height: 420px;
  max-height: 900px;
  overflow: hidden;
  /* Hebt den Stapelkontext, damit das `z-index: -1` des Schleiers unter dem
     Text, aber ueber dem Seitengrund bleibt. Ohne das rutscht der Schleier
     hinter die Flaeche von `body` und ist unsichtbar. */
  isolation: isolate;
  color: var(--tinte);
  text-align: center;
  text-decoration: none;
}

/* Das Bild liegt als <img> im Markup und nicht im CSS, weil die linke
   Haelfte das erste sichtbare Element der Seite ist: nur so laesst sich
   `fetchpriority="high"` setzen, und nur so kennt der Browser die Groesse,
   bevor das Stylesheet da ist. */
.hero-haelfte img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform 0.6s var(--kurve);
}

/* **Schleier als Verlauf, nicht als gleichmaessige Flaeche.**

   Die bestehende Seite legt dort flache 50 % Schwarz. Nachgemessen an den
   tatsaechlich gemalten Pixeln erreicht ihre rote Augenbraue damit **3,07:1**
   gegen den Grund, den sie bekommt — WCAG AA verlangt 4,5:1 fuer Schrift
   dieser Groesse. Auf der gruenen Haelfte sind es 4,60:1, also knapp
   darueber; es haengt also am Foto, nicht an der Farbe.

   Statt die Marke umzufaerben oder das ganze Bild abzusenken, sitzt die
   Deckung dort, wo sie gebraucht wird: Der Text steht senkrecht mittig
   (`place-items: center`), und genau dieses Band wird dunkler. Oben und
   unten bleibt das Foto heller als vorher — es wirkt dadurch nicht
   flaechiger, sondern plastischer.

   Der Mittelwert ueber die Hoehe liegt weiter bei rund 50 %. */
.hero-haelfte::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg,
    rgb(0 0 0 / 36%) 0%,
    rgb(0 0 0 / 74%) 50%,
    rgb(0 0 0 / 36%) 100%);
}

@media (hover: hover) {
  .hero-haelfte:hover img { transform: scale(1.04); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-haelfte img { transition: none; }
  .hero-haelfte:hover img { transform: none; }
}

/* **Die Begrenzung sitzt am Fliesstext, nicht am ganzen Block.**

   Vorher stand hier `max-width: 32ch` (322px). „BUSINESS" ist bei 72px
   aber 448 Pixel breit — und ein Grid-Item, das breiter ist als seine
   Spalte, zentriert Chrome nicht, sondern faellt auf linksbuendig
   zurueck, damit nichts links aus dem Bild laeuft. Die Ueberschrift
   begann deshalb an der linken Kante des Blocks und ragte rechts heraus:
   32 Pixel bei „EVENTS", 77 bei „BUSINESS".

   Das sah aus wie ein Zentrierfehler des Blocks — der Block war aber
   exakt mittig. Gemessen am Original: der Satz ist dort 448 Pixel breit
   und laeuft ueber zwei Zeilen, nicht drei. */
.hero-haelfte-text {
  display: grid;
  justify-items: center;
  gap: 0.875rem;
  width: 100%;
  padding-inline: var(--gutter);
}
.hero-haelfte .hero-satz { max-width: 448px; }

.hero-augenbraue {
  margin: 0;
  font-family: var(--schrift-display);
  font-size: 0.875rem;
  font-weight: 700;
  /* 4,2px auf 14px — gemessen am Original. */
  letter-spacing: 0.3em;
  text-transform: uppercase;
  /* Akzent als Schrift, nicht als Flaeche — siehe `--akzent-text`. */
  color: var(--akzent-text);
}

.hero-haelfte .hero-titel { margin: 0; }

.hero-satz {
  margin: 0;
  color: var(--tinte-leise);
}

.hero-haelfte .knopf { margin-top: 0.5rem; }

/* **Die rechte Haelfte traegt Gruen, die linke Rot.**

   Das ist keine Zierde, sondern die Zweiteilung des Hauses: Clubbetrieb
   und Vermietung sind verschiedene Angebote an verschiedene Leute. Die
   bestehende Seite faerbt deshalb Augenbraue und Knopf je Haelfte
   verschieden.

   Umgesetzt durch Umbelegen der Akzent-Token statt durch eigene Regeln
   fuer Knopf und Augenbraue: So gilt es auch fuer den Fokusring, den
   Umriss beim Ueberfahren und alles, was spaeter dazukommt. */
.hero-haelfte-gruen {
  --akzent:       var(--gruen);
  --akzent-rgb:   var(--gruen-rgb);
  --akzent-tinte: var(--gruen-tinte);
  --akzent-text:  var(--gruen);
}

/* **Untereinander ab 900px, und dann jede Haelfte flacher.**

   Zwei gestapelte Haelften von je 68svh ergaeben 136svh — man saehe die
   zweite gar nicht und wuesste nicht, dass sie da ist. Zusammen duerfen
   sie etwa die Hoehe eines einteiligen Heros haben, also jede die Haelfte.

   Der Haltepunkt ist derselbe wie der von `.ueber` weiter unten. Wer einen
   aendert, muss den anderen mitziehen. */
@media (max-width: 899px) {
  .hero-zwei { grid-template-columns: 1fr; }
  .hero-haelfte {
    height: calc((100svh - var(--kopf-hoehe)) / 2);
    min-height: 300px;
    max-height: 460px;
  }
}

/* ------------------------------------------------------------- Ueber uns -- */

.ueber {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (min-width: 900px) {
  .ueber { grid-template-columns: 1fr 1fr; }
}

/* Logo ueber der Ueberschrift, linksbuendig — 20 % im Original. */
.ueber-logo { width: 20%; min-width: 80px; margin-bottom: 1.25rem; }
@media (max-width: 767px) { .ueber-logo { width: 21%; } }

.ueber-text h2 {
  /* Die kleinere Stufe — siehe `--t-h2-text`. */
  font-size: var(--t-h2-text);
  letter-spacing: normal;
  /* 32px — gemessen. Mit den 20px der Vorlage war der ganze Textblock
     12 Pixel kuerzer, und weil das Raster ihn senkrecht mittig setzt,
     sass er dadurch 20 Pixel tiefer als im Original. Ein Abstand, zwei
     sichtbare Folgen. */
  margin-bottom: 2rem;
}
/* Blocksatz wie im Original. */
/* Kein Blocksatz. Auf schmalen Spalten reisst er Loecher zwischen die
   Woerter — auf dem Telefon bis zu 45 Pixel in einer Zeile. */
.ueber-text p { color: var(--tinte-leise); }
.ueber-text .knopf-reihe { margin-top: 2rem; }

/* **Auf dem Telefon richtet sich der Abschnitt nach den anderen.**

   Sobald `.ueber` einspaltig steht, sitzt diese Ueberschrift direkt ueber
   „Next Events" und „Get the Vibe" — und war mit 22px sichtbar kleiner als
   deren 28px. Auf der bestehenden Seite sind alle drei gleich gross
   (gemessen: je 35px bei 390px Breite).

   Der Knopf steht aus demselben Grund mittig: In den anderen Abschnitten
   macht das `[data-mitte]`, hier geht es nicht ueber das Markup, weil der
   Knopf auf dem Schreibtisch in der linken Spalte bleiben soll.

   Der Haltepunkt ist derselbe wie der des Rasters oben — zwei Werte, die
   zusammengehoeren. Wer einen aendert, muss den anderen mitziehen. */
@media (max-width: 899px) {
  .ueber-text .knopf-reihe { justify-content: center; }
}

/* **Bild links, Text rechts — und auf dem Telefon doch Text zuerst.**

   Der Business-Anreisser auf der Startseite dreht die Spalten, damit er
   sich vom Abschnitt „Ueber uns" darueber absetzt und die Seite nicht zwei
   gleich gebaute Bloecke untereinander zeigt.

   Einspaltig kehrt die Reihenfolge zurueck: sonst steht erst ein Foto eines
   bestuhlten Saals da und die Ueberschrift, die erklaert was man sieht,
   kommt danach. Die Rasterreihenfolge regelt das, nicht die Markup-Folge —
   so bleibt die Lesefolge fuer Lesegeraete die der Quelle. */
.ueber-gedreht .ueber-bild { grid-row: 1; }
@media (max-width: 899px) {
  .ueber-gedreht .ueber-bild { grid-row: 2; }
}

/* Aufzaehlung mit gefuelltem Haken. Dasselbe Kaestchen wie bei den
   Formular-Auswahlfeldern — ein Zeichen, zwei Verwendungen. */
.haken-liste {
  display: grid;
  gap: 0.75rem;
  margin: 1.5rem 0 0;
  padding: 0;
  list-style: none;
  color: var(--tinte-leise);
}
.haken-liste li {
  position: relative;
  padding-left: 2rem;
}
.haken-liste li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.15em;
  width: 1.125rem;
  height: 1.125rem;
  border-radius: var(--r-klein);
  background: var(--haken) var(--akzent) center / 12px 12px no-repeat;
}

/* --------------------------------------------------------------- Karten -- */

/* Drei Spalten, Abstand 20px — und ab Tablet abwaerts eine Spalte. Das
   Original schaltet bei 1024 px direkt auf einspaltig, nicht stufenweise. */
.karten {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 1024px) {
  .karten { grid-template-columns: 1fr; }
}

/* **Keine Perforation.** Die Geschwisterprojekte stanzen in ihre
   Eventkarten zwei Kerben und eine Reisslinie, damit sie wie eine
   Eintrittskarte aussehen. Die Vorlage baggi-hp tut das nicht: Dort
   ist die Karte eine schlichte dunkle Flaeche — Flyer oben, Text darunter,
   scharfe Ecken, kein Schatten. Gemessen: `border-radius: 0`,
   `box-shadow: none`, kein Rahmen.

   Damit faellt auch das Token `--abriss` weg, an dem Kerbenhoehe und
   Trennlinie hingen — es hatte keine Leserin mehr. */
.karte {
  display: flex;
  flex-direction: column;
  background: var(--karte);
  border-radius: var(--r-karte);
  /* Damit der Flyer nicht ueber die Kante haengt, wenn `--r-karte` einmal
     nicht null ist, und fuer das Heranfahren des Bildes beim Ueberfahren. */
  overflow: hidden;
  transition: transform 0.3s var(--kurve), background 0.3s var(--kurve);
}
.karte:hover {
  transform: translateY(-6px);
  background: var(--box-hell);
}
.karte:active { transform: translateY(-2px); }

.karte-bild { background: var(--box-hell); }
/* Flyer sind 16:9 — ein quadratischer Beschnitt schneidet den Titel weg. */
.karte-bild img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.karte-text {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.25rem 1.25rem 1.375rem;
  flex: 1;
}

/* Datum ueber dem Titel. Gemessen am Original: 14px, **weiss**, Stärke
   500, keine Versalien, Sperrung 0,35px — also deutlich zurueckhaltender
   gesetzt als die Versalzeile, die hier vorher stand. */
.karte-datum {
  margin: 0;
  color: var(--tinte);
  font-size: var(--t-klein);
  font-weight: 500;
  letter-spacing: 0.025em;
}

.karte-titel {
  font-size: var(--t-h3);
  line-height: 1.25;
  letter-spacing: 0.02em;
}

/* Die mitveranstaltenden Haeuser, in der Akzentfarbe — die einzige Angabe
   auf der Karte, die man sonst nirgends sieht. */
.karte-ort {
  margin: 0;
  color: var(--akzent-text);
  font-size: var(--t-klein);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Aufforderung mit Pfeil, unten an der Karte. `margin-top: auto` schiebt
   sie an die Unterkante, damit sie in allen Karten einer Reihe auf
   derselben Linie steht — auch wenn die Titel verschieden lang sind.

   **Keine Trennlinie.** Die hatte ich ergaenzt; das Original hat dort
   keine (nachgemessen: `border-top: 0`). Auf einer Karte mit vier kurzen
   Zeilen zerteilt sie mehr, als sie ordnet. */
.karte-mehr {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin: 1.25rem 0 0;
  font-size: 0.75rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--tinte);
  transition: gap 0.22s var(--kurve), color 0.2s ease;
}
.karte-mehr { margin-top: auto; }
.karte:hover .karte-mehr { gap: 0.7rem; color: var(--akzent-text); }

/* Monatsueberschrift der Eventliste. */
/* Zentriert und weiss, ohne Trennlinie — wie im Original. */
.monat {
  /* Bis 32px. `--t-h3` (bis 24px) war zu leise fuer eine Zeile, die eine
     ganze Kartengruppe eroeffnet. */
  font-size: clamp(1.5rem, 3.5vw, 2rem);
  color: var(--tinte);
  text-align: center;
  margin: clamp(2.5rem, 5vw, 3.5rem) 0 1.5rem;
}
.monat:first-child { margin-top: 0; }

.leer {
  color: var(--tinte-leise);
  text-align: center;
  padding-block: 3rem;
}

/* ------------------------------------------------------- Schieberegler -- */

/* Ersetzt Swiper. Das Band wird verschoben, die Folien teilen sich die
   Breite — wie viele gleichzeitig zu sehen sind, sagt `data-zeigen`. */
.slider { position: relative; }

/* Die Spur umfasst **nur das Band**, nicht die Punktreihe. Daran haengen
   zwei Dinge: Das Beschneiden (frueher am Regler) und die senkrechte Mitte
   fuer die Pfeile — die sassen vorher auf der Mitte von Bild plus Punkten
   und damit zu tief.

   `touch-action: pan-y` gibt das senkrechte Scrollen an die Seite weiter
   und behaelt die waagerechte Geste fuer das Blaettern. Ohne das verschluckt
   der Browser entweder das Wischen oder das Scrollen. */
.slider-spur {
  position: relative;
  overflow: hidden;
  touch-action: pan-y;
}
.slider-band {
  display: flex;
  /* `transition` setzt slider.js, damit eine Strecke ohne JavaScript nicht
     erst leer dasteht und dann springt. */
}
.slider-band > figure {
  margin: 0;
  flex: 0 0 100%;
  padding-inline: 0.3125rem;
  box-sizing: border-box;
}
.slider-band img {
  width: 100%;
  object-fit: cover;
  background: var(--box);
  border-radius: var(--r-karte);
}
/* Die Einblick-Strecke zeigt Querformate und laesst sich vergroessern. */
/* An der Klasse, nicht an der Abschnitts-ID. Die ID heisst je Projekt
   anders (`einblick`, `fotos`); haengt die Regel daran, faellt sie beim
   Umbenennen lautlos aus — dann folgt die Folienbreite dem Bild statt der
   Spur und vom Nachbarbild schaut ein Streifen hervor. */
.slider-randlos .slider-band > figure { cursor: zoom-in; }
/* 16:9 — das Format der Dateien im Streifen (1400x788). Die Deckblaetter
   auf /fotos/ tragen 2:3, weil ihre Quellen Hochformate sind: Jede Flaeche
   folgt ihrer eigenen Quelle, statt beide auf ein gemeinsames Mass zu
   zwingen und eine davon zu beschneiden. */
.slider-randlos .slider-band img { aspect-ratio: 16 / 9; }
/* Die Ueber-uns-Strecke zeigt Hochformate. */
#ueber .slider-band img { aspect-ratio: 2 / 3; }

.slider-pfeil {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  display: grid;
  place-items: center;
  width: 42px; height: 42px;
  border: 0;
  border-radius: 50%;
  background: rgb(0 0 0 / 45%);
  backdrop-filter: blur(8px);
  color: var(--akzent-text);
  cursor: pointer;
  transition: background 0.15s ease;
}
.slider-pfeil:hover { background: rgb(0 0 0 / 75%); }
.slider-rueck { left: 0.3125rem; }
.slider-vor { right: 0.3125rem; }

.slider-punkte {
  display: flex;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 1rem;
}
.slider-punkt {
  width: 8px; height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  /* Im Original: aktiver Punkt in der Akzentfarbe, die uebrigen weiss. */
  background: var(--tinte);
  opacity: 0.45;
  cursor: pointer;
  transition: background 0.15s ease, opacity 0.15s ease;
}
.slider-punkt[aria-current='true'] { background: var(--akzent); opacity: 1; }

/* Die Einblick-Strecke laeuft im Original randlos ueber die volle
   Fensterbreite. Sie steht im Markup trotzdem in der Huelle, damit die
   Ueberschrift darueber ausgerichtet bleibt — der negative Rand holt sie
   wieder heraus. `100vw` statt `100%`, weil die Huelle schmaler ist; der
   Ausgleich nach links ist die halbe Differenz. */
.slider-randlos {
  /* `--sb` ist die Breite der Scrollleiste, gesetzt von page-common.js.
     Ohne den Abzug ist die Flaeche auf dem Schreibtisch genau um diese
     Breite zu breit und die ganze Seite laesst sich quer schieben. */
  width: calc(100vw - var(--sb, 0px));
  margin-left: calc(50% - (100vw - var(--sb, 0px)) / 2);
}
.slider-randlos .slider-rueck { left: 0; }
.slider-randlos .slider-vor { right: 0; }

/* ------------------------------------------------------------ Lightbox -- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  place-items: center;
  background: rgb(0 0 0 / 92%);
  padding: clamp(1rem, 5vw, 3rem);
}
.lightbox[data-offen='ja'] { display: grid; }

.lb-bild {
  max-width: 100%;
  max-height: 82vh;
  object-fit: contain;
  border-radius: var(--r-karte);
}
.lb-zaehler {
  position: absolute;
  bottom: 1.25rem;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  color: var(--tinte-still);
  font-size: var(--t-klein);
}

.lb-knopf {
  position: absolute;
  display: grid;
  place-items: center;
  width: 48px; height: 48px;
  border: 0;
  border-radius: 50%;
  background: rgb(255 255 255 / 10%);
  backdrop-filter: blur(8px);
  color: var(--tinte);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.lb-knopf:hover { background: var(--akzent); color: var(--akzent-tinte); }
.lb-zu    { top: 1rem; right: 1rem; }
.lb-rueck { left: 1rem;  top: 50%; transform: translateY(-50%); }
.lb-vor   { right: 1rem; top: 50%; transform: translateY(-50%); }

/* --------------------------------------------------------------- Anfahrt -- */

.anfahrt {
  display: grid;
  gap: clamp(1.5rem, 4vw, 3rem);
}
@media (min-width: 760px) {
  .anfahrt { grid-template-columns: 1fr 1fr; }
}
.anfahrt h2 { font-size: var(--t-h3); margin-bottom: 1rem; }

.zeile {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin-bottom: 0.75rem;
  color: var(--tinte-leise);
}
.zeile .icon { color: var(--akzent-text); margin-top: 0.2rem; }
.zeile a:hover { color: var(--akzent-text); }

/* ------------------------------------------------------- Seitenkopf (Unter) -- */

/* Feste Hoehe. Ohne sie richtet sich jeder Kopf nach der Laenge seines
   Einleitungssatzes und die Unterseiten stehen unterschiedlich hoch. */
/* Bildbanner der Unterseiten — im Original je Seite ein anderes Clubfoto,
   mit dunklem Schleier darueber. */
.seitenkopf-bild {
  position: relative;
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  isolation: isolate;
}
/* **Verlauf statt gleichmaessigem Schleier.**

   Ein flacher Schleier liess das Foto oben noch kraeftig durchschlagen und
   endete unten mit einer sichtbaren Kante zum Abschnitt darunter. Das
   Original legt stattdessen einen Verlauf aus dem Seitengrund darueber, der
   nach unten in volle Deckung laeuft: Der Banner geht in die Seite ueber,
   statt an ihr abzubrechen.

   Gemessen: 60 % oben, 40 % bei 40 % Hoehe, deckend am Fuss. */
.seitenkopf-bild::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg,
    rgb(13 13 13 / 72%) 0%,
    rgb(13 13 13 / 58%) 40%,
    rgb(13 13 13 / 100%) 100%);
}
/* Die Ausschnitte sitzen mittig: Alle vier Motive sind Querformate aus der
   eigenen Fotostrecke und tragen kein Motiv am Rand, das der Beschnitt
   treffen koennte. */
.seitenkopf-bild[data-banner='events']  { background-image: url('../img/banner/events.webp'); }
.seitenkopf-bild[data-banner='jobs']    { background-image: url('../img/banner/jobs.webp'); }
.seitenkopf-bild[data-banner='kontakt'] { background-image: url('../img/banner/kontakt.webp'); }

.seitenkopf {
  /* Hoehe waechst mit der Fensterbreite, statt auf dem Telefon als flacher
     Streifen dazustehen, durch den das Bild stark beschnitten wird. */
  min-height: clamp(320px, 34vw, 460px);
  display: grid;
  align-content: center;
  /* Der Banner laeuft unter die Kopfzeile, damit die schwebende Leiste
     auch hier auf einem Bild sitzt und nicht auf leerer Flaeche.

     Negativer Rand **und** Polster gehoeren zusammen: Der Rand schiebt den
     Banner unter die Leiste, das Polster holt den Inhalt wieder in die
     sichtbare Flaeche. Eines ohne das andere drueckt ihn aus der Mitte —
     genau das war hier frueher der Fall, als das Polster ohne Gegenstueck
     stand. */
  /* **Kein negativer Rand mehr.** Die Leiste ist hier deckend schwarz;
     einen Banner darunter zu schieben hiesse, oben 80 Pixel Foto
     wegzuwerfen. Das Original setzt `padding: 128px 0` und faengt unter
     der Leiste an. */
  padding-block: clamp(3rem, 8vw, 8rem);
  /* `background-color`, nicht die Kurzschreibweise `background`. Das
     Element traegt beide Klassen (`seitenkopf seitenkopf-bild`), und die
     Kurzschreibweise setzt alle uebrigen background-Werte zurueck — damit
     fiel `background-size: cover` aus `.seitenkopf-bild` auf `auto`
     zurueck und das Bannerbild lag in Originalgroesse in der Flaeche,
     also dreifach vergroessert. Das Bild ueberlebte nur, weil die
     Banner-Regeln hoehere Spezifitaet haben. */
  background-color: var(--flaeche);
  border-bottom: 1px solid var(--linie);
  text-align: center;
}
/* Eigene Skala, nicht `--t-h1`: Die Bannerueberschrift steht allein auf
   einer grossen Flaeche und darf deutlich groesser anfangen als eine
   Ueberschrift im Fliesstext. */
/* Auf dem Telefon traegt die Ueberschrift den ganzen Banner — sie darf
   dort deutlich groesser anfangen. 13vw heisst rund 51px auf einem
   390px-Geraet statt der vorherigen 40px. */
/* **Drei Dinge zusammen, sonst wird der Titel abgeschnitten.**

   Ein langes Wort wie „DATENSCHUTZ" hat bei 13vw auf einem 390er Telefon
   eine Mindestbreite von 396 Pixeln. Die `.huelle` ist ein Rasterelement
   mit `min-width: auto` und kann deshalb nicht unter diese Mindestbreite
   schrumpfen — sie wurde 428 Pixel breit, und `overflow-x: clip` am
   Dokument schnitt den Ueberhang einfach ab. Sichtbar war das nur als
   fehlendes „Z".

   `min-width: 0` erlaubt dem Rasterelement zu schrumpfen, der kleinere
   Faktor laesst die vorkommenden Titel passen, und `overflow-wrap` faengt
   den Fall ab, dass spaeter ein noch laengeres Wort dazukommt: Dann bricht
   es um, statt zu verschwinden. */
.seitenkopf > .huelle { min-width: 0; }

/* Die Marke ueber der Seitenueberschrift — Clubname in Versalien, gesperrt (baggi-hp).
   Im Original `#cc2026` bei 14px; hier `--akzent-text`, weil der gemessene
   Wert auf dem dunklen Foto nur 3,5:1 erreicht. */
.seitenkopf-marke {
  margin: 0 0 0.75rem;
  font-family: var(--schrift-display);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--akzent-text);
}
.seitenkopf h1 {
  line-height: 1;
  font-size: clamp(2.25rem, 11vw, 4.5rem);
  overflow-wrap: anywhere;
}
.seitenkopf p {
  margin: 1rem auto 0;
  max-width: 54ch;
  color: var(--tinte-leise);
  text-transform: none;
}
/* **Nicht in der Akzentfarbe.** Im Abschnittskopf mitten auf der Seite ist
   die Unterzeile rot — dort ist sie ein Signal. Im Seitenkopf steht direkt
   darueber schon die rote Augenbraue (baggi-hp); eine zweite rote Zeile
   darunter macht aus der Ueberschrift ein Sandwich. Das Original setzt sie
   weiss bei 60 % Deckung. */
.seitenkopf .unterzeile {
  color: rgb(var(--tinte-rgb) / 60%);
  font-weight: 400;
  font-size: clamp(0.9375rem, 2.6vw, 1.125rem);
}

/* Auf dem Telefon traegt der Banner ein festes Seitenverhaeltnis statt einer
   Mindesthoehe. Der Umweg ueber eigene Hochformat-Zuschnitte war falsch: Ein
   schmaler Ausschnitt aus einem Breitbild heisst staerker vergroessern, nicht
   schwaecher. Und eine feste Mindesthoehe bei schmaler Breite erzwingt genau
   diese Vergroesserung, weil `cover` die Hoehe fuellen muss.

   **3:2 statt 16:9 — gemessen, nicht geschaetzt.** Mit dem Verhaeltnis des
   Bildes (16:9, die Datei ist 1536x864) war das Band bei 390 Pixel Breite
   219 Pixel hoch. Davon gehen 80 fuer die schwebende Kopfzeile ab, es
   bleiben 139 fuer 96 Pixel Text: 21 Pixel Luft ueber der Ueberschrift,
   22 darunter. Die Schrift klebte oben an der Leiste und unten an der
   Kante — genau das wirkte gequetscht.

   Das Polster ist hier **nicht** der Hebel: `align-content: center`
   zentriert den Inhalt, sobald er die Inhaltsbox ueberlaeuft, und das tut
   er auf jeder Telefonbreite. Ein kleineres Polster verschiebt deshalb
   nichts. Nur mehr Hoehe hilft.

   3:2 ergibt 260 Pixel, also 180 nutzbare statt 139 — die Luft verdoppelt
   sich auf gut 40 Pixel. Der Preis sind rund 16 Prozent seitlicher
   Beschnitt. Das ist der Tausch: etwas weniger Bild gegen Text, der nicht
   zwischen zwei Kanten klemmt. */
@media (max-width: 759px) {
  .seitenkopf-bild {
    min-height: 0;
    aspect-ratio: 3 / 2;
    background-position: center center;
  }
}

/* ------------------------------------------------------------------ FAQ -- */

.kontakt-raster {
  display: grid;
  gap: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}
@media (min-width: 900px) {
  .kontakt-raster { grid-template-columns: 1fr 1fr; }
  /* Ist die FAQ leer, faellt die linke Spalte weg und das Formular rueckt
     in die Mitte. */
  /* 672px — gemessen; die Vorlage fuehrt 640. */
  .kontakt-raster[data-ohne-faq='ja'] {
    grid-template-columns: minmax(0, 672px);
    justify-content: center;
  }
}

.faq {
  border-bottom: 1px solid var(--linie);
}
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.125rem 0;
  cursor: pointer;
  font-weight: 700;
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
/* Das Pluszeichen dreht sich beim Aufklappen zum Minus. Als ::after und
   nicht als Symbol im Markup: eine Zierde gehoert nicht in den Quelltext. */
.faq summary::after {
  content: '';
  flex: none;
  width: 14px; height: 14px;
  background:
    linear-gradient(var(--akzent), var(--akzent)) center / 100% 2px no-repeat,
    linear-gradient(var(--akzent), var(--akzent)) center / 2px 100% no-repeat;
  transition: transform 0.2s ease;
}
.faq[open] summary::after { transform: rotate(45deg); }
.faq[open] summary { color: var(--akzent-text); }
.faq-text {
  padding-bottom: 1.25rem;
  color: var(--tinte-leise);
}
/* Die Antwort kommt als reiner Text aus Clubinio, mit Zeilenumbruechen —
   `page-kontakt.js` setzt sie als `textContent`. Ohne `pre-wrap` faltet CSS
   die Umbrueche zu Leerzeichen und aus einer gegliederten Antwort wird ein
   Block. Dieselbe Loesung wie bei der Eventbeschreibung weiter unten, aus
   demselben Grund: kein Markup aus einem Shopadmin-Feld interpretieren. */
.faq-text p { white-space: pre-wrap; overflow-wrap: anywhere; }

/* ---------------------------------------------------------------- Fotos -- */

/* Die Albenliste. Karten im Raster, Deckblatt oben, darunter Titel und
   Datum — dieselbe Form wie die Eventkarten, damit die Seite zusammengehoert. */
.alben-raster {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
}
.album-karte {
  display: flex;
  flex-direction: column;
  border-radius: var(--r-karte);
  background: var(--karte);
  overflow: hidden;
  color: inherit;
  text-decoration: none;
  transition: transform 0.3s var(--kurve), box-shadow 0.3s var(--kurve);
}
.album-karte:hover { transform: translateY(-4px); box-shadow: var(--schatten-hoch); }
.album-karte:focus-visible { outline: 2px solid var(--akzent); outline-offset: 3px; }

/* Festes Seitenverhaeltnis: Die Deckblaetter kommen aus der API und haben
   unterschiedliche Formate — ohne das springen die Karten in der Hoehe. */
/* **2:3 hochkant — das Format der Dateien selbst.** Clubinio liefert die
   Deckblaetter als 1333x2000; in einer Querflaeche blieb davon ein Drittel
   uebrig, Koepfe und das Logo am unteren Rand fielen weg. So steht das
   Motiv vollstaendig da, genau wie im Shopadmin.

   Fest und nicht `auto`, damit die Karten im Raster gleich hoch bleiben —
   kaeme spaeter ein Querformat dazu, wuerde es beschnitten statt die Reihe
   zu zerreissen. */
.album-bild {
  aspect-ratio: 2 / 3;
  background: var(--box);
  /* **Positionierungsrahmen, nicht nur Verhaeltnis.** Ein `height: 100%` am
     Bild loest sich zu `auto` auf, solange die Elternhoehe selbst erst aus
     `aspect-ratio` entsteht — das Bild legt sich dann in seinem eigenen
     Format aus und zieht die Box mit. Ein hochformatiges Deckblatt machte
     aus 4:3 so ein 2:3. Absolut gesetzt kann es das nicht mehr. */
  position: relative;
  overflow: hidden;
}
.album-bild img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.55s var(--kurve);
}
.album-karte:hover .album-bild img { transform: scale(1.04); }

.album-text { padding: 1rem 1.125rem 1.25rem; }
.album-titel { font-size: var(--t-h3); margin-bottom: 0.4rem; }
.album-zeile {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  margin: 0;
  font-size: var(--t-klein);
  color: var(--tinte-leise);
}
.album-zahl { color: var(--akzent-text); white-space: nowrap; }

/* Die Bilder einer Strecke als **Mosaik**: Jedes behaelt sein eigenes
   Format, Hoch- und Querformat stehen nebeneinander.

   Spalten statt Raster, weil ein Raster feste Zeilenhoehen braucht und die
   Bilder dafuer beschnitten werden muessten. `break-inside: avoid` haelt
   ein Bild zusammen, sonst zerreisst es die Spaltenkante.

   Der Preis: Spalten laufen senkrecht, die Lesereihenfolge ist also
   spaltenweise statt zeilenweise. Fuer eine Fotowand ist das in Ordnung —
   fuer eine Liste waere es das nicht. */
.fotoraster {
  column-count: 2;
  column-gap: 0.5rem;
  margin-top: 1.5rem;
}
@media (min-width: 600px)  { .fotoraster { column-count: 3; } }
@media (min-width: 900px)  { .fotoraster { column-count: 4; } }
@media (min-width: 1200px) { .fotoraster { column-count: 5; } }

.fotoraster figure {
  margin: 0 0 0.5rem;
  break-inside: avoid;
  border-radius: var(--r-klein);
  overflow: hidden;
  background: var(--box);
  cursor: zoom-in;
}
.fotoraster img {
  width: 100%;
  height: auto;
  display: block;
  transition: transform 0.4s var(--kurve), opacity 0.2s ease;
}
.fotoraster figure:hover img { transform: scale(1.05); }
.fotoraster figure:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }

/* Rueckweg aus einer Strecke. Steht ueber der Ueberschrift, nicht darunter:
   Wer zurueck will, sucht oben. */
.zurueck {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin-bottom: 1rem;
  color: var(--tinte-leise);
  font-size: var(--t-klein);
  text-decoration: none;
}
.zurueck::before { content: '\2039'; font-size: 1.3em; line-height: 1; }
.zurueck:hover { color: var(--akzent-text); }

/* Die Kopfzeile einer Strecke steht links, nicht mittig wie die der
   Abschnitte auf der Startseite. */
.kopfzeile-links { text-align: left; }

/* ---------------------------------------------------------------- Jobs -- */

/* Im Original steht die Ansprache linksbuendig und in normaler Schriftlage,
   nicht als zentrierte Versalueberschrift. */
.abschnitt-oben { padding-block: clamp(2.5rem, 6vw, 4rem) 0; }

/* **Als letzter Abschnitt braucht er sein Polster zurueck.**

   Die Zeile darueber setzt es auf 0 — richtig fuer einen Abschnitt, der
   an den naechsten anschliesst, falsch fuer den letzten vor dem Fuss.
   Auf /kontakt/ stiessen die Social-Symbole direkt an die Fusskante, auf
   /events/ die letzte Kartenreihe.

   **Zielgenau auf diese Klasse, nicht auf `section:last-of-type`.** Mein
   erster Versuch war die allgemeine Regel — sie ist aber spezifischer
   als `.abschnitt` und haette auf /business/, /jobs/, /impressum/ und
   /datenschutz/ das Polster von 112 auf 80 gesenkt. Vier Seiten
   veraendert, um zwei zu reparieren. `.abschnitt-oben` ist die einzige
   Klasse im Stylesheet, die unten auf 0 geht; damit ist der Fall
   vollstaendig abgedeckt.

   80px — gemessen am Original. */
.abschnitt-oben:last-of-type {
  padding-bottom: clamp(3.5rem, 9vw, 5rem);
}
/* Ansprache und Formular gehoeren zusammen. Ohne das hier stossen zwei
   volle Abschnittspolster aneinander und reissen eine Luecke zwischen
   Einleitung und erstem Feld. Die zweite Zeile ueberspringt die
   ausgeblendeten Stellen. */
.abschnitt-oben + .abschnitt,
.abschnitt-oben + [hidden] + .abschnitt { padding-top: clamp(1.75rem, 4vw, 2.75rem); }
/* `.jobs-ansprache` und `.jobs-intro` sind weg: Die bestehende Seite hat
   ueber dem Bewerbungsformular keinen Einleitungsabsatz, sondern nur die
   Ueberschrift „Jetzt bewerben". Das Mindestalter steht jetzt als Hinweis
   direkt am Altersfeld. */
.feld-hinweis {
  font-size: 0.75rem;
  color: var(--tinte-still);
}

/* -------------------------------------------------------------- Stellen -- */

.stelle {
  padding: 1.5rem;
  background: rgb(255 255 255 / 5%);
  border: 1px solid rgb(255 255 255 / 8%);
  border-radius: var(--r-karte);
  margin-bottom: 1rem;
}
.stelle h3 { font-size: var(--t-h3); margin-bottom: 0.5rem; }
/* `white-space` wie bei der FAQ-Antwort: `page-jobs.js` setzt die
   Beschreibung als reinen Text, die Umbrueche darin sollen stehen bleiben. */
.stelle p {
  color: var(--tinte-leise);
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------ Formulare -- */

/* 672px — gemessen, auf beiden Formularseiten gleich. Mittig in der
   Huelle, nicht ueber deren volle Breite. */
.form {
  display: grid;
  gap: 1.125rem;
  max-width: 672px;
  margin-inline: auto;
}

/* h2 traegt global keinen Abstand; ueber einem Formular braucht sie einen,
   sonst sitzt sie auf der ersten Feldbeschriftung. */
#kontaktformular h2 { margin-bottom: 1.5rem; }

/* Im Original stehen kurze Felder nebeneinander, nicht alle untereinander.
   `auto-fit` statt fester Spalten: unter ~420px je Feld bricht die Reihe
   von selbst um, ohne eigene Abfrage. */
.form-reihe {
  display: grid;
  gap: 1.125rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}

/* **`align-content: start` ist nicht kosmetisch.**

   Die Felder einer Reihe sind Rasterzellen und werden auf gleiche Hoehe
   gestreckt. Ohne diese Zeile wachsen die Zeilen darin mit — und weil
   das Altersfeld einen Hinweis darunter traegt (drei Zeilen) und das
   Namensfeld nicht (zwei), verteilte sich der Ueberschuss links auf
   Beschriftung und Eingabefeld: Das linke Feld war **60px hoch statt
   46** und begann 13px tiefer als das rechte.

   Mit `start` behalten die Zeilen ihre Inhaltshoehe, und der Ueberschuss
   bleibt unten stehen, wo er niemanden stoert. */
.feld {
  display: grid;
  gap: 0.5rem;
  align-content: start;
}
/* **Doch Versalien.** Der Kommentar hier behauptete das Gegenteil und
   stammte aus der Vorlage; an der Vorlagenseite baggi-hp nachgemessen
   sind es 12px, Versalien, **weiss** (nicht gedaempft), Sperrung 0,6px. */
.feld > span {
  font-size: 0.75rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--tinte);
}
/* „(optional)" steht im Original hinter dem Namen des Felds, statt dass
   die Pflichtfelder einen Stern tragen. Gedaempft, damit die Zeile nicht
   zweigeteilt wirkt. */
.feld-optional { color: var(--tinte-still); }
.feld-pflicht { color: var(--akzent-text); }

/* **Rahmen, Rundung und eine deckende Flaeche** — alles an der
   bestehenden Seite gemessen: `#212121` mit `1px solid #383838`, Radius
   8px, 12/16 Polster, 46px hoch. Die Vorlage faehrt rahmenlose, fast
   durchsichtige Felder; der Kommentar dazu stand hier noch und ist jetzt
   falsch, deshalb weg.

   Die 8px sind dieselbe Ausnahme wie beim Ticketknopf und den
   Bereichskacheln — `--r-feld` bleibt 0, sonst wandert die Rundung
   durchs ganze Projekt. */
input[type='text'], input[type='email'], input[type='tel'],
input[type='number'], input[type='file'], textarea, select {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid #383838;
  border-radius: 8px;
  background: #212121;
  color: var(--tinte);
  font: inherit;
  /* **Nach `font: inherit`.** Die Kurzschreibweise setzt `line-height`
     zurueck — dieselbe Falle wie beim Knopf. 12+20+12 plus Rahmen ergibt
     die 46px des Originals; mit der geerbten Zeilenhoehe des Fliesstexts
     waren es 66. */
  line-height: 20px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
:is(input[type='text'], input[type='email'], input[type='tel'],
    input[type='number'], textarea, select):hover:not(:focus) {
  border-color: #4a4a4a;
}
textarea {
  min-height: 150px;
  resize: vertical;
  border-radius: 8px;
}
/* Fokus als schmaler Ring aussen. Er liegt ueber dem Rand, nicht darin,
   und verschiebt deshalb nichts. */
input:focus, textarea:focus, select:focus {
  outline: 0;
  border-color: var(--akzent);
  box-shadow: 0 0 0 2px rgb(var(--akzent-rgb) / 45%);
}
/* **Eigener Wert, nicht `--tinte-still`.** Die Eingabefelder haben jetzt
   einen helleren Grund (`#212121` statt fast durchsichtig); darauf
   erreicht das stille Grau nur 3,91:1. `#8a8a8a` traegt mit 4,66:1 und
   bleibt trotzdem erkennbar leiser als der eingegebene Text. */
::placeholder { color: #8a8a8a; opacity: 1; }

/* Das Dateifeld traegt keine eigene Flaeche: sonst steht ein Knopf in
   einem Kasten in einem Formular. Nur der Knopf bleibt sichtbar, der
   Dateiname steht daneben im Text. */
input[type='file'] {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: var(--t-klein);
  color: var(--tinte-leise);
}
input[type='file']:focus {
  background: none;
  box-shadow: none;
}
input[type='file']::file-selector-button {
  margin-right: 0.75rem;
  padding: 0.6rem 1.2rem;
  border: 0;
  border-radius: var(--r-knopf);
  background: rgb(255 255 255 / 10%);
  color: var(--tinte);
  font: inherit;
  font-size: var(--t-klein);
  cursor: pointer;
  transition: background 0.2s ease;
}
input[type='file']::file-selector-button:hover {
  background: rgb(255 255 255 / 16%);
}
input[type='file']:focus-visible::file-selector-button {
  outline: 2px solid var(--akzent);
  outline-offset: 2px;
}

/* Mehrfachauswahl der Bereiche auf der Jobseite. Keine Pillen mehr: sieben
   Umrisse mit je einem Kreis darin ergeben eine Wand aus Rahmen. Hier steht
   nur das Kaestchen und der Text daneben, in Spalten gesetzt, damit die
   unterschiedlich langen Bezeichnungen untereinander ausgerichtet bleiben. */
.auswahl {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
  gap: 0.9rem 1.5rem;
  margin-top: 0.3rem;
}
.auswahl label {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  color: var(--tinte-leise);
  cursor: pointer;
  transition: color 0.2s ease;
}
.auswahl label:hover,
.auswahl label:has(input:checked) { color: var(--tinte); }

/* Das Fieldset traegt im Original keinen Rahmen — nur die Beschriftung
   darueber, wie bei jedem anderen Feld. */
fieldset.feld {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}
fieldset.feld legend { padding: 0; }

.zustimmung {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  font-size: var(--t-klein);
  color: var(--tinte-leise);
}
.zustimmung input { margin-top: 0.1rem; }

/* Ein eigenes Kaestchen fuer beide Stellen. Das Systemkaestchen ist ein
   weisses Quadrat und passt zu nichts hier; gefuellt statt umrandet spricht
   es dieselbe Sprache wie die Eingabefelder. */
.auswahl input, .zustimmung input {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 20px; height: 20px;
  border: 0;
  border-radius: var(--r-klein);
  background: rgb(255 255 255 / 10%);
  cursor: pointer;
  transition: background 0.2s ease;
}
.auswahl label:hover input:not(:checked),
.zustimmung:hover input:not(:checked) { background: rgb(255 255 255 / 16%); }
.auswahl input:checked, .zustimmung input:checked {
  background: var(--haken) var(--akzent) center / 13px 13px no-repeat;
}
.auswahl input:focus-visible, .zustimmung input:focus-visible {
  outline: 2px solid var(--akzent);
  outline-offset: 2px;
}
.zustimmung a { color: var(--akzent-text); text-decoration: underline; }

/* Honigtopf. Fuer Menschen unsichtbar, fuer Skripte verlockend.
   Nicht `display: none` — manche Skripte ueberspringen genau das. */
.honigtopf {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* **Die Erfolgsmeldung war eine rote Textzeile.**

   Rot ist auf dieser Seite die Akzentfarbe — und zugleich die Farbe, in
   der jeder Fehler steht. Wer eine Bewerbung abgeschickt hatte, las
   „Danke! Wir haben deine Bewerbung" in derselben Farbe wie „Bitte
   stimme der Datenschutzerklaerung zu", in derselben Groesse, an
   derselben Stelle. Das ist im besten Fall uebersehbar und im
   schlechteren beunruhigend.

   Jetzt ein eigener Kasten mit Flaeche, Rahmen und Zeichen. Eine
   Einsendung ist der Moment, in dem jemand etwas aus der Hand gibt —
   dort gehoert die deutlichste Rueckmeldung der ganzen Seite hin, nicht
   die leiseste.

   Im Ruhezustand nimmt die Meldung keinen Platz ein: `min-height` auf
   einer leeren Zeile haette sonst dauerhaft eine Luecke ueber dem Knopf
   hinterlassen. */
.rueckmeldung {
  margin: 0;
  font-size: var(--t-klein);
}
.rueckmeldung:empty { display: none; }

.rueckmeldung[data-state='ok'],
.rueckmeldung[data-state='fehler'] {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.875rem;
  align-items: center;
  padding: 1.125rem 1.25rem;
  border-radius: 8px;
  font-size: 1rem;
  line-height: 1.5;
}
/* Das Zeichen als ::before, damit es nicht vorgelesen wird — der Text
   sagt bereits, was los ist. */
.rueckmeldung[data-state='ok']::before,
.rueckmeldung[data-state='fehler']::before {
  content: '';
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-position: center;
  background-repeat: no-repeat;
  background-size: 15px 15px;
}

/* Gruen, nicht in der Akzentfarbe: Der Akzent ist hier rot und waere
   vom Fehlerfall nicht zu unterscheiden. #2e7d32 traegt weisse Schrift
   mit 5,13:1 — derselbe Ton wie der Partnerabschnitt auf /business/. */
.rueckmeldung[data-state='ok'] {
  background: rgb(46 125 50 / 18%);
  box-shadow: inset 0 0 0 1px var(--gruen-partner);
  color: var(--tinte);
  font-weight: 500;
}
.rueckmeldung[data-state='ok']::before {
  background-color: var(--gruen-partner);
  background-image: var(--haken);
}

.rueckmeldung[data-state='fehler'] {
  background: rgb(204 32 38 / 16%);
  box-shadow: inset 0 0 0 1px var(--akzent);
  color: var(--tinte);
}
.rueckmeldung[data-state='fehler']::before {
  background-color: var(--akzent);
  background-image: var(--ausruf);
}

.rueckmeldung[data-state='laeuft'] { color: var(--tinte-still); }

/* ------------------------------------------------------------- Eventseite -- */

/* Inhaltsspalte ~820px und Titel ~40px — Originalwerte. */
.event { max-width: 820px; margin-inline: auto; }
.event h1 { font-size: clamp(1.75rem, 4vw, 2.5rem); }

.event-flyer {
  width: 100%;
  border-radius: var(--r-karte);
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--box);
  margin-bottom: 1.75rem;
}

/* **Untereinander, jeder ueber die volle Breite.**

   Die Vorlage legt Ticket- und Lounge-Knopf nebeneinander (`flex: 1 1
   260px`). Die bestehende Seite stapelt sie: beide 896 Pixel breit, der
   Lounge-Knopf unter dem Ticketknopf. Das ist auch die richtige
   Rangfolge — der zweite Knopf ist kein gleichwertiger Weg, sondern ein
   Zusatz fuer einen Teil der Gaeste, und nebeneinander lesen sie sich
   als Alternative. */
.event .knopf-reihe {
  flex-direction: column;
  margin-bottom: 2rem;
}
.event .knopf-reihe .knopf { width: 100%; }

/* Der U18-Knopf laeuft ueber dieselbe Breite wie der Ticketknopf. Als
   schmaler Knopf unter einem breiten stand er auf dem Schreibtisch
   verloren in der Flaeche. */
.event .knopf-reihe-u18 .knopf { width: 100%; }

/* U18-Formular. Erscheint nur, wenn Minderjaehrige eingelassen werden —
   tools/build.py entscheidet das je Termin aus `ageRestriction`.

   Steht unter den Knoepfen und nicht daneben: Es ist kein gleichrangiger
   Weg zum Ticket, sondern eine Bedingung fuer einen Teil der Gaeste. Der
   Abstand nach oben ist deshalb negativ gegen den Abstand der Knopfreihe —
   Hinweis und Knopf gehoeren optisch zusammen, nicht zum Flyer darueber. */
/* Der Knopf steht direkt unter dem Ticketknopf, der Hinweis darunter: Die
   Handlung zuerst, die Erklaerung als Beschriftung dazu. Der negative
   Abstand nach oben arbeitet gegen den Abstand der Ticketreihe — beide
   Knoepfe gehoeren zusammen. */
.event .knopf-reihe-u18 { margin: -1rem 0 0.6rem; }
.u18-hinweis {
  margin: 0 0 2.5rem;
  color: var(--tinte-still);
  font-size: var(--t-klein);
}

.event-datum {
  color: var(--akzent-text);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.625rem;
}
.event h1 { margin-bottom: 1.5rem; }
/* Die Beschreibung steht auf der Eventseite fast allein auf der Flaeche.
   Eine leichte Absetzung gibt ihr eine Kante, statt sie im Grund
   verschwinden zu lassen — ohne sie als Kasten zu rahmen. */
.event-text a { color: var(--akzent-text); }
.event-text {
  margin-top: 0.5rem;
  padding: 1.25rem 1.375rem;
  background: rgb(255 255 255 / 3.5%);
  border-radius: var(--r-karte);
  color: var(--tinte-leise);
  line-height: 1.55;
  /* Die Beschreibung kommt als reiner Text aus Clubinio, mit Zeilenumbruechen
     und Emoji. `pre-wrap` erhaelt die Umbrueche, ohne dass dafuer Markup
     aus einem Shopadmin-Feld interpretiert werden muss. */
  white-space: pre-wrap;
  /* Lange Adressen haben keine Trennstelle — ohne das hier laufen sie aus
     dem Kasten heraus und werden am Rand abgeschnitten. `anywhere` statt
     `break-word`, weil es auch in die Mindestbreite einfliesst: Sonst zieht
     ein einziger langer Link den Kasten breiter als den Bildschirm. */
  overflow-wrap: anywhere;
}

.infokasten {
  margin-top: 2.5rem;
  padding: 1.75rem;
  background: rgb(255 255 255 / 5%);
  border: 1px solid rgb(255 255 255 / 8%);
  border-radius: var(--r-karte);
}
.infokasten h2 { font-size: var(--t-h3); margin-bottom: 1.25rem; }
/* Zwei Paare nebeneinander, Beschriftung ueber dem Wert — wie im Original.
   `dt`/`dd` stehen im Markup abwechselnd; das Raster setzt sie deshalb in
   eine eigene Zelle je Paar, indem jedes `dt` eine neue Zeile beginnt. */
.infokasten dl {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem 2.5rem;
  margin: 0;
}
@media (min-width: 620px) {
  .infokasten dl { grid-template-columns: 1fr 1fr; }
}
.infopaar dt { margin: 0; }
.infokasten dd {
  text-transform: uppercase;
  font-weight: 700;
  margin-top: 0.25rem;
}
.infokasten dt {
  color: var(--tinte-still);
  font-size: var(--t-klein);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.infokasten dd { margin: 0; }

.lounges {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
}
.lounge {
  background: var(--karte);
  border-radius: var(--r-karte);
  overflow: hidden;
  box-shadow: var(--schatten);
}
.lounge img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.lounge-text { padding: 1rem 1.125rem 1.25rem; }
.lounge-text h3 { font-size: 1.0625rem; margin-bottom: 0.375rem; }
.lounge-wert { margin: 0; color: var(--tinte-leise); font-size: var(--t-klein); }
.lounge-hinweis {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--tinte-still);
  font-size: var(--t-klein);
}

/* Zentriert mit Pfeil davor — wie im Original. Der Pfeil ist wie bei den
   Knoepfen gezeichnet, nicht gesetzt. */
.zurueck::before {
  content: '';
  width: 1em;
  height: 1em;
  flex: none;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2Z'/%3E%3C/svg%3E") center / contain no-repeat;
}
.zurueck {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
  margin-top: 2.5rem;
  color: var(--tinte-leise);
  font-size: var(--t-klein);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.zurueck:hover { color: var(--akzent-text); }

/* ------------------------------------------------------------ Rechtstext -- */

.rechtstext { max-width: 72ch; }
/* Variante `.rechtstext--schlicht` (aus beachhouse-hp): Titel in der
   Textschrift, wie geschrieben statt in Versalien. */
.rechtstext--schlicht h1 { font-family: var(--schrift-text); text-transform: none; }
.rechtstext h2 {
  font-size: var(--t-h3);
  margin: 2.5rem 0 0.875rem;
  text-transform: none;
}
.rechtstext h3 {
  font-size: 1.0625rem;
  margin: 1.75rem 0 0.5rem;
  text-transform: none;
}
.rechtstext p, .rechtstext li { color: var(--tinte-leise); }
.rechtstext a { color: var(--akzent-text); text-decoration: underline; }
.rechtstext ul { padding-left: 1.25rem; }
.rechtstext address { font-style: normal; margin-bottom: 1.5rem; }

/* ------------------------------------------------------------------ Fuss -- */

/* Zwei Spalten wie im Original: links Marke und Rechtslinks, rechts die
   Anfahrt samt Social-Symbolen und dem Clubinio-Zeichen. */
/* Der Fuss ist heller als der Seitengrund — Clubinio-Boxfarbe auf
   Clubinio-Grund. */
.fuss {
  background: var(--box);
  padding-block: clamp(2.5rem, 6vw, 4rem);
}
/* **Drei Spalten, die Marke ueber zwei davon.** Gemessen am Original:
   378px je Spalte, 40px Luecke; der Markenblock spannt ueber die ersten
   beiden, „Quick Links" steht in der dritten. */
.fuss-raster {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: 1fr;
}
@media (min-width: 760px) {
  .fuss-raster { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .fuss-marke { grid-column: span 2; }
}
/* Der Fliesstext laeuft nicht ueber die ganzen zwei Spalten — im Original
   bricht er nach 448 Pixeln um. */
.fuss-marke p { max-width: 448px; }

/* Relativ zur Spalte, nicht als feste Pixelzahl — so macht es das
   Original (`width: 24%`). Feste 150px blieben auf dem Telefon gleich
   gross, waehrend die Spalte auf Fensterbreite schrumpfte, und das Zeichen
   nahm dort fast die ganze Breite ein.

   `clamp` statt reiner Prozente: nach unten gedeckelt, damit es auf sehr
   schmalen Geraeten nicht unleserlich klein wird, nach oben, damit es auf
   grossen Fenstern nicht aufblaeht. */
.fuss-logo {
  width: clamp(84px, 24%, 150px);
  margin-bottom: 1.25rem;
}

.fuss p, .fuss li { color: var(--tinte-leise); font-size: var(--t-klein); }
.fuss a:hover { color: var(--akzent-text); }

/* **Zweite Fussspalte: „Quick Links" als zwei Listen nebeneinander.**

   Das Original setzt die Ueberschrift einmal und laesst darunter zwei
   Spalten laufen — Rechtliches links, Seiten rechts. Deshalb steht die H2
   ausserhalb des Rasters und spannt mit `grid-column: 1 / -1` darueber.

   Auf dem Telefon bleiben es zwei Spalten, nicht eine: vier bzw. drei
   kurze Verweise untereinander ergaeben eine unnoetig lange Leiste, und
   nebeneinander passen sie auch auf 320px. */
.fuss-links h2 {
  font-size: 1rem;
  letter-spacing: 0.08em;
  margin-bottom: 1rem;
  color: var(--akzent-text);
}
.fuss-links ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.75rem;
}
.fuss-links a { color: var(--tinte-leise); }
.fuss-links a:hover { color: var(--akzent-text); }

/* Schlusszeile: Seitenverweise links, Rechtehinweis rechts. Im Original
   eine eigene Zeile unter dem Raster, durch eine feine Linie abgesetzt. */
.fuss-zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid rgb(var(--tinte-rgb) / 10%);
}
.fuss-zeile p { margin: 0; }
.fuss-seiten {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}
.fuss-seiten a { color: var(--tinte-leise); font-size: var(--t-klein); }
.fuss-seiten a:hover { color: var(--akzent-text); }

/* **Runde Flaechen, nicht freie Symbole.**

   Der Kommentar hier behauptete das Gegenteil und stammte aus der
   Vorlage. An der bestehenden Seite gemessen: ein Kreis von 40px (im
   Fuss 36) mit Weiss bei 10 % Deckung, darin das Symbol in 20px (bzw.
   16) **weiss** — nicht in der Akzentfarbe. */
.fuss-social { display: flex; gap: 0.75rem; margin: 1.25rem 0; }
.fuss-social a {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgb(var(--tinte-rgb) / 10%);
  color: var(--tinte);
  transition: background 0.2s ease;
}
.fuss-social a:hover { background: rgb(var(--tinte-rgb) / 20%); color: var(--tinte); }
.fuss-social svg { width: 20px; height: 20px; }

/* Im Fuss eine Spur kleiner — ebenfalls gemessen. */
.fuss .fuss-social a { width: 36px; height: 36px; }
.fuss .fuss-social svg { width: 16px; height: 16px; }

.clubinio { display: inline-block; }
.clubinio img { height: 38px; width: auto; }

/* ------------------------------------------------------------- Business -- */

/* Der Hero der Vermietungsseite ist hoeher als der der Startseite und
   traegt mehr Text — er muss ihn tragen koennen, ohne dass der Knopf unter
   die Falte rutscht. */
.hero-business {
  height: calc(100svh - var(--kopf-hoehe));
  min-height: 560px;
  max-height: 940px;
  text-align: center;
}
/* **Eigene Groesse, nicht die des Seitentitels.** Die Ueberschrift hier ist
   ein Satz aus zwei Zeilen, kein einzelnes Wort wie „EVENTS" — auf 72px
   zerfaellt sie in fuenf Zeilen und drueckt die Knoepfe aus dem Bild.
   Gemessen am Original: 48px, Zeilenhoehe 1,0. */
.hero-business .hero-titel {
  font-size: clamp(2rem, 4.6vw, 3rem);
  line-height: 1;
  margin-bottom: 1.5rem;
}
/* Nur der Fliesstext wird eingeengt. Die Ueberschrift darf die volle
   Spaltenbreite nutzen, sonst bricht sie frueher als noetig.
   768px — gemessen; `62ch` war rund 70 Pixel zu eng und erzeugte einen
   anderen Zeilenumbruch als im Original. */
.hero-business .hero-satz {
  max-width: 768px;
  margin: 0 auto;
}

/* „powered by" plus Partnerzeichen — im Original **unter** der
   Ueberschrift, nicht darueber. Es ist eine Fussnote zur Aussage, kein
   Vorspann. */
.hero-partner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin: 0 0 1.75rem;
  font-size: var(--t-klein);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--tinte-still);
}
/* 20px — gemessen. Mit 34px drängte sich das Partnerzeichen vor die
   Ueberschrift, unter der es stehen soll. */
.hero-partner img { height: 20px; width: auto; }

/* ------------------------------------------------- Business: Merkmale -- */

/* Vier gleichrangige Kacheln. Ab Tablet zwei, auf dem Schreibtisch vier —
   bei drei Spalten bliebe in der zweiten Reihe eine Luecke stehen. */
.merkmale {
  display: grid;
  gap: 20px;
  grid-template-columns: 1fr;
}
@media (min-width: 620px)  { .merkmale { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Vier Spalten, mittig im Abschnitt — zusammen 1216 Pixel wie der uebrige
   Inhalt, aber 280 je Kachel mit 32 Luecke, so wie gemessen. */
@media (min-width: 1024px) {
  .merkmale {
    grid-template-columns: repeat(4, 280px);
    gap: 32px;
    justify-content: center;
  }
}

/* **Kein Kasten.** Ich hatte den Merkmalen Rahmen und Flaeche gegeben;
   im Original stehen sie frei auf dem Abschnittsgrund, mittig gesetzt,
   mit einem gruenen Strichsymbol darueber (gemessen: `background:
   transparent`, `border: 0`, `text-align: center`). */
.merkmal {
  text-align: center;
  padding: 0;
}
.merkmal-symbol {
  display: inline-flex;
  margin-bottom: 1.25rem;
  /* Das helle Gruen als Schrift- und Strichfarbe auf dunklem Grund —
     dort sind es 6,39:1, da ist nichts zu heilen. */
  color: #4caf50;
}
.merkmal h3 {
  /* 18px/28px — gemessen. */
  font-size: 1.125rem;
  line-height: 1.56;
  margin-bottom: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.merkmal p { color: var(--tinte-leise); margin: 0; font-size: var(--t-klein); }

/* Der einzige farbige Abschnitt der Seite: der Partnerblock. Die Token
   werden hier umbelegt, damit auch Schrift, Verweise und der Fokusring
   mitziehen und nicht einzeln nachgefaerbt werden muessen. */
.abschnitt-gruen {
  --tinte: #ffffff;
  --tinte-leise: rgb(255 255 255 / 86%);
  --tinte-still: rgb(255 255 255 / 70%);
  --tinte-rgb: 255 255 255;
  background: var(--gruen-partner);
  color: var(--tinte);
}
.abschnitt-gruen .partner p { color: var(--tinte-leise); }

/* ------------------------------------------------- Business: Laufband -- */

/* Endlose Bildstrecke als Zierde.

   **Die Spur enthaelt jedes Bild zweimal.** Sie laeuft genau um ihre halbe
   Breite nach links und springt dann zurueck — weil an dieser Stelle die
   zweite Haelfte exakt dort steht, wo die erste begann, ist der Sprung
   unsichtbar. Mit nur einer Folge waere an jeder Runde eine Luecke zu
   sehen, waehrend das erste Bild von rechts nachrueckt.

   Die zweite Haelfte traegt `aria-hidden`, der ganze Abschnitt ebenfalls:
   fuer ein Lesegeraet sind das sechzehn leere Bilder ohne Aussage. */
.abschnitt-laufband {
  padding-block: clamp(2rem, 5vw, 3.5rem);
  overflow: hidden;
}
.laufband {
  /* Weiche Kanten links und rechts, damit die Bilder nicht abgeschnitten
     wirken, sondern aus dem Dunkel kommen und darin verschwinden. */
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.laufband-spur {
  display: flex;
  gap: 20px;
  width: max-content;
  animation: laufband 64s linear infinite;
}
/* 320 x 400 — gemessen; die Bilder sind 4:5, die Hoehe gibt die Breite
   vor. Vorher 240 x 300, also ein Viertel zu klein. */
.laufband-spur img {
  height: clamp(220px, 28vw, 400px);
  width: auto;
  object-fit: cover;
  border-radius: var(--r-karte);
}
@keyframes laufband {
  /* `-50%` statt einer Pixelzahl: die Spur ist doppelt so breit wie die
     Folge, also ist die halbe Spur genau eine Folge — unabhaengig davon,
     wie breit die Bilder bei der aktuellen Hoehe geraten. */
  from { transform: translateX(0); }
  to   { transform: translateX(calc(-50% - 10px)); }
}
/* Der Abstand zwischen den beiden Haelften zaehlt mit: 50 % der Spur
   enthaelt die halbe Luecke an der Nahtstelle. Deshalb oben die 10px —
   die halbe `gap`. Wer `gap` aendert, muss sie mitziehen. */
@media (prefers-reduced-motion: reduce) {
  .laufband-spur { animation: none; }
}

/* -------------------------------------------------- Business: Partner -- */

/* Mittig gesetzter Block: Partnerzeichen, Ueberschrift, Text, Knopf. */
/* **Die Vermietungsseite fuehrt eine eigene Ueberschriftenstufe.**

   Auf der Startseite ist „DEMNÄCHST" 60px gross. Hier sind „Ihr Partner
   fuer…", „Die wichtigsten Fakten" und „Unsere Bereiche" durchgehend
   **36px/40px** — gemessen. Die Seite traegt mehr Text und kleinere
   Einheiten; eine 60px-Ueberschrift ueber vier Kacheln erschlaegt sie.

   Als Regel am `<main>` und nicht an jeder Ueberschrift einzeln: So gilt
   sie auch fuer alles, was spaeter dazukommt. */
/* „Jetzt bewerben" ist im Original 30px — kleiner als die 60px der
   Startseite und kleiner als die 36px der Vermietungsseite. */
.seite-jobs .kopfzeile h2 { font-size: 1.875rem; line-height: 1.2; }

.seite-business .kopfzeile h2,
.seite-business .partner h2,
.seite-business .ueber-text h2 {
  font-size: var(--t-h2-text);
  line-height: 1.11;
  letter-spacing: normal;
}

.partner { text-align: center; }
.partner-logo { display: inline-block; margin-bottom: 1.5rem; }
.partner-logo img { height: 46px; width: auto; }
.partner h2 { font-size: var(--t-h2); margin-bottom: 1.25rem; }
.seite-business .partner h2 { margin-bottom: 1.25rem; }
.partner p { color: var(--tinte-leise); margin: 0 auto; max-width: 60ch; }

/* **Der Partnerknopf traegt die Farbe des Partners, nicht unsere.**

   Trend ID fuehrt Gruen. Ein roter Knopf mit „Mehr ueber Trend ID" liest
   sich wie unser Angebot, nicht wie ein Wechsel auf eine fremde Seite.
   **Zwei Gruentoene, und das ist eine bewusste Abweichung.** Das Original
   fuellt mit `#4caf50` und schreibt Weiss darauf — das sind 2,78:1, nicht
   einmal die 3:1 fuer grosse Schrift. Zuerst hatte ich die Schrift dunkel
   gemacht; das traegt (6,99:1), sieht aber deutlich anders aus, besonders
   auf der vollflaechig gruenen Sektion.

   Jetzt stattdessen: die **Flaeche** wird satter, die Schrift bleibt
   weiss. `#2e7d32` ist dieselbe Gruenfamilie, nur eine Stufe dunkler
   (Material Green 800 statt 500), und traegt Weiss mit **5,13:1**. Damit
   bleibt der Eindruck des Originals erhalten — gruene Flaeche, weisse
   Schrift —, nur eben lesbar.

   Als **Schriftfarbe** auf dunklem Grund bleibt das helle `#4caf50`: dort
   sind es 6,99:1, da ist nichts zu heilen. */
.knopf-partner {
  --akzent: var(--gruen-partner);
  --akzent-rgb: 46 125 50;
  --akzent-tinte: #ffffff;
  --akzent-text: #4caf50;
}

/* Heller Knopf auf farbiger Flaeche — so steht „Mehr ueber Trend ID" auf
   dem gruenen Abschnitt. */
.knopf-hell {
  --akzent: #ffffff;
  --akzent-rgb: 255 255 255;
  --akzent-tinte: #0d0d0d;
  --akzent-text: #ffffff;
}

/* --------------------------------------------------- Business: Fakten -- */

/* **Gruene Haken, keine roten Balken.** Die Balken waren meine Zutat;
   das Original setzt vor jeden Punkt einen gefuellten Haken in
   `#4caf50`. Auf dem Seitengrund sind das 6,39:1 — der helle Ton kann
   hier bleiben. */
.fakten {
  display: grid;
  gap: 1.25rem;
  margin-top: 2rem;
}
.fakt {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem;
  align-items: start;
}
.fakt-haken {
  display: inline-flex;
  margin-top: 0.1em;
  color: #4caf50;
}
.fakt h3 {
  font-size: 0.875rem;
  margin-bottom: 0.25rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.fakt p { color: var(--tinte-leise); margin: 0; font-size: var(--t-klein); }

/* ------------------------------------------------- Business: Bereiche -- */

/* Acht Raeume als Bildkacheln. Vier Spalten waeren zu klein fuer die
   Bildunterschriften, zwei lassen die Fotos auf dem Schreibtisch
   aufblaehen — deshalb drei, und die achte Kachel beginnt eine neue Reihe.

   Die Beschriftung liegt **unter** dem Bild und nicht darauf: auf einem
   dunklen Clubfoto braucht Schrift darauf einen weiteren Schleier, und der
   naehme den Bildern genau das, wofuer sie dastehen. */
.bereiche {
  display: grid;
  gap: 24px;
  grid-template-columns: 1fr;
}
@media (min-width: 620px)  { .bereiche { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* **Drei Spalten, nicht vier.** Gemessen: 389px je Kachel, 24px Luecke.
   Mit vier Spalten wurden die Fotos so klein, dass die Raeume darauf
   nicht mehr zu unterscheiden waren. */
@media (min-width: 1024px) { .bereiche { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* **Dunkler als der Abschnitt, nicht heller — und mit Rundung.**

   Gemessen: Grund `#0d0d0d` auf dem `#181818` des Abschnitts, kein
   Rahmen, Radius 12px. Die 12px sind die einzige Rundung der ganzen
   Seite; Knoepfe, Eventkarten und Eingabefelder sind durchgehend scharf.
   Deshalb steht der Wert hier und nicht im Token-Block — `--r-karte`
   bleibt 0, sonst wanderte die Rundung an fuenfzig andere Stellen. */
.bereich {
  margin: 0;
  background: var(--nacht);
  border: 0;
  border-radius: 12px;
  overflow: hidden;
}
.bereich img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
.bereich figcaption { padding: 1rem; }
/* Weiss, nicht in der Akzentfarbe — gemessen. Rot war meine Zutat und
   liess acht Kacheln nebeneinander unruhig wirken. */
.bereich h3 {
  font-size: var(--t-klein);
  margin-bottom: 0.375rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--tinte);
}
.bereich p { color: var(--tinte-leise); font-size: var(--t-klein); margin: 0; }

/* ---------------------------------------------- Business: Videofenster -- */

/* `<dialog>` statt eigener Overlay-Bastelei: Der Browser haelt den Fokus
   darin, schliesst auf Escape und legt es ueber alles andere, ohne dass
   irgendwo ein `z-index` hochgezaehlt werden muss. */
.videofenster {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: min(92vw, 520px);
  max-height: 92svh;
  overflow: visible;
}
.videofenster::backdrop { background: rgb(0 0 0 / 82%); }
.videofenster video {
  display: block;
  width: 100%;
  height: auto;
  max-height: 86svh;
  background: #000;
  border-radius: var(--r-karte);
}
.videofenster-zu {
  position: absolute;
  top: -2.75rem;
  right: 0;
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  font-size: 1.75rem;
  line-height: 1;
  color: var(--tinte);
  background: rgb(var(--tinte-rgb) / 12%);
  border: 0;
  border-radius: var(--r-klein);
  cursor: pointer;
}
.videofenster-zu:hover { background: rgb(var(--tinte-rgb) / 22%); }
/* Auf sehr niedrigen Fenstern ist ueber dem Video kein Platz — dann
   wandert der Knopf hinein. */
@media (max-height: 640px) {
  .videofenster-zu { top: 0.5rem; right: 0.5rem; background: rgb(0 0 0 / 55%); }
}

/* ------------------------------------------------------- Kontaktangaben -- */

/* E-Mail und Adresse nebeneinander, Social Media darunter — so wie im
   Original. In derselben Spaltenbreite wie das Formular darueber, damit
   beides eine Flucht bildet. */
.kontakt-angaben {
  display: grid;
  gap: 2rem;
  max-width: 672px;
  margin-inline: auto;
}
@media (min-width: 620px) {
  .kontakt-angaben { grid-template-columns: 1fr 1fr; }
  .kontakt-sozial { grid-column: 1 / -1; }
}
.kontakt-angaben h2 {
  font-size: 1.125rem;
  margin-bottom: 0.625rem;
}
.kontakt-angaben p { color: var(--tinte-leise); margin: 0 0 0.5rem; }
.kontakt-angaben .fuss-social { margin: 0; }

/* Datumszeile ueber einem Rechtstext. */
.stand { color: var(--tinte-still); font-size: var(--t-klein); margin-bottom: 2rem; }

/* ---------------------------------------- Bausteine aus topagency-hp -- */

/* Zurueck in die Vorlage (Auftrag R9), hier ungenutzt. Werte von TOB
   Agency gemessen; Farben ueber die Token dieses Projekts. */

/* Einstiegspreis in `.karte-abriss`: „ab" und Betrag mit 4px Abstand,
   darunter 9px-Hinweis. */
.karte-preis { display: flex; flex-direction: column; gap: 2px; }
.karte-preis strong { display: flex; gap: 4px; font-size: 15px; line-height: 1.5; font-weight: 700; }
.karte-preis small { font-size: 9px; line-height: 1.3; }

/* Variante: schmalerer Listenrahmen fuer das Kartenraster. */
.karten--liste { max-width: 1140px; margin-inline: auto; }

/* Kennzeile ueber der Ueberschrift im Ueber-Abschnitt. */
.ueber-text .ueber-marke {
  margin: 0 0 20px;
  font-family: var(--schrift-display);
  font-size: 31px;
  font-weight: 800;
  line-height: 1;
  text-transform: uppercase;
  color: var(--akzent-text);
}

/* Fussspalte mit Social-Symbolen und Clubinio-Logo. */
.fuss-kanaele .clubinio { display: block; width: fit-content; }

/* ------------------------------------------------------------- Bewegung -- */

/* **Alles haengt an `html.anim`.** Diese Klasse setzt `assets/js/anim.js`,
   und zwar nur, wenn das Modul wirklich laeuft und `prefers-reduced-motion`
   nicht gesetzt ist. Faellt das Skript aus, bleibt die Klasse weg — und
   damit auch jede Regel, die etwas unsichtbar macht. Die Seite steht dann
   vollstaendig da, nur ohne Bewegung.

   Bewegt wird ausschliesslich `transform` und `opacity`. Beides laeuft im
   Compositor; alles andere (Hoehe, Position, Filter) erzwingt eine
   Neuberechnung des Layouts und ruckelt auf dem Telefon. */

html.anim [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.55s ease, transform 0.75s var(--kurve);
}
html.anim [data-reveal][data-sichtbar='ja'] {
  opacity: 1;
  transform: none;
}

/* Karten laufen versetzt ein, statt als Block aufzutauchen. Die
   Verzoegerung steht je Position im CSS, weil ein Inline-Style unter
   `style-src 'self'` nicht erlaubt waere. */
html.anim .karten [data-reveal]:nth-child(2) { transition-delay: 0.09s; }
html.anim .karten [data-reveal]:nth-child(3) { transition-delay: 0.18s; }
html.anim .karten [data-reveal]:nth-child(4) { transition-delay: 0.27s; }
html.anim .karten [data-reveal]:nth-child(5) { transition-delay: 0.36s; }
html.anim .karten [data-reveal]:nth-child(6) { transition-delay: 0.45s; }

/* Der Flyer zieht beim Darueberfahren leicht an. Die Karte selbst hebt
   schon ab — zusammen wirkt es, als laege das Bild tiefer in der Karte. */
.karte-bild { overflow: hidden; }
.karte-bild img { transition: transform 0.55s var(--kurve); }
.karte:hover .karte-bild img { transform: scale(1.05); }

/* Der Hero laeuft beim Laden auf: Logo, Titel, Knopf nacheinander. Kein
   Scroll-Ausloeser noetig — er steht ohnehin sofort im Bild. */
@keyframes hero-auf {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: none; }
}
html.anim .hero-logo,
html.anim .hero-titel,
html.anim .hero-text .knopf {
  animation: hero-auf 0.9s var(--kurve) both;
}
html.anim .hero-logo        { animation-delay: 0.08s; }
html.anim .hero-titel       { animation-delay: 0.22s; }
html.anim .hero-text .knopf { animation-delay: 0.40s; }

/* ---------------------------------------------------------------- Fehler -- */

.fehlerseite {
  min-height: 70svh;
  display: grid;
  place-items: center;
  text-align: center;
  padding-block: 4rem;
}
.fehlerseite .kennzahl {
  font-size: clamp(5rem, 18vw, 10rem);
  font-weight: 800;
  line-height: 1;
  color: var(--akzent-text);
}
/* Der Knopf unter einem Kartenblock steht mittig und mit Abstand — ohne
   das klebt er linksbuendig an der Unterkante der ersten Karte.

   **Ausdrueckliche Kennzeichnung im Markup, nicht ueber die Struktur.** An
   der Abschnitts-ID zu haengen war falsch (die heisst je Projekt anders),
   aber `.abschnitt > .huelle > .knopf-reihe` war zu weit: Auf den
   Eventseiten stehen die Knopfreihen in derselben Struktur und bekamen
   dadurch 44 Pixel Abstand nach oben — zwischen Ticket- und U18-Reihe klaffte
   eine Luecke, und das negative Mass an `.knopf-reihe-u18` war ueberschrieben. */
/* **Die beiden Formulare handhaben ihren Absendeknopf verschieden.**

   Gemessen: Auf /kontakt/ steht er links und nur so breit wie sein Text
   (242px), auf /jobs/ laeuft er ueber die volle Formularbreite (672px).
   Das ist kein Versehen des Originals — das Bewerbungsformular ist
   laenger, und ein schmaler Knopf am Ende einer langen Spalte wird
   uebersehen. Deshalb zwei Faelle statt einer Regel. */
.form .knopf-reihe { justify-content: flex-start; }
.form .knopf-reihe .knopf { width: auto; }
.form .knopf-reihe .knopf-voll { width: 100%; }

.knopf-reihe[data-mitte] {
  justify-content: center;
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
}
