/* ============================================================
   Sängervereinigung Mainflingen 1887 — Stylesheet
   Farben und Maße stehen alle hier oben. Wer das Aussehen
   ändern will, ändert in der Regel nur diesen Block.
   ============================================================ */
:root {
  --rot: #e30d31;          /* auf Weiß 4,81:1 — knapp über WCAG AA, nicht aufhellen */
  --rot-dunkel: #b60a27;
  --violett: #513270;
  --gruen: #2f6b46;        /* auf Weiß 6,34:1 — die Farbe der Proben */
  --weiss: #ffffff;
  --grau-50: #f7f7f8;
  --grau-100: #eeeef0;
  --grau-300: #cfcfd4;
  --grau-500: #6b6b74;
  --grau-700: #4a4a52;
  --grau-900: #1d1d21;

  --lesebreite: 68ch;      /* Zeilenlänge der Textspalte */
  --seitenbreite: 1180px;
  --abstand: 1.5rem;
  --rundung: 10px;
  --schatten: 0 2px 10px rgba(0, 0, 0, .08);

  /* Startseiten-Bühne: HIER das Foto tauschen */
  --buehne-bild: url("/assets/img/buehne.jpg");

  --schrift: system-ui, -apple-system, "Segoe UI", Roboto,
             "Helvetica Neue", Arial, sans-serif;
}

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

body {
  margin: 0;
  font-family: var(--schrift);
  font-size: 1.05rem;
  line-height: 1.65;
  color: var(--grau-900);
  background: var(--weiss);
}

h1, h2, h3, h4 { line-height: 1.25; color: var(--violett); margin: 2rem 0 .6rem; }
h1 { font-size: clamp(1.8rem, 4vw, 2.6rem); margin-top: 0; }
h2 { font-size: clamp(1.4rem, 3vw, 1.9rem); }
h3 { font-size: 1.25rem; }

a { color: var(--rot); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--rot-dunkel); }
:focus-visible { outline: 3px solid var(--violett); outline-offset: 2px; }

img { max-width: 100%; height: auto; }

.sprungmarke {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--weiss); padding: .6rem 1rem;
}
.sprungmarke:focus { left: .5rem; top: .5rem; }

/* Text, den nur Sprachausgaben bekommen. Nicht display:none und nicht
   visibility:hidden — beides nähme ihn auch der Sprachausgabe weg. */
