/* ============================================================================
   Born 4 Korn — Design und Layout
   ----------------------------------------------------------------------------
   Ersetzt born4korn-party.de (WordPress mit Elementor) nach dem Open Air:
   „Wir sehen uns 2027" und der Rückblick mit dem Fotoalbum. Vorlage:
   halloween-hannover-hp (dasselbe Konzept, am selben Tag live).

   **Struktur vom System, Marke vom Original** (Übernahmeauftrag, R8).
   Farben, Schriften und Bilder von der bisherigen Seite: dunkler Grund
   #0b0b0b, Rot (gemessen #f3150f). Schrift: Inter, normal und fett —
   wie halloween-hannover-hp (Betreiber 01.11.2026).

   Neu im System: `.hero--seitlich`, `.abschnitt--akzent`, `.album-zahl`
   (docs/README.md). Aus sundayfunday-hp: `.hero--diashow`,
   `.hero--welle`, `.abschnitt--schraeg`.

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

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

/* **Eine Familie: Inter, nur normal (400) und fett (700).**

   Vorgabe des Betreibers (01.11.2026). Die Horror-Schrift des Originals
   (Kenyan Coffee) und NEXA entfallen; die Marke trägt der Schriftzug im
   Logo und im Hero. Inter ist die Systemschrift der Vorlage, SIL OFL 1.1
   — der Lizenztext liegt daneben (assets/fonts/OFL-inter.txt).

   **Andere Gewichte gibt es auf dieser Seite nicht.** Die Datei ist
   variabel (100–900); die Regeln setzen trotzdem nur 400 und 700 —
   tools/pruefen.py hält das fest.

   Vorgeladen wird inter-var.woff2. Wer die Familie tauscht, muss die
   `<link rel="preload">` in allen Seiten **und** in `tools/build.py`
   mitziehen. */
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

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

:root {
  /* **Dunkel**, wie born4korn-party.de (gemessen: Kopf und Fuß #0b0b0b,
     Seitengrund schwarz). */
  --nacht:        #0b0b0b;   /* Seitengrund */
  --box:          #1c1c1c;   /* dunkle Kästen (Albenkarten, Infokasten) */
  --box-hell:     #1c1c1c;   /* abgesetzte Fläche */
  --flaeche:      #0b0b0b;   /* Fuß — gemessen */
  --karte:        #1c1c1c;   /* Albenkarten — gemessen */
  --kopf:         rgb(11 11 11 / 94%);
  --linie:        #333333;   /* Trenner, Feldrahmen */

  --schrift-display: 'Inter', system-ui, -apple-system, sans-serif;
  --schrift-text:    'Inter', system-ui, -apple-system, sans-serif;
  --schrift-menu:    var(--schrift-text);
  --schrift-zier:    var(--schrift-display);
  --schrift-band:    var(--schrift-display);

  --tinte:        #ffffff;
  --tinte-leise:  #bdbdbd;   /* über 10:1 auf #0b0b0b */
  --tinte-still:  #9e9e9e;   /* über 7:1 auf #0b0b0b */
  --tinte-rgb:    255 255 255;
  /* Schrift auf dunklen Flächen (Fuß, Albenkarten, Bilder). */
  --tinte-hell:   #ffffff;

  /* **Akzent #dc1209 statt gemessen #f3150f** (Menü und Knopf des
     Originals). Weiß auf #f3150f misst 4,26:1 — unter AA. Derselbe
     Farbton dunkler: 5,08:1. Clubinio führt #F5E903 (das Gelb der „4" im
     Logo); die Seite selbst ist rot. */
  --akzent:       #dc1209;
  --akzent-tinte: #ffffff;
  --akzent-rgb:   220 18 9;
  /* Rot als **Schrift auf dunklem Grund**: aufgehellt, 5,93:1 auf
     #0b0b0b (tools/kontrast.js). */
  --akzent-text:  var(--akzent-hell);
  --akzent-hell:  #ff4a4a;

  /* Rundungen: Knöpfe und Felder leicht, Albenkarten 14px — wie die
     Karten und der Ticketkasten des Originals. */
  --r-knopf:      6px;
  --r-feld:       6px;
  --r-karte:      14px;
  --r-klein:      0;

  --schatten:     0 1px 2px rgb(0 0 0 / 12%), 0 8px 24px rgb(0 0 0 / 14%);
  --schatten-hoch: 0 2px 4px rgb(0 0 0 / 14%), 0 16px 40px rgb(0 0 0 / 20%);

  /* Schleier über den Bildbannern der Unterseiten. */
  --bild-schleier: 35%;

  --kurve:        cubic-bezier(0.32, 0.72, 0, 1);

  --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");

  /* **Gemessen: Kante bei 150px im 1440er Fenster, 20px auf dem Telefon.**
     Elementor setzt je Widget eigene Kanten: Kopf, Startseite und Alben
     150, Fotos 152, Impressum 160, Datenschutz 270. Eine Hülle für alle
     (System, R8) — auf der Kante, die die meisten Seiten haben:
     1180 − 2 × 20 = 1140 innen, Kante (1440 − 1180) / 2 + 20 = 150. */
  --breite:       1180px;
  --breite-schmal: 746px;    /* Kontaktformular: 706px gemessen + 2 × 20 */
  --gutter:       20px;

  /* Systemmaß, nicht das Original (100px) — Entscheidung des Betreibers. */
  --kopf-hoehe:   80px;

  /* Typografie, gemessen bei 390 / 768 / 1440. */
  --t-hero:   clamp(2.5rem, 6.4vw, 5.6875rem);  /* 91px */
  --t-h1:     clamp(2.1875rem, 7.85vw, 7.0625rem); /* 35 / 80 / 113px */
  --t-h2:     1.5rem;     /* 24px, ab 768: 34px (Stufe unten) */
  --t-h3:     1.125rem;
  --t-text:   1rem;
  --t-klein:  0.875rem;
}
/* h2-Stufe: gemessen 34px bei 768 und 1440 — Elementor wechselt erst
   unter 768 auf den Telefonwert, clamp() lag bei 768 auf 24px. */
@media (min-width: 768px) { :root { --t-h2: 2.125rem; } }

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

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

/* 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);
  /* 24px auf 16px — gemessen. */
  line-height: 1.5;
  -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);
  /* Inter fett — eines der beiden Gewichte der Seite. */
  font-weight: 700;
  /* Zeilenhöhe 1,0: Elementor setzt sie auf die Schriftgröße. */
  line-height: 1;
  text-transform: uppercase;
  /* Keine Sperrung — gemessen `normal`. */
  letter-spacing: normal;
}

/* **Kurze Etiketten tragen die Displayschrift**, nicht die Fließtextschrift. */
.karte-ort,
.karte-abriss,
.faq summary,
.zurueck,
.fehlerseite .kennzahl,
.sprung {
  font-family: var(--schrift-display);
}


/* 14px zwischen Absätzen — gemessen (Absatz bei 1547 + 72 = 1619, der
   nächste bei 1633). */
p { margin: 0 0 0.875rem; }
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(2.5rem, 5vw, 4rem); }
.abschnitt-flaeche { background: var(--flaeche); }

/* **Abschnitt auf Akzentgrund** — neu im System (`.abschnitt--akzent`).
   Aus halloween-hannover-hp („EINDRUCK GEFÄLLIG?" auf rotem Grund),
   Überschrift weiß. */
.abschnitt--akzent {
  background: var(--akzent);
  color: var(--akzent-tinte);
}
.abschnitt--akzent .kopfzeile h2 {
  color: inherit;
  font-size: clamp(2.5rem, 6vw, 4rem);   /* im Original rund 60px */
}

/* Abschnitt direkt unter einem anderen: kein Polster oben, der Abstand
   kommt vom Abschnitt darüber. Elementor stapelt die Container des
   Originals so — ein doppeltes Polster wäre eine Lücke, die es dort nicht
   gibt. **Das untere Polster bleibt** (Übernahmeauftrag, R7: in baggi-hp
   setzte `.abschnitt-oben` es auf null, und /kontakt/ klebte am Fuß). */
.abschnitt-oben { padding-top: 0; }

/* Bildabschnitt mit dunklem Schleier — Systembaustein. Born 4 Korn
   nutzt ihn nicht (siehe docs/README.md); die Regel bleibt, damit der
   Baustein in der Vorlage vollständig ist. */
.abschnitt-bild {
  position: relative;
  padding-block: clamp(3.5rem, 9vw, 6.25rem);
  background: url('../img/hero.webp') left 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));
}

/* **Schräg angeschnittenes Band** — neu im System (`.abschnitt--schraeg`).

   Das Original setzt „NEXT EVENTS" auf ein pinkes Band, das oben und unten
   schräg ausläuft (Elementor-Formteiler „tilt"). Gemessen: 226px hoch ab
   768px, 270px auf dem Telefon, Überschrift mittig.

   Der Anschnitt ist `clip-path`, kein SVG im Markup: Zierde gehört nicht
   in den Quelltext, und das Band bleibt ein einziges Element. Die Schräge
   ist in Pixeln, nicht in Prozent — sonst wäre sie auf dem Telefon flacher
   als auf dem Schreibtisch, während das Band dort sogar höher ist. */
.abschnitt--schraeg {
  --schraege: 50px;
  display: grid;
  align-items: center;
  min-height: 226px;
  padding-block: calc(var(--schraege) + 1rem);
  background: var(--akzent);
  color: var(--akzent-tinte);
  clip-path: polygon(0 var(--schraege), 100% 0, 100% calc(100% - var(--schraege)), 0 100%);
}
@media (max-width: 767px) {
  .abschnitt--schraeg { min-height: 270px; }
}
.abschnitt--schraeg .kopfzeile { margin-bottom: 0; }
.abschnitt--schraeg .kopfzeile h2 {
  font-family: var(--schrift-band);
  font-size: 2.1875rem;   /* 35px, ab 768: 56px */
  color: inherit;
}
@media (min-width: 768px) { .abschnitt--schraeg .kopfzeile h2 { font-size: 3.5rem; } }

/* Abschnittskopf: Überschrift, zentriert. */
.kopfzeile { text-align: center; margin-bottom: clamp(1.25rem, 3vw, 2.5rem); }
.kopfzeile h2 { font-size: var(--t-h2); }
.kopfzeile p {
  margin: 0.75rem 0 0;
  color: var(--tinte-leise);
  text-transform: none;
}
.kopfzeile .unterzeile { color: var(--akzent-text); font-weight: 400; }

/* **Zierzeile** — Systembaustein aus sundayfunday-hp (`.zierzeile`).

   Ein Beiklang in Schreibschrift über oder unter einer Überschrift.
   Inhaltlich keine Überschrift, sondern Beiklänge zur echten darunter oder
   darüber — deshalb `<p>`, nicht `<h2>`: sonst hätte die Seite zwei
   Überschriften für einen Abschnitt. Gewicht 700 auf einem Schnitt ohne
   Fett — siehe Schriften. */
.zierzeile {
  margin: 0;
  font-family: var(--schrift-zier);
  font-weight: 700;
  line-height: 1;
  color: var(--akzent-text);
  font-size: 1.5625rem;   /* 25px, ab 768: 51px */
}
.kopfzeile .zierzeile {
  margin: 0 0 1.25rem;
  color: var(--akzent-text);
  font-size: 1.5625rem;   /* 25px, ab 768: 69px */
}
/* **Stufen statt clamp()** — Elementor setzt je Stufe einen festen Wert,
   und bei 768 gelten schon die Desktopwerte. clamp() traf dort 37 statt
   51 bzw. 69px (Abgleich 31.10.2026). */
@media (min-width: 768px) {
  .zierzeile { font-size: 3.1875rem; }
  .kopfzeile .zierzeile { font-size: 4.3125rem; }
}

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

.knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  /* 12px/24px Polster, Zeilenhöhe 18px, **kein Rahmen** — alles gemessen.
     Zusammen 42px, die Höhe des Originals.

     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: 1;
  /* 900 — so setzt es das Original; NEXA hat darüber nur den Black-Schnitt
     (700), der Browser nimmt ihn ohne synthetisches Fett. */
  font-weight: 700;
  font-size: 1.125rem;      /* 18px — gemessen */
  text-transform: uppercase;
  letter-spacing: normal;
  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='M5 12h12.2l-4.6-4.6L14 6l6 6-6 6-1.4-1.4 4.6-4.6H5v-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='M5 12h12.2l-4.6-4.6L14 6l6 6-6 6-1.4-1.4 4.6-4.6H5v-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`. */
/* Auf hellem Grund: ein helles Grau statt `#1e1e1e` aus baggi-hp. */
.knopf-leer {
  background: var(--box-hell);
  color: var(--tinte);
  box-shadow: inset 0 0 0 1px rgb(var(--tinte-rgb) / 12%);
}
.knopf-leer:hover {
  filter: none;
  background: #e6e6e6;
  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[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;
  margin-top: 1.5rem;
}

/* Die Absendeknoepfe laufen im Original ueber die volle Formularbreite. */
.form .knopf-reihe { display: block; margin-top: 0.5rem; }
/* Pille, höher als der Systemknopf — Formular neu (Betreiber 01.11.2026). */
.form .knopf-reihe .knopf { width: 100%; padding-block: 1.1rem; border-radius: 980px; }

.icon { flex: none; }

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

/* **Systemkopf wie top10-singen-hp, nicht die feste schwarze Leiste aus baggi-hp.**

   Über Hero und Seitenbanner steht die Zeile frei im Bild — so auch im
   Original. Sobald gescrollt wird, bekommt sie einen Grund (`data-fest`,
   gesetzt von page-common.js). Das Original kennt diesen Zustand nicht:
   Sein Kopf ist `static` und scrollt mit weg (gemessen 31.10.2026). Der
   Grund ist deshalb geschlossen, nicht gemessen — siehe `--kopf`.

   `sticky` belegt Platz im Fluss. Hero und Seitenkopf ziehen sich mit
   negativem Rand darunter (siehe dort); beides gehört zusammen. */
.kopf {
  position: sticky;
  top: 0;
  z-index: 50;
  background: transparent;
  color: var(--tinte-hell);
  isolation: isolate;
  transition: background 0.25s ease;
}
.kopf[data-fest='ja'] {
  background: var(--kopf);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

/* **Weichzeichner aus, solange das Menü offen ist.** `backdrop-filter`
   erzeugt einen umgebenden Block für `position: fixed`; `.menu` liegt in
   `.kopf` und bezöge sein `inset` sonst auf die 80px hohe Leiste statt auf
   das Sichtfeld — das Menü wäre dann so gut wie nicht zu sehen. */
.kopf[data-offen='ja'] {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* Genau `--kopf-hoehe` hoch — Hero, Banner und Menü rechnen damit. */
.kopf-innen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  height: var(--kopf-hoehe);
}

/* Die Leiste läuft über die volle Fensterbreite; Marke und Menü stehen auf
   der Kante des Inhalts — gemessen: Logo bei 150, Menü endet bei 1290. */
.kopf-innen {
  max-width: none;
  padding-inline: max(var(--gutter),
                      calc((100% - var(--breite)) / 2 + var(--gutter)));
}

.logo { display: flex; align-items: center; }
/* Querformat-Schriftzug (941×100): gemessen 306px breit bei 1440,
   also rund 33px hoch; auf dem Telefon schmaler. */
.logo img { height: 22px; width: auto; }
@media (min-width: 768px) { .logo img { height: 33px; } }

.menu-knopf {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 6px;
  /* Gemessen am Original: 60×60, Pink, weiße Balken 30×2px. */
  width: 60px; height: 60px;
  padding: 0;
  border: 0;
  background: var(--akzent);
  color: var(--akzent-tinte);
  cursor: pointer;
}
.menu-knopf span {
  display: block;
  width: 30px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transition: transform 0.28s var(--kurve), opacity 0.2s ease;
}
/* 8px = halbe Balkenhöhe 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); }

/* **Abstand 31px zwischen zwei Punkten, mit pinkem Trennstrich in der
   Mitte** — gemessen: „Home" endet bei 987, „Events" beginnt bei 1018.
   Die Punkte selbst haben kein seitliches Polster (Kasten = Schrift). */
.menu ul {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0; padding: 0;
  list-style: none;
}

@media (min-width: 900px) {
  .menu li { display: flex; align-items: center; }
  .menu li:not(:last-child)::after {
    content: '';
    width: 1px;
    height: 16px;
    margin-inline: 15px;
    background: rgb(var(--akzent-rgb) / 60%);
  }
}

/* **`.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. */
/* 900, 20px/20px, Versalien, 5px oben und unten — gemessen. Schrift
   Inter statt Titillium (Betreiber 31.10.2026); Inter hat den 900er
   Schnitt wirklich, Titillium nahm dafür den 700er. */
.menu ul a {
  font-family: var(--schrift-menu);
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: normal;
  padding: 5px 0;
  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] { 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. */
  /* **Deckend, nicht `--kopf`.** Mit den 94 % der gescrollten Leiste
     schimmerte das Hero durch die Menüpunkte (Betreiber 01.11.2026:
     „halb transparent ist kacke"). */
  .kopf[data-offen='ja'] { background: var(--flaeche); }

  .menu {
    position: fixed;
    inset: var(--kopf-hoehe) 0 0;
    background: var(--flaeche);
    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); }

  /* 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 { font-size: var(--t-klein); margin: 0; }
  .menu-fuss a { font-size: var(--t-klein); color: rgb(255 255 255 / 75%); }
  .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;
  /* Unter die klebende Kopfzeile ziehen — sie steht frei im Bild. Das
     Gegenstück ist `padding-top` an `.hero-text`. */
  margin-top: calc(var(--kopf-hoehe) * -1);
  /* **Höhe als Token, Systemwert als Rückfall.** Feste Höhe, keine
     `vh`-Einheiten — sonst springt sie auf dem Telefon, wenn die
     Adressleiste ein- und ausfährt. */
  height: var(--hero-hoehe, clamp(500px, 71svh, 790px));
  display: grid;
  place-items: center;
  overflow: hidden;
  background: #181818;
  color: var(--tinte-hell);
  text-align: center;
}

/* Niedriger als die Vorlage: Nur Schriftzug, Dank und Titel — der
   Rückblick soll gleich darunter anklingen (Vorgabe wie
   halloween-hannover-hp). */
:root { --hero-hoehe: 560px; }
@media (min-width: 768px) { :root { --hero-hoehe: 640px; } }
@media (min-width: 1025px) { :root { --hero-hoehe: 760px; } }

.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 weiße Schrift auf dem Foto trägt. **Deckung
   geschlossen, nicht gemessen** — das Original legt eine Elementor-
   Überlagerung über die Diashow, deren Wert in referenz/ nicht steht. */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  /* 50 %: Das Heldenbild ist ein heller Sonnenuntergang; bei 30 % trug
     die rote Dankeszeile darauf nicht. */
  background: rgb(0 0 0 / 50%);
}