.nur-vorlesen {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---------- Kopf und Navigation ---------- */
/* Höhe für die per JavaScript eingesetzten Bausteine vorab reservieren,
   damit beim Nachladen nichts springt. */
[data-include="header"] { min-height: 72px; }
[data-include="footer"] { min-height: 200px; }

/* Die Kopfzeile klebt oben. Ohne die folgende Zeile springt der Browser bei
   einem Anker genau so weit, dass das Ziel HINTER der Kopfzeile liegt — es ist
   dann eingeblendet und trotzdem nicht zu sehen. Aufgefallen ist das an der
   Bestätigung nach dem Absenden des Kontaktformulars (#meldung-ok): gemessen
   stand sie bei 0 px, die Kopfzeile ist 72 px hoch (schmal 76 px). Betrifft
   ebenso die Sprungmarke „Zum Inhalt springen" und #frueher auf der
   Neuigkeitenseite. 6rem lassen etwas Luft darüber. */
html { scroll-padding-top: 6rem; }

.kopf {
  position: sticky; top: 0; z-index: 50;
  background: var(--weiss); border-bottom: 1px solid var(--grau-100);
  min-height: 72px;                 /* verhindert Springen beim Nachladen */
}
.kopf__innen {
  max-width: var(--seitenbreite); margin: 0 auto;
  display: flex; align-items: center; gap: var(--abstand);
  padding: .6rem var(--abstand);
}
.kopf__logo { display: flex; align-items: center; gap: .7rem; text-decoration: none; }
.kopf__logo img { height: 52px; width: auto; }
.kopf__name { font-weight: 700; color: var(--violett); line-height: 1.2; }
.kopf__name span { display: block; font-weight: 400; font-size: .8rem; color: var(--grau-500); }

.burger {
  margin-left: auto; background: none; border: 0; padding: .5rem;
  font-size: 1.6rem; line-height: 1; color: var(--violett); cursor: pointer;
}

.menue, .menue ul { list-style: none; margin: 0; padding: 0; }
.menue a { display: block; padding: .6rem .2rem; text-decoration: none; color: var(--grau-900); }
.menue a:hover, .menue .ist-aktiv > a { color: var(--rot); }
.menue .ist-aktiv-eltern > a { color: var(--rot); }
.menue > li > ul a { padding-left: 1.2rem; color: var(--grau-700); }

/* Der Vorverkauf steht nur waehrend des Verkaufszeitraums im Menue. Weil er
   dann etwas ist, das man nicht verpassen soll, hebt er sich ab. Die
   Auszeichnung sitzt am li, nicht am a: So bleibt das Klappmenue-Verhalten
   der Nachbarn unberuehrt. */
.menue__vorverkauf > a {
  color: #7a1220;
  font-weight: 600;
}

/* mobil: eingeklappt */
.menue { display: none; width: 100%; border-top: 1px solid var(--grau-100); }
.kopf.ist-offen .menue { display: block; }
/* Das aufgeklappte Menü gehört UNTER die Logozeile — dafür muss die Reihe
   umbrechen dürfen. Ohne diese Zeile liegen Logo, Burger und Menü in einer
   einzigen Reihe: Das Menü stand als schmale Spalte rechts neben dem Burger,
   bei 360 px waren „Die Eintrittserklärung" und „Datenschutzerklärung" am
   rechten Rand abgeschnitten, und Logo und Burger schwebten wegen
   "align-items: center" in der senkrechten Mitte der über 1000 px hohen
   Kopfzeile — also mitten im Menü. Auf den Umbruch ist auch das "width: 100%"
   an .menue ausgelegt.
   Warum nur bei "ist-offen" und nicht immer an .kopf__innen: Bei geschlossenem
   Menü ist die Zeile aus Wappen, Vereinsname und Burger am Handy knapp breiter
   als der Bildschirm. Sie darf sich dort zusammenschieben — dürfte sie
   umbrechen, rutschte der Burger in eine zweite Zeile und die Kopfzeile
   wüchse von 76 auf 129 px, auf jeder Seite und die ganze Zeit. */
.kopf.ist-offen .kopf__innen { flex-wrap: wrap; }

/* Bei geöffnetem Menü bleibt am Handy nur das Wappen stehen; der Schriftzug
   „Sängervereinigung Mainflingen 1887" samt Zeile darunter tritt zurück.
   Geschlossen ist er sofort wieder da, und am Rechner (ab 1000 px, siehe
   unten) ändert sich nichts.

   Weggeschoben statt "display: none": Das Wappen trägt bewusst ein leeres
   alt-Attribut, weil der Schriftzug daneben schon sagt, wohin der Verweis
   führt. Wäre der Schriftzug wirklich entfernt, bliebe ein Verweis ohne
   jede Beschriftung übrig — eine Sprachausgabe läse dann nur „Link". So
   verschwindet er für das Auge und bleibt für die Sprachausgabe erhalten.
   Dieselbe Technik nutzt oben die Sprungmarke „Zum Inhalt springen". */
.kopf.ist-offen .kopf__name { position: absolute; left: -9999px; }

/* Das offene Menü ist am Handy höher als der Bildschirm: gemessen 798 px
   Liste in einem 640 px hohen Fenster. Weggescrollt werden kann das NICHT,
   denn .kopf klebt (position: sticky, top: 0) — ein klebender Kasten, der
   höher ist als das Fenster, bleibt mit seiner Oberkante bei 0 stehen, und
   was unten hinausragt, bekommt niemand zu sehen. Gemessen: auch nach 2000 px
   Scrollen stand der letzte Menüpunkt bei 825 px, also 185 px unterhalb des
   Bildschirmrands. Fünf der siebzehn Punkte — „Kontakt" samt Untermenü und
   „Links" — waren am Handy überhaupt nicht erreichbar.
   Deshalb bekommt die Liste selbst eine Höhengrenze und scrollt in sich;
   Wappen und Burger bleiben dabei stehen, das Menü lässt sich also auch von
   unten wieder schließen. Abgezogen wird die Logozeile darüber (5.5rem = 88 px,
   gemessen sind es 84 px — der Rest ist Luft).
   Die zweite max-height-Zeile ist dieselbe Angabe in dvh: Am Handy rechnet
   100vh die Fläche hinter der ein- und ausfahrenden Adressleiste mit, 100dvh
   nicht. Browser, die dvh nicht kennen, werfen die Zeile weg und behalten die
   erste — deshalb stehen beide da und in dieser Reihenfolge. */
.kopf.ist-offen .menue {
  max-height: calc(100vh - 5.5rem);
  max-height: calc(100dvh - 5.5rem);
  overflow-y: auto;
}

/* ---------- Seitenrumpf ---------- */
.page { max-width: var(--seitenbreite); margin: 0 auto; padding: 2rem var(--abstand) 4rem; }
/* Lange deutsche Wörter wie „Datenschutzerklärung" oder „Fastnachtsabteilung"
   sind auf schmalen Handys breiter als eine Zeile. Sie ragten über den rechten
   Rand hinaus, und die Seite liess sich seitlich schieben. Umbrochen wird nur
   dann, wenn ein Wort sonst nicht in die Zeile passt — sobald genug Platz da
   ist, ändert sich am Schriftbild nichts. Der Kopf ist bewusst nicht dabei,
   damit der Vereinsname dort nie mitten im Wort getrennt wird. */
.page, .buehne { overflow-wrap: break-word; }
.prose { max-width: var(--lesebreite); }
.prose p, .prose ul, .prose ol, .prose table { margin: 0 0 1.1rem; }
.prose img { border-radius: var(--rundung); margin: 1.2rem 0; }
/* Bilder im Beitrag stehen NEBEN dem Text, abwechselnd links und rechts.
   Welche Seite gilt, steht als Klasse am Bild: CSS kann Bilder, die in
   verschiedenen Absätzen stehen, nicht abwechselnd durchzählen. Gesetzt
   werden die Klassen von `python3 tools/bildlage.py --anwenden`, check.py
   meldet ein Bild ohne sie.
   Unter 700 px bleibt alles wie zuvor — daneben wäre die Textspalte auf
   einem Handy nur noch eine Handvoll Zeichen breit. */
@media (min-width: 700px) {
  /* Nur dort breiter, wo tatsächlich Bilder fließen: reiner Text behält
     seine Lesebreite von 68 Zeichen. Browser ohne :has zeigen die schmale
     Spalte — die Bilder fließen trotzdem. */
  .prose:has(img.links, img.rechts) { max-width: 880px; }
  /* "clear: both" hält die Bilder auseinander: das nächste Bild beginnt
     erst unter dem vorigen. Ohne das stehen zwei Bilder gleichzeitig im
     Text, sobald der Absatz dazwischen kürzer ist als das Bild hoch — die
     Textspalte schrumpft dann auf wenige Wörter, und die Abwechslung
     links/rechts ist nicht mehr zu erkennen. */
  .prose img.links, .prose img.rechts {
    max-width: 38%; margin-top: .3rem; clear: both;
  }
  .prose img.links { float: left; margin-right: 1.4rem; margin-bottom: 1rem; }
  .prose img.rechts { float: right; margin-left: 1.4rem; margin-bottom: 1rem; }
  /* Ein Zwischentitel darf nicht neben einem Bild hängen, und der Rückweg
     unter dem Beitrag nicht neben dem letzten Bild stehen. */
  .prose h2 { clear: both; }
  .prose::after { content: ""; display: block; clear: both; }
}
.prose table { border-collapse: collapse; width: 100%; }
.prose th, .prose td { border: 1px solid var(--grau-300); padding: .5rem .7rem; text-align: left; }
/* Eine Tabelle mit mehreren Spalten passt auf einem Handy nicht nebeneinander.
   Steht sie in diesem Rahmen, wird NUR die Tabelle seitlich gerollt — die Seite
   selbst bleibt stehen. Das `tabindex="0"` im HTML macht den Rahmen auch mit der
   Tastatur erreichbar, sodass man die rechten Spalten mit den Pfeiltasten
   erreicht, ohne wischen zu können. */
.tabelle-rollt { overflow-x: auto; }
.tabelle-rollt:focus-visible { outline: 3px solid var(--violett); outline-offset: 3px; }
.prose th { background: var(--grau-50); }
.zurueck { display: inline-block; margin-top: 2rem; }

/* ---------- Startseiten-Bühne ---------- */
.buehne {
  position: relative; color: var(--weiss); text-align: center;
  padding: clamp(3rem, 12vw, 7rem) var(--abstand);
  background: var(--violett) var(--buehne-bild) center / cover no-repeat;
}
.buehne::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(29,29,33,.35), rgba(81,50,112,.75));
}
.buehne > * { position: relative; }
.buehne h1 { color: var(--weiss); text-shadow: 0 2px 12px rgba(0,0,0,.4); }
.buehne p { font-size: 1.2rem; margin: .4rem 0 1.6rem; }