.hero-text {
  position: relative;
  z-index: 2;
  padding-top: var(--kopf-hoehe);
}

.hero-logo {
  /* Der Schriftzug „Born 4 Korn — Riesenstoppelfete Reesdorf" ist das
     Bildmotiv des Originals, kein kleines Logo. */
  width: min(88%, 640px);
  margin: 0 auto 1.5rem;
}

/* **Augenbraue über dem Titel** — hier die Dankeszeile. Ein `<p>`, keine
   Überschrift. Systembaustein (baggi-hp, sundayfunday-hp). */
.hero-augenbraue {
  margin: 0 0 0.625rem;
  font-family: var(--schrift-display);
  font-weight: 700;
  font-size: clamp(1.125rem, 4.6vw, 2.1875rem);
  line-height: 1;
  text-transform: uppercase;
  /* Hell, nicht `--akzent`: Dunkler Grund → helle Stufe, wie überall
     auf der Seite. */
  color: var(--akzent-hell);
}

/* Der Hero-Titel ist ein <p>, kein <h1> — die H1 der Seite steht statisch
   und für Lesegeräte unsichtbar im Markup. Sonst wären es zwei.
   Gemessen: 91px/91px ab 768, 50px auf dem Telefon, drei Zeilen. */
.hero-titel {
  margin: 0 0 2.25rem;
  font-family: var(--schrift-display);
  font-size: clamp(3.125rem, 11.85vw, 5.6875rem);
  font-weight: 700;
  line-height: 1;
  text-transform: uppercase;
}
.hero-titel span { display: block; }

/* **Der Hero-Knopf ist größer und gerundet.** Gemessen: NEXA 900 29px,
   12/24px Polster, 20px Radius — 353×53. Auf dem Telefon 16px (221×40). */
.hero-text .knopf {
  border-radius: 20px;
  font-size: clamp(1rem, 3.8vw, 1.8125rem);
}

/* **Diashow** — neu im System (`.hero--diashow`).

   Mehrere Bilder in `.hero-medium`, eines nach dem anderen sichtbar, mit
   langsamem Zoom. Werte des Originals (Elementor-Diashow): 6s je Bild,
   0,5s Überblendung, Ken Burns nach innen.

   **Reines CSS, kein Skript.** Die Bilder liegen übereinander; jedes läuft
   dieselbe Animation über die ganze Runde (Bildzahl × 6s) und ist nur in
   seinem Drittel sichtbar. Die Verzögerung je Bild steht hier — als
   Inline-Style wäre sie unter `style-src 'self'` nicht erlaubt. Für mehr
   als drei Bilder: `--bilder` setzen und je Bild eine Verzögerungszeile.

   Wer Bewegung abbestellt hat, sieht das erste Bild still. */
.hero--diashow { --bilder: 3; --dauer: 6s; }
.hero--diashow .hero-medium img {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: hero-dia calc(var(--bilder) * var(--dauer)) linear infinite;
}
.hero--diashow .hero-medium img:nth-child(1) { opacity: 1; }
.hero--diashow .hero-medium img:nth-child(2) { animation-delay: calc(var(--dauer) * 1); }
.hero--diashow .hero-medium img:nth-child(3) { animation-delay: calc(var(--dauer) * 2); }
/* Ein Drittel sichtbar (33,3 %), 0,5s Überblendung ≈ 2,8 % von 18s. */
@keyframes hero-dia {
  0%     { opacity: 0; transform: scale(1); }
  2.8%   { opacity: 1; }
  33.3%  { opacity: 1; }
  36.1%  { opacity: 0; transform: scale(1.15); }
  100%   { opacity: 0; transform: scale(1.15); }
}
@media (prefers-reduced-motion: reduce) {
  .hero--diashow .hero-medium img { animation: none; }
}

/* **Welle am unteren Rand** — neu im System (`.hero--welle`).

   Das Original setzt unter den Hero einen pinken Wellenstreifen, darunter
   weiß (Elementor-Widget „Animated Wave Divider"). Hier als ein SVG im
   CSS: hinten die pinke Welle, vorn die weiße in der Seitenfarbe. Die
   Bewegung des Widgets ist nicht übernommen — ein schwappender Rand unter
   einer Diashow mit Zoom wäre Bewegung auf Bewegung. */
.hero--welle::before {
  content: '';
  position: absolute;
  inset: auto 0 -1px;
  z-index: 3;
  height: clamp(40px, 7vw, 90px);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1440 90' preserveAspectRatio='none'%3E%3Cpath fill='%23dc1209' d='M0 38c240-38 480-38 720 0s480 38 720 0v52H0z'/%3E%3Cpath fill='%230b0b0b' d='M0 62c240-30 480-30 720 0s480 30 720 0v28H0z'/%3E%3C/svg%3E") center bottom / 100% 100% no-repeat;
  pointer-events: none;
}

/* **Text seitlich** — neu im System (`.hero--seitlich`).

   Für ein Heldenbild mit dem Motiv links und dunkler rechter Hälfte
   (halloween-hannover-hp). Ab 1025px steht der Text rechts, darunter
   mittig. Born 4 Korn nutzt den mittigen Hero — Systemvorrat. */
.hero--seitlich .hero-medium img { object-position: 25% center; }
.hero--seitlich::after {
  background: linear-gradient(to bottom, rgb(0 0 0 / 15%), rgb(0 0 0 / 70%) 65%, rgb(17 17 17) 100%);
}
.hero--seitlich .hero-text { display: grid; justify-items: center; }
.hero--seitlich .hero-logo { width: min(78%, 420px); margin-bottom: 1.5rem; }
.hero--seitlich .hero-titel { margin-bottom: 0; }
/* Nur Schriftzug und Titel — der Hero ist deshalb niedriger als das
   Systemmaß, damit der Rückblick schon im ersten Bild anklingt. */
.hero--seitlich { height: clamp(560px, 78svh, 760px); }
@media (min-width: 1025px) {
  .hero--seitlich { place-items: center end; }
  .hero--seitlich::after {
    background: linear-gradient(to right, transparent 35%, rgb(0 0 0 / 55%) 60%, rgb(0 0 0 / 55%));
  }
  .hero--seitlich .hero-medium img { object-position: left center; }
  .hero--seitlich .hero-text {
    width: 50%;
    max-width: none;
    margin: 0;
    padding-inline: 0 max(var(--gutter), calc((100vw - var(--breite)) / 2 + var(--gutter)));
  }
}

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

/* Drei Spalten, Abstand 20px — ab Tablet abwärts eine Spalte. Systemmaß:
   Das Original zeigt derzeit keine Karten (0 Termine), es gibt nichts zu
   messen. Kartenform aus cosmopolar-hp. */
.karten {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 1024px) {
  .karten { grid-template-columns: 1fr; }
}

.karte {
  /* Höhe des Abrisses — die Kerben im Hintergrund sitzen genau dort. */
  --abriss: 44px;
  display: flex;
  flex-direction: column;
  /* Die Kerben sind **Aussparungen im Kartenhintergrund**, keine farbigen
     Kreise. Zwei Kreise in der Hintergrundfarbe waeren nur auf schwarzem
     Grund unsichtbar — der Eventabschnitt der Startseite liegt aber auf
     einem Foto, dort staenden sie als dunkle Punkte. So stanzen sie
     wirklich, und es zeigt sich, was immer dahinterliegt. */
  background:
    radial-gradient(circle 11px at 0 calc(100% - var(--abriss)),
      transparent 11px, var(--karte) 11.5px) left / 51% 100% no-repeat,
    radial-gradient(circle 11px at 100% calc(100% - var(--abriss)),
      transparent 11px, var(--karte) 11.5px) right / 51% 100% no-repeat;
  border-radius: var(--r-karte);
  /* Damit der Flyer die Rundung der Karte uebernimmt, ohne ihn einzeln zu
     runden — sonst steht an der Oberkante eine Ecke ueber. */
  overflow: hidden;
  /* Dunkle Karte auf weißem Grund — wie die Albenkarten des Originals. */
  color: var(--tinte-hell);
  box-shadow: var(--schatten);
  transition: transform 0.3s var(--kurve), box-shadow 0.3s var(--kurve);
}
.karte:hover {
  transform: translateY(-6px);
  box-shadow: var(--schatten-hoch);
}
.karte:active { transform: translateY(-2px); }

.karte-bild { background: #1a1a1a; }
/* 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.375rem;
  padding: 0.875rem 0.9375rem 1rem;
  flex: 1;
}
/* Der Abschnitt unter der Perforation, wie bei einer Eintrittskarte:
   links Termin und Uhrzeit, rechts der Weg zur Veranstaltung.

   Feste Hoehe aus `--abriss`, damit die Trennlinie genau dort sitzt, wo die
   Kerben im Kartenhintergrund ausgespart sind. Waechst der Abschnitt mit
   seinem Inhalt, wandert die Linie und die Stanzung passt nicht mehr. */
.karte-abriss {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  height: var(--abriss);
  margin: 0;
  padding-inline: 0.9375rem;
  border-top: 2px dashed rgb(255 255 255 / 18%);
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.karte-termin { color: rgb(255 255 255 / 72%); white-space: nowrap; }
.karte-infos {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--akzent-hell);
  transition: gap 0.22s var(--kurve);
}
/* Der Pfeil rueckt beim Darueberfahren ein Stueck weiter — die Karte ist
   ein Link, und das zeigt sie damit. */
.karte:hover .karte-infos { gap: 0.6rem; }
.karte-titel {
  font-size: var(--t-h3);
  line-height: 1.2;
}
/* Ortszeile unter dem Titel, in der Akzentfarbe. */
.karte-ort {
  margin: 0;
  color: var(--akzent-hell);
  font-size: var(--t-klein);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Monatsüberschrift der Eventliste. */
.monat {
  font-size: var(--t-h3);
  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;
}
/* Im Kartenraster über alle Spalten — sonst steht der Hinweis in einem
   Drittel der Breite und bricht nach drei Wörtern um. */
.karten > .leer { grid-column: 1 / -1; }
/* Verweise im Hinweis (E-Mail auf /kontakt/) als Verweis erkennbar. */
.leer a { color: var(--akzent-text); text-decoration: underline; text-underline-offset: 3px; }


/* ------------------------------------------------------------ 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(var(--tinte-rgb) / 8%);
  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%); }

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

/* Bildbanner der Unterseiten — **ein Bild für alle**: das Heldenbild
   des Originals (Menge vor der Bühne), mit leichtem Schleier. */
.seitenkopf-bild {
  position: relative;
  background-position: center center;
  background-size: cover;
  background-repeat: no-repeat;
  isolation: isolate;
}
.seitenkopf-bild {
  background-image: linear-gradient(rgb(0 0 0 / var(--bild-schleier)), rgb(0 0 0 / var(--bild-schleier))),
                    url('../img/hero.webp');
  background-position: center, center;
}

/* **Feste Höhe, gemessen ab Fensteroberkante** (also samt Kopfzeile):
   456px bei 1440, 481px bei 768, 356px auf dem Telefon. Der Banner läuft
   unter die klebende Kopfzeile — negativer Rand **und** Polster gehören
   zusammen: Der Rand schiebt ihn unter die Leiste, das Polster holt den
   Inhalt wieder in die sichtbare Fläche. */
/* **Zentriert über die volle Höhe**, nicht über die Höhe unter dem Kopf —
   gemessen: Titel bei 193 in einem 456px-Banner (90px hoch, Mitte 238).
   Mit Polster für den Kopf saß er 30px zu tief. Die Kopfzeile liegt frei
   darüber; der Titel bleibt bei jeder Stufe unter ihr. */
.seitenkopf {
  margin-top: calc(var(--kopf-hoehe) * -1);
  height: 356px;
  display: grid;
  align-content: center;
  background-color: #181818;
  color: var(--tinte-hell);
  text-align: center;
}
@media (min-width: 768px) { .seitenkopf { height: 481px; } }
@media (min-width: 1025px) { .seitenkopf { height: 456px; } }

/* Ein Rasterelement schrumpft sonst nicht unter die Mindestbreite seines
   längsten Wortes — „DATENSCHUTZ" liefe auf dem Telefon über den Rand. */
.seitenkopf > .huelle {
  min-width: 0;
  display: grid;
  justify-items: center;
}

/* Gemessen: NEXA 700, 113px / 80px / 67px, Zeilenhöhe 0,8. Impressum und
   Datenschutz stehen auf dem Telefon bei 35px — ihre Wörter sind länger. */
.seitenkopf h1 {
  font-size: 4.1875rem;
  line-height: 0.8;
  overflow-wrap: anywhere;
}
@media (max-width: 767px) {
  .seitenkopf--lang h1 { font-size: 2.1875rem; }
}
@media (min-width: 768px) { .seitenkopf h1 { font-size: 5rem; } }
@media (min-width: 1025px) { .seitenkopf h1 { font-size: 7.0625rem; } }

/* **Die Unterzeile ist ein schräges Etikett in der Akzentfarbe**, das
   über die Unterkante des Titels ragt. Systemklasse aus sundayfunday-hp:
   32/23/14px, 10/20px Polster (5/10 auf dem Telefon), um rund 5° gedreht. */
.seitenkopf .unterzeile {
  margin: -0.35em 0 0;
  padding: 10px 20px;
  background: var(--akzent);
  color: var(--akzent-tinte);
  font-family: var(--schrift-display);
  font-weight: 700;
  /* Stufen statt clamp(): Elementor setzt je Stufe einen festen Wert —
     14 / 23 / 32px, gemessen. clamp() traf 31,68 statt 32. */
  font-size: 0.875rem;
  line-height: 1;
  text-transform: uppercase;
  transform: rotate(-5deg);
}
@media (max-width: 767px) {
  .seitenkopf .unterzeile { padding: 5px 10px; }
}
@media (min-width: 768px) { .seitenkopf .unterzeile { font-size: 1.4375rem; } }
@media (min-width: 1025px) { .seitenkopf .unterzeile { font-size: 2rem; } }

/* ------------------------------------------------------------------ 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, fällt die linke Spalte weg; das Formular nimmt die
     schmale Hülle ganz ein. */
  .kontakt-raster[data-ohne-faq='ja'] { grid-template-columns: minmax(0, 1fr); }
}

.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 -- */

/* **Seiten ohne Bild unter dem Kopf: Kopf deckend.** Albenseiten (und die
   404) haben keinen Banner; die weiße Menüschrift stünde sonst auf Weiß.
   Gemessen: Auf den Albenseiten des Originals ist die Leiste #252525.
   Als `:has()` an der Seite und nicht als Klasse am Kopf — der Rahmen ist
   auf allen Seiten wortgleich (tools/rahmen.py). */
body:not(:has(.hero, .seitenkopf)) .kopf { background: var(--flaeche); }

/* Die Albenliste. Gemessen: zwei Spalten ab 768px, 30px Abstand, auf dem
   Telefon eine. Systemklassen wie top10-singen-hp, Markenform des
   Originals (Plugin clubinio-fotos). */
.alben-raster {
  display: grid;
  gap: 30px;
  grid-template-columns: 1fr;
}
@media (min-width: 768px) {
  .alben-raster { grid-template-columns: 1fr 1fr; }
  /* Ein einziges Album: mittig in Spaltenbreite statt links in der Hälfte. */
  .alben-raster:has(> :only-child) { grid-template-columns: minmax(0, 555px); justify-content: center; }
}

/* **Dunkle Karte, 14px Radius**, Text mittig (aus halloween-hannover-hp,
   dort gemessen am Plugin clubinio-fotos). */
.album-karte {
  display: flex;
  flex-direction: column;
  border-radius: var(--r-karte);
  background: var(--karte);
  overflow: hidden;
  color: var(--tinte-hell);
  transition: transform 0.3s var(--kurve), box-shadow 0.3s var(--kurve);
}
.album-karte:hover { transform: translateY(-4px); box-shadow: var(--schatten-hoch); }

/* Quadratisch wie im Original (472×472 bei 1440). Fest, damit die Karten
   einer Reihe gleich hoch beginnen. */
.album-bild {
  position: relative;
  aspect-ratio: 1 / 1;
  background: #222222;
  overflow: hidden;
}
.album-bild img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 0.55s var(--kurve);
}
.album-karte:hover .album-bild img { transform: scale(1.04); }