/* Das Vorverkaufsbanner sitzt direkt unter der Buehne und ist buendig mit dem
   Inhalt darunter — NICHT randlos wie die Buehne. Der Grund: Ein randloses
   Bild muesste bei jeder Fensterbreite anders beschnitten werden; so bleibt
   das Seitenverhaeltnis ueberall gleich, und wer das Bild anlegt, sieht beim
   Entwerfen genau das, was spaeter zu sehen ist. Hoechste Anzeigebreite ist
   damit 1132 px (1180 minus zweimal Abstand), das Bild ist mit 2264 px genau
   doppelt so breit. Ohne "display:block" liesse die Zeilenhoehe unter dem
   Bild einen schmalen Streifen stehen. */
.vorverkaufsbanner {
  max-width: var(--seitenbreite);
  margin: 0 auto;
  padding: 1.5rem var(--abstand) 0;
}
.vorverkaufsbanner img {
  display: block;
  width: 100%;
  border-radius: var(--rundung);
}

.knopf {
  display: inline-block; margin: .3rem; padding: .75rem 1.4rem;
  border-radius: 999px; background: var(--rot); color: var(--weiss);
  font-weight: 600; text-decoration: none;
}
.knopf:hover { background: var(--rot-dunkel); color: var(--weiss); }
/* Der zweite Knopf der Bühne ist die Umkehrung des ersten: weiß mit roter
   Schrift statt rot mit weißer. #e30d31 auf Weiß hat 4,81:1 — knapp über
   den geforderten 4,5:1, deshalb den Rotton hier nicht aufhellen. Beim
   Überfahren greift die Regel darüber und füllt den Knopf dunkelrot. */