.album-text {
  flex: 1;
  padding: 28px 18px 36px;
  text-align: center;
}
/* Bildzahl unten rechts im Bild — „151" im Original. */
.album-zahl {
  position: absolute;
  right: 14px;
  bottom: 12px;
  z-index: 1;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgb(0 0 0 / 60%);
  font-size: 0.8125rem;
  font-weight: 700;
}
/* Datum: klein, fett, Versalien. Rot auf #1c1c1c als kleine Schrift
   braucht die helle Stufe (`--akzent-hell`). */
.album-zeile {
  margin: 0 0 6px;
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1.5;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--akzent-hell);
}
/* Inter fett; breiter als eine schmale Displayschrift, deshalb höchstens
   32px — sonst läuft ein Albentitel bis an den Kartenrand. */
.album-titel {
  font-size: clamp(1.5rem, 3vw, 2rem);
  line-height: 1;
}
.album-ort {
  margin: 8px 0 0;
  font-weight: 700;
  color: var(--akzent-hell);
}

/* Albenseite: Titel links, darunter die Angaben. Gemessen NEXA 67px/1,2
   (50px bei 768, 42px auf dem Telefon), Angaben NEXA 15,2px — bis 1024px
   je eine Zeile, darüber nebeneinander mit Trennpunkt. */
/* Gemessen: Titel bei 208 (1440) und 157 (390) von der Fensteroberkante,
   erstes Bild 102px unter den Angaben. Das Abschnittspolster allein
   setzte den Titel 64px zu hoch. */
.kopfzeile-links {
  text-align: left;
  padding-top: clamp(37px, 4.4vw, 64px);
  margin-bottom: clamp(32px, 5vw, 64px);
}
.kopfzeile-links h1 {
  font-size: 2.625rem;
  line-height: 1.2;
}
@media (min-width: 768px) { .kopfzeile-links h1 { font-size: 3.125rem; } }
@media (min-width: 1025px) { .kopfzeile-links h1 { font-size: 4.1875rem; } }
.kopfzeile-links .unterzeile span { display: block; margin-bottom: 10px; }
@media (min-width: 1025px) {
  .kopfzeile-links .unterzeile span { display: inline; margin: 0; }
  .kopfzeile-links .unterzeile span + span::before { content: ' · '; }
}
.kopfzeile-links .unterzeile {
  margin-top: 20px;
  font-family: var(--schrift-text);
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--tinte);
}

/* **Zwei Spalten, die erst links, dann rechts füllen** — CSS-`columns`,
   wie das Original (Plugin clubinio-fotos): Im DOM stehen dort Bild 1 bis
   8 alle in der linken Spalte untereinander, gemessen 31.10.2026. 15px
   Abstand, 8px Radius, auch auf dem Telefon zwei Spalten. Die Bilder
   behalten ihr Format, hoch neben quer. */
.fotoraster {
  columns: 2;
  column-gap: 15px;
}
/* Drei Spalten ab 1025px: Die Vorschaubilder sind 480px breit und sollen
   nicht hochgezogen werden. */
@media (min-width: 1025px) { .fotoraster { columns: 3; } }
.fotoraster figure {
  position: relative;
  margin: 0 0 15px;
  break-inside: avoid;
  border-radius: 8px;
  overflow: hidden;
  background: #171a21;
  cursor: zoom-in;
}
.fotoraster img { width: 100%; height: auto; }
/* Auf dem Telefon senkrecht nur 10px — gemessen (Bild 112px hoch, das
   nächste 122px tiefer); waagerecht bleiben es 15. */
@media (max-width: 767px) { .fotoraster figure { margin-bottom: 10px; } }

/* „Foto melden" — Fähnchen oben rechts im Bild, erst beim Darüberfahren
   deutlich. Wie im Original (Plugin clubinio-fotos). */
.melde-knopf {
  position: absolute;
  top: 8px; right: 8px;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: rgb(0 0 0 / 55%);
  color: var(--tinte-hell);
  opacity: 0.7;
  transition: opacity 0.2s ease;
}
.fotoraster figure:hover .melde-knopf, .melde-knopf:focus-visible { opacity: 1; }

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

/* **Formular neu gesetzt — nicht mehr das Original** (Betreiber
   01.11.2026: „moderner", Vorbild die Kontaktseite eines Schwesterclubs).
   Gefüllte Felder ohne Rahmen, gerundet, Beschriftung in gemischter
   Schreibung, kurze Felder nebeneinander, Absendeknopf als Pille über die
   volle Breite.
   Übertragen auf hellen Grund: Die Fläche ist Tinte mit 5 %, nicht Weiß
   mit 6 % wie dort. Der Abgleich zählt das Formular deshalb nicht mehr
   gegen das Original (tools/abgleich.py, ERSETZT). */
.form {
  display: grid;
  gap: 1.375rem;
  --r-feld: 14px;
}

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

/* Kurze Felder nebeneinander. `auto-fit` statt fester Spalten: unter
   ~420px je Feld bricht die Reihe von selbst um, ohne eigene Abfrage. */
.form-reihe {
  display: grid;
  gap: 1.375rem 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 — traegt ein
   Feld einen Hinweis darunter und sein Nachbar nicht, verteilt sich der
   Ueberschuss auf Beschriftung und Eingabefeld, und die beiden Felder
   beginnen nicht mehr auf einer Linie. */
.feld {
  display: grid;
  gap: 0.5rem;
  align-content: start;
}
.feld > span {
  font-size: 0.9375rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--tinte-leise);
}
.feld-optional { font-style: normal; color: var(--tinte-still); }
.feld-pflicht { font-style: normal; color: var(--akzent-text); }

input[type='text'], input[type='email'], input[type='tel'],
input[type='number'], input[type='file'], textarea, select {
  width: 100%;
  padding: 0.95rem 1.05rem;
  /* Kein Rahmen. Die Flaeche allein zeigt, wo geschrieben wird — eine Linie
     um jedes Feld zieht das Formular in Kaestchen auseinander. */
  border: 0;
  border-radius: var(--r-feld);
  background: rgb(var(--tinte-rgb) / 5%);
  color: var(--tinte);
  font: inherit;
  /* **Nach `font: inherit`.** Die Kurzschreibweise setzt `line-height`
     zurück — dieselbe Falle wie beim Knopf. */
  line-height: 1.4;
  transition: box-shadow 0.2s ease, background 0.2s ease;
}
:is(input[type='text'], input[type='email'], input[type='tel'],
    input[type='number'], textarea, select):hover:not(:focus) {
  background: rgb(var(--tinte-rgb) / 7%);
}
/* Eigener Pfeil: Der des Systems sitzt am Rand und passt nicht zur Rundung. */
select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.75rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%23555555' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round' d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1.05rem center;
  background-size: 16px 16px;
  cursor: pointer;
}
textarea {
  min-height: 150px;
  resize: vertical;
}
/* Fokus: Feld wird weiß, Ring aussen. Er liegt ueber dem Rand, nicht
   darin, und verschiebt deshalb nichts. */
input:focus, textarea:focus, select:focus {
  outline: 0;
  background-color: var(--nacht);
  box-shadow: 0 0 0 2px rgb(var(--akzent-rgb) / 55%);
}
/* 58 % Tinte auf der 5-%-Fläche ≈ #676767 auf #f2f2f2: 5,1:1. Das stille
   Grau (#767676) läge dort unter 4,5. */
::placeholder { color: rgb(var(--tinte-rgb) / 58%); 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(var(--tinte-rgb) / 8%);
  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(var(--tinte-rgb) / 14%);
}
input[type='file']:focus-visible::file-selector-button {
  outline: 2px solid var(--akzent);
  outline-offset: 2px;
}

/* 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: 0.9375rem;
  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: 7px;
  background: rgb(var(--tinte-rgb) / 8%);
  cursor: pointer;
  transition: background 0.2s ease;
}
.auswahl label:hover input:not(:checked),
.zustimmung:hover input:not(:checked) { background: rgb(var(--tinte-rgb) / 14%); }
.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;
}

/* Grün, nicht in der Akzentfarbe: Pink wäre dem Fehlerfall zu nah.
   #2e7d32 trägt weiße Schrift mit 5,13:1. */
.rueckmeldung[data-state='ok'] {
  background: rgb(46 125 50 / 12%);
  box-shadow: inset 0 0 0 1px #2e7d32;
  color: var(--tinte);
  font-weight: 400;
}
.rueckmeldung[data-state='ok']::before {
  background-color: #2e7d32;
  background-image: var(--haken);
}

.rueckmeldung[data-state='fehler'] {
  background: rgb(var(--akzent-rgb) / 10%);
  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); }

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