.knopf--hell { background: var(--weiss); color: var(--rot); }
/* Zweiter Absendeknopf neben einem .knopf (z. B. "Zurück zum Formular" im
   Kartenvorverkauf): sieht bewusst wie ein einfacher Verweis aus, nicht wie
   ein Knopf, damit der eigentliche .knopf daneben der auffälligere bleibt. */
.knopf-verweis {
  background: none; border: none; padding: 0; margin: .3rem;
  font: inherit; color: var(--rot); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 2px; cursor: pointer;
}
.knopf-verweis:hover { color: var(--rot-dunkel); }

/* ---------- Karten (Neuigkeiten, Galerien, Chöre) ---------- */
.karten { display: grid; gap: var(--abstand); grid-template-columns: 1fr; padding: 0; list-style: none; }
.karte {
  background: var(--weiss); border: 1px solid var(--grau-100);
  border-radius: var(--rundung); overflow: hidden; box-shadow: var(--schatten);
  display: flex; flex-direction: column;
}
.karte img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; margin: 0; }
.karte__text { padding: 1rem 1.1rem 1.3rem; }
.karte__datum { font-size: .85rem; color: var(--grau-500); }
.karte h2, .karte h3 { margin: .2rem 0 .5rem; font-size: 1.15rem; }
.karte h2 a, .karte h3 a { text-decoration: none; color: var(--violett); }
.karte h2 a:hover, .karte h3 a:hover { color: var(--rot); }