/* **Zwischentitel als fetter Fließtext, nicht als Überschrift.** Das
   Original setzt sie in Textgröße (16px, fett), die Haftungsabschnitte
   zusätzlich unterstrichen — gemessen am Impressum. Im Markup bleiben es
   h2/h3, damit die Gliederung für Lesegeräte stimmt. */
.rechtstext { max-width: 72ch; }
.rechtstext h2, .rechtstext h3 {
  margin: 1.5rem 0 0;
  font-family: var(--schrift-text);
  font-size: var(--t-text);
  font-weight: 700;
  line-height: 1.5;
  text-transform: none;
}
.rechtstext h2 { text-decoration: underline; }
.rechtstext h2:first-child, .rechtstext h3:first-child { margin-top: 0; }
/* So breit wie der Text — im Original ein fettes `strong` im Absatz. */
.rechtstext h2, .rechtstext h3 { width: fit-content; }
.rechtstext p, .rechtstext li { color: var(--tinte); }
.rechtstext a { color: var(--akzent-text); }
.rechtstext ul { padding-left: 1.25rem; }
.rechtstext address { font-style: normal; margin-bottom: 0.875rem; }

/* **Zwei Spalten** — Variante des Rechtstexts (`.rechtstext--zweispaltig`).
   Das Impressum des Originals steht ab 768px in zwei gleich breiten
   Spalten, 20px Abstand (gemessen: 550 + 20 + 550 bei 1440). */
/* `max-width` der Hülle, nicht `none`: Beide Klassen sitzen am selben
   Element, und `none` hob die Breite der `.huelle` mit auf — der Text lief
   bis an den Fensterrand. */
.rechtstext--zweispaltig {
  display: grid;
  gap: 1.5rem 20px;
  max-width: var(--breite);
}
@media (min-width: 768px) {
  .rechtstext--zweispaltig { grid-template-columns: 1fr 1fr; }
}

/* „powered by clubinio" in Schwarz unter den Pflichtangaben — Variante
   des Systembausteins `.clubinio`, größer als im Fuß (gemessen 215×71 bei
   1440, 138×46 bei 768). */
/* Doppelte Klasse: `.clubinio` und `.clubinio img` stehen weiter unten
   im Fuß und gewännen bei gleicher Spezifität (Höhe 39px, Rand 30px). */
.clubinio.clubinio--gross { display: block; margin-top: 1.5rem; }
.clubinio.clubinio--gross img { width: 138px; height: auto; }
@media (min-width: 1025px) { .clubinio.clubinio--gross img { width: 215px; } }

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

/* Grund wie die Seite, zwei gleich breite Spalten
   ab 768px — links Marke, rechts „Links" rechtsbündig. Auf dem Telefon untereinander, alles linksbündig. */
.fuss {
  background: var(--flaeche);
  color: var(--tinte-hell);
  padding-block: 40px 2.5rem;
}
.fuss-raster {
  display: grid;
  gap: 2.5rem 20px;
  grid-template-columns: 1fr;
}
@media (min-width: 768px) {
  .fuss-raster { grid-template-columns: 1fr 1fr; }
}

/* Logo mit Slogan: 182px breit bei 1440, 120 bei 768, 109 auf dem Telefon. */
.fuss-logo { width: 196px; margin-bottom: 19px; }

.fuss p { color: var(--tinte-hell); font-size: var(--t-klein); line-height: 1.5; }
@media (min-width: 768px) { .fuss p { font-size: var(--t-text); } }
.fuss a:hover { color: var(--akzent-hell); }

/* **„Quick Links" ist die Rechtsspalte des Systems** (`.fuss-recht`), hier
   mit Überschrift wie im Original: NEXA 27px in Pink (20px auf dem
   Telefon), darunter die drei Verweise untereinander, rechtsbündig ab
   768px. Pink auf #252525 misst 3,4:1 — für Großschrift (ab 18,66px fett)
   genügen 3:1. */
/* Die Elemente bleiben spaltenbreit; nur der Text steht rechts —
   gemessen: „QUICK LINKS" und jeder Verweis 550px breit. */
.fuss-recht {
  display: grid;
  align-content: start;
  font-size: var(--t-klein);
  line-height: 1.5;
}
@media (min-width: 768px) {
  .fuss-recht { text-align: right; }
}
@media (min-width: 1025px) {
  .fuss-recht { font-size: var(--t-text); }
}
.fuss-recht h2 {
  margin-bottom: 20px;
  font-size: 1.75rem;
  color: var(--akzent-text);   /* Rot auf Dunkel: helle Stufe */
}
.fuss-recht a { color: var(--tinte-hell); }
@media (min-width: 768px) { .fuss-recht h2 { font-size: 1.6875rem; } }

/* Symbole in 40px-Kreisen, 5px Abstand — gemessen. */
.fuss-social { display: flex; gap: 5px; margin: 20px 0 0; }
.fuss-social a {
  display: grid;
  place-items: center;
  width: 40px; height: 40px;
  color: var(--akzent-hell);
}
.fuss-social a:hover { color: var(--tinte-hell); }

/* „powered by clubinio": 128×50 bei 1440, 98×39 bei 768. */
.clubinio { display: inline-block; margin-top: 30px; }
.clubinio img { height: 39px; width: auto; }
@media (min-width: 1025px) { .clubinio img { height: 50px; } }

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

/* **Unter dem Formular nur die Social-Symbole, mittig** — so das Original:
   56px große Felder (44 auf dem Telefon), 5px Abstand, Pink auf Weiß.
   Der Block mit E-Mail und Anschrift aus baggi-hp entfällt: Die Anschrift ist hier
   der Sitz der GbR, kein Ort, an dem man jemanden antrifft. */
.fuss-social--gross {
  justify-content: center;
  margin-top: 20px;
}
.fuss-social--gross a {
  width: 44px; height: 44px;
  color: var(--akzent-text);
}
.fuss-social--gross a:hover { color: var(--tinte); }
.fuss-social--gross .icon { width: 22px; height: 22px; }
@media (min-width: 768px) {
  .fuss-social--gross a { width: 56px; height: 56px; }
  .fuss-social--gross .icon { width: 28px; height: 28px; }
}

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

/* ------------------------------------------------------------- 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: 700;
  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. */
.knopf-reihe[data-mitte] {
  justify-content: center;
  margin-top: clamp(1.75rem, 4vw, 2.75rem);
}