.zweispaltig { display: grid; gap: 2.5rem; grid-template-columns: 1fr; margin-top: 3rem; }
.block--grau { background: var(--grau-50); padding: 3rem 0; margin-top: 3rem; }
.block--grau > .page { padding-top: 0; padding-bottom: 0; }

/* ---------- Chronik: Knopfspalte links, Inhalt rechts ---------- */
/* Die Spalte kommt aus partials/chronik.html und wird von site.js eingesetzt.
   Das Raster hängt deshalb an `:has(.chronikspalte)`: Solange die Spalte NICHT
   da ist — kein JavaScript, Baustein nicht geladen — bleibt es beim einfachen
   Blocksatz und der Text nimmt die ganze Breite. Ohne diese Bedingung stünde
   dort eine 16 rem breite leere Spalte neben dem Text. */
.chronikspalte__titel { font-weight: 700; color: var(--violett); margin: 0 0 .5rem; }
.chronikspalte__titel a { text-decoration: none; color: inherit; }
.chronikspalte__titel a:hover { color: var(--rot); }
.chronikspalte ul { list-style: none; padding: 0; margin: 0 0 1.5rem; }
.chronikspalte li { margin: 0; }
.chronikspalte li a {
  display: block; padding: .3rem .6rem; border-radius: var(--rundung);
  text-decoration: none; color: var(--grau-700);
}
.chronikspalte li a:hover { background: var(--grau-50); color: var(--rot); }
/* Der Eintrag der Seite, auf der man steht. Gesetzt wird `aria-current` von
   site.js; eine eigene Klasse gibt es dafür bewusst nicht, sonst müssten
   Hervorhebung und Vorleseprogramm getrennt gepflegt werden. */
.chronikspalte li a[aria-current="page"] {
  background: var(--violett); color: var(--weiss); font-weight: 700;
}

@media (min-width: 900px) {
  .chronik:has(.chronikspalte) {
    display: grid; grid-template-columns: 15rem minmax(0, 1fr); gap: 2.5rem;
    align-items: start;
  }
  /* Die Spalte bleibt beim Scrollen stehen — bei 48 Einträgen und einem
     langen Jahrestext sonst der halbe Sinn der Sache. `top` hält Abstand zur
     klebenden Kopfzeile (72 px, derselbe Wert wie scroll-padding-top).
     Die Höhengrenze mit eigenem Rollbalken ist NICHT Kosmetik: ein klebender
     Kasten, der höher ist als das Fenster, lässt sich nicht scrollen — genau
     das ist im Mobilmenü schon einmal passiert, und 48 Einträge sind auf
     einem flachen Bildschirm höher als das Fenster. */
  .chronikspalte {
    position: sticky; top: 6rem;
    max-height: calc(100vh - 7.5rem);
    max-height: calc(100dvh - 7.5rem);
    overflow-y: auto;
  }
}
/* Unter 900 px steht die Spalte über dem Text und darf NICHT kleben — sie wäre
   dort höher als das Fenster und ließe sich dann nicht mehr scrollen.
   Sie braucht aber eine Grenze: nachgemessen ist die Liste aus 48 Einträgen
   1960 px hoch. Ohne Grenze müsste man am Handy durch die ganze Liste wischen,
   ehe der erste Satz Chronik zu sehen ist. Mit Grenze ist der Text nach einem
   Wisch da, und die Liste rollt in sich — derselbe Handgriff wie beim
   aufgeklappten Mobilmenü. */
@media (max-width: 899px) {
  .chronikspalte {
    max-height: 13rem; overflow-y: auto;
    border: 1px solid var(--grau-100); border-radius: var(--rundung);
    padding: .8rem; margin-bottom: 1.5rem;
  }
  .chronikspalte ul:last-of-type { margin-bottom: 0; }
}

/* ---------- Termine ---------- */
.terminliste { list-style: none; padding: 0; margin: 0; }
.termin { display: flex; gap: 1rem; padding: .9rem 0; border-bottom: 1px solid var(--grau-100); }
/* Ohne das bleibt ein Flex-Kind mindestens so breit wie sein längstes
   ungebrochenes Wort (z. B. ein langer Link aus der Kalenderbeschreibung)
   und sprengt am Handy den Rand, egal was overflow-wrap sagt. */
.termin > span { min-width: 0; }
.termin__datum {
  flex: 0 0 6rem; text-align: center; border-radius: var(--rundung);
  background: var(--violett); color: var(--weiss); padding: .4rem 0; line-height: 1.15;
}
/* Proben tragen eine grüne Plakette statt der violetten. Gerechnet, nicht
   geraten: #2f6b46 hat 6,34:1 Kontrast zu weißer Schrift (nötig sind 4,5:1
   für die kleine Monatszeile). Die Farbe muss hier nichts tragen, was sonst
   fehlte: Proben stehen in einem eigenen Abschnitt unter der Überschrift
   „Proben". Wer Violett und Grün nicht unterscheidet — es ist das Paar, das
   bei der häufigsten Farbenblindheit zusammenfällt —, verliert deshalb keine
   Auskunft. Ein Wort „Probe" an jedem der rund zwanzig Einträge wäre unter
   dieser Überschrift nur Wiederholung. */
.termin--probe .termin__datum { background: var(--gruen); }
.termin__tag { display: block; font-size: 1.5rem; font-weight: 700; }
/* Ein mehrtägiger Termin trägt die Spanne in der oberen Reihe („19.–22."
   statt „19"). Sieben Zeichen passen bei 1.5rem nicht in die Plakette —
   deshalb hier kleiner. */
.termin--mehrtaegig .termin__tag { font-size: 1.2rem; }
/* Der Monat steht ausgeschrieben, nicht abgekürzt. Dafür ist die Plakette
   6 rem breit: „SEPTEMBER" braucht bei dieser Größe 71 px (gemessen im
   Browser, nicht geschätzt). */
.termin__monat { display: block; font-size: .75rem; text-transform: uppercase; }
/* Das Jahr steht seit dem 28.08.2026 in der Plakette, weil es aus der Zeile
   daneben verschwunden ist. Etwas blasser als der Monat: Es unterscheidet
   die Termine seltener und soll die Kachel nicht dreiteilig wirken lassen. */
.termin__jahr { display: block; font-size: .7rem; opacity: .8; }
.termin__ort { color: var(--grau-500); font-size: .92rem; }
/* Überschrift eines Terminabschnitts samt Kalendersymbol daneben. Das Symbol
   steht NEBEN der Überschrift, nicht darin: Sonst hinge sein Name mit in der
   Überschrift, und wer sich per Sprachausgabe von Überschrift zu Überschrift
   hangelt, hörte jedes Mal den ganzen Satz mit. baseline statt center, damit
   das Symbol auf der Schriftlinie sitzt und nicht daneben schwebt. */
.abschnittskopf { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.ics-verweis {
  color: var(--violett); line-height: 0; padding: .35rem;
  border-radius: var(--rundung);
}
/* Alles, was zu den Proben gehört, trägt dieselbe Farbe wie ihre Plaketten:
   die beiden Überschriften und das Kalendersymbol daneben. Die Klasse steht
   ausdrücklich im HTML und wird nicht aus dem Inhalt erschlossen (etwa über
   :has(.termin--probe)) — sonst schlüge die Farbe genau dann um, wenn gerade
   keine Probe ansteht oder der Kalender ausgefallen ist. */
.ueberschrift--proben, .ueberschrift--proben + .ics-verweis { color: var(--gruen); }
.ics-verweis:hover { background: var(--grau-50); }
.ics-verweis:focus-visible { outline: 3px solid var(--violett); outline-offset: 2px; }
/* Beschreibungstext aus dem Kalender — wie der Ort eine Nebenangabe.
   overflow-wrap: anywhere (statt nur break-word) bricht auch einen langen
   Link mitten im Wort um, sonst zählt er bei der Min-Content-Breite als
   ein einziges, unteilbares Wort. */
.termin__text { display: block; color: var(--grau-500); font-size: .9rem; overflow-wrap: anywhere; }
/* Beiläufige Angaben rund um die Terminlisten: wann zuletzt vom Kalender
   geholt wurde, und wie weit das Probenfenster reicht. */
.termin-stand { color: var(--grau-500); font-size: .85rem; margin-top: .8rem; }
.termin.ist-vorbei { display: none; }

/* ---------- Galerie ---------- */
.galerie { display: grid; gap: .6rem; grid-template-columns: repeat(2, 1fr); padding: 0; list-style: none; }
.galerie a { display: block; }
.galerie img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 6px; margin: 0; }

/* ---------- Formular ---------- */
.formular { max-width: 34rem; }
.formular label { display: block; margin: 1rem 0 .3rem; font-weight: 600; }
.formular input, .formular textarea {
  width: 100%; padding: .6rem .7rem; font: inherit;
  border: 1px solid var(--grau-300); border-radius: 6px; background: var(--weiss);
}
.formular textarea { min-height: 10rem; resize: vertical; }
.formular .einwilligung { display: flex; gap: .6rem; align-items: flex-start; margin-top: 1.2rem; font-weight: 400; }
.formular .einwilligung input { width: auto; margin-top: .35rem; }
.honigtopf { position: absolute; left: -9999px; }

.hinweis { padding: .9rem 1.1rem; border-radius: var(--rundung); background: #e8f5ec; border: 1px solid #b7ddc3; }
.hinweis--fehler { background: #fdeaec; border-color: #f3b9c1; }

/* ---------- Fuß ---------- */
.fuss { background: var(--grau-900); color: var(--grau-300); margin-top: 4rem; }
.fuss__innen {
  max-width: var(--seitenbreite); margin: 0 auto; padding: 2.5rem var(--abstand);
  display: grid; gap: 2rem; grid-template-columns: 1fr;
}
.fuss a { color: var(--weiss); }
.fuss h2 { color: var(--weiss); font-size: 1.05rem; margin: 0 0 .6rem; }
.fuss ul { list-style: none; padding: 0; margin: 0; }

/* ---------- Umbrüche ---------- */
/* Auf sehr schmalen Handys war der Seitenrand von 1,5 rem zu grosszügig: auf
   einem 320 Pixel breiten Gerät gingen dafür rund 15 Prozent der Bildschirm-
   breite verloren, und lange Wörter mussten deshalb umbrechen, obwohl sie auf
   den Bildschirm gepasst hätten. Ab 481 Pixel gilt wieder der normale Rand,
   dort ändert sich also nichts. */
@media (max-width: 480px) {
  :root { --abstand: .75rem; }
}

@media (min-width: 700px) {
  .karten { grid-template-columns: repeat(2, 1fr); }
  .galerie { grid-template-columns: repeat(3, 1fr); }
  .zweispaltig { grid-template-columns: 1fr 1fr; }
  .fuss__innen { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1000px) {
  .karten { grid-template-columns: repeat(3, 1fr); }
  .galerie { grid-template-columns: repeat(4, 1fr); }
  .burger { display: none; }
  /* Diese drei Zeilen nehmen am Rechner alles zurück, was "ist-offen" für
     das Handy setzt. Nötig sind sie, weil die Klasse am Kopf hängen bleibt:
     Der Burger ist hier zwar ausgeblendet, aber wer das Menü am schmalen
     Fenster öffnet und das Fenster dann breit zieht, nimmt sie mit herüber.
     Ohne die Zeilen stünde dort ein Wappen ohne Vereinsnamen, die Kopfreihe
     dürfte umbrechen, und das Menü erschiene als lange Liste untereinander
     statt als Leiste (gemessen 321 px statt 72 px Kopfhöhe).
     Die letzte Zeile braucht ".kopf.ist-offen" davor, obwohl ".menue" gleich
     darunter schon "display: flex" setzt: Ein Mediaabschnitt erhöht das
     Gewicht einer Regel nicht, und ".kopf.ist-offen .menue { display: block }"
     weiter oben wiegt schwerer als ".menue" allein. Sie nimmt ausserdem die
     Höhengrenze des Handymenüs zurück — bliebe "overflow-y: auto" stehen,
     schnitte die Leiste am Rechner ihre eigenen Klappmenüs ab, denn die
     hängen als absolut gesetzte Kästen unter ihr. */
  .kopf.ist-offen .kopf__name { position: static; }
  .kopf.ist-offen .kopf__innen { flex-wrap: nowrap; }
  .kopf.ist-offen .menue { display: flex; overflow: visible; max-height: none; }
  .menue { display: flex; width: auto; margin-left: auto; border: 0; gap: .3rem; }
  .menue > li { position: relative; }
  .menue > li > a { padding: .7rem .8rem; font-weight: 600; }
  .menue > li > ul {
    display: none; position: absolute; left: 0; top: 100%; min-width: 15rem;
    background: var(--weiss); border: 1px solid var(--grau-100);
    border-radius: var(--rundung); box-shadow: var(--schatten); padding: .4rem 0;
  }
  .menue > li:hover > ul, .menue > li:focus-within > ul { display: block; }
  .menue > li > ul a { padding: .5rem 1rem; }
}

/* ---------- Lightbox ---------- */
.lightbox {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(20, 18, 24, .94);
  display: flex; align-items: center; justify-content: center;
}
.lightbox[hidden] { display: none; }
.lightbox__bild { max-width: 92vw; max-height: 84vh; border-radius: 6px; }
.lightbox button {
  position: absolute; background: none; border: 0; color: var(--weiss);
  font-size: 2.6rem; line-height: 1; cursor: pointer; padding: .5rem 1rem;
}
.lightbox__zu { top: .5rem; right: .5rem; font-size: 2.2rem; }
.lightbox__vor { left: 0; top: 50%; transform: translateY(-50%); }
.lightbox__nach { right: 0; top: 50%; transform: translateY(-50%); }
.lightbox__zaehler {
  position: absolute; bottom: 1rem; left: 0; right: 0;
  text-align: center; color: var(--grau-300); margin: 0;
}

@media print {
  .kopf, .fuss, .knopf { display: none; }
  .page { max-width: none; }
}

/* Beschriftung nur für Vorleseprogramme: sichtbar ist die Spaltenüberschrift
   der Tabelle, aber ein Eingabefeld braucht eine eigene, eindeutige
   Beschriftung — sonst hört man dreimal "Anzahl". */
.nur-vorleser {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
