/* ============================================================
   VS Ried — Seitengerüst
   Kopfbereich, Navigation, Fußbereich, Textspalten.
   Komponenten stehen in components.css, Tokens in tokens.css.
   ============================================================ */

/* ------------------------------------------------------------
   Kopfbereich
   ------------------------------------------------------------ */

/* Unsichtbare Marken am Seitenanfang. Nehmen keinen Platz ein (absolut) und
   dienen den Observern in menu.js als Schaltschwellen:

     --tief   (120 px)  darüber wird der Kopfbereich flach
     --seicht  (56 px)  darunter wird er wieder hoch

   Der Abstand zwischen beiden ist Absicht (siehe menu.js): Er muss größer
   sein als die Höhenänderung des Kopfbereichs, sonst kann der Umschalter
   sich selbst auslösen. */
.vs-kopfmarke {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  pointer-events: none;
}
.vs-kopfmarke--tief   { height: 120px; }
.vs-kopfmarke--seicht { height: 56px; }

.vs-header {
  background: var(--surface-card);
  border-bottom: var(--border-width) solid var(--border-soft);
  position: sticky;
  top: 0;
  z-index: 20;

  /* Ruhezustand. Oben mehr Luft als unten: Das Logo hat unten die Zeile
     "im Traunkreis" und damit optisch schon Gewicht — gleiche Abstände
     lassen es nach oben gedrückt wirken. */
  --kopf-oben:  var(--space-5);
  --kopf-unten: var(--space-3);
  --kopf-logo:  200px;
}

/* Gescrollter Zustand. Das Logo ist mit 220 px Breite rund 83 px hoch und
   bestimmt damit die Höhe des Kopfbereichs; bei 168 px sind es 63 px. Mit
   den kleineren Innenabständen wird der Kopf von 119 px auf 79 px flacher —
   auf einem Handy im Hochformat sind das gut 6 % der Bildfläche, die beim
   Lesen wieder frei werden.

   Nicht kleiner: Die Navigation braucht 48 px Klickhöhe (--hit), darunter
   würde der Kopfbereich das Klickziel verkleinern statt nur sich selbst. */
.vs-header--kompakt {
  --kopf-oben:  var(--space-2);
  --kopf-unten: var(--space-2);
  --kopf-logo:  150px;
}

.vs-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding-block: var(--kopf-oben) var(--kopf-unten);
  transition: padding-block var(--dur-mid) var(--ease-out);
}

/* Ab hier passt alles in eine Zeile — Umbruch wäre dann ein Fehler,
   kein Notbehelf. */
@media (min-width: 76rem) {
  .vs-header__inner { flex-wrap: nowrap; }
  .vs-nav__liste { flex-wrap: nowrap; }
}

.vs-header__logo { display: inline-flex; line-height: 0; }
.vs-header__logo img {
  width: var(--kopf-logo);
  height: auto;
  transition: width var(--dur-mid) var(--ease-out);
}

@media (min-width: 48rem) {
  .vs-header            { --kopf-logo: 220px; }
  .vs-header--kompakt   { --kopf-logo: 168px; }
}

/* Wer Bewegung reduziert haben will, bekommt den Zustandswechsel ohne
   Übergang — nicht gar nicht. Der flachere Kopf ist der Zweck, die
   Animation nur die Verpackung. */
@media (prefers-reduced-motion: reduce) {
  .vs-header__inner,
  .vs-header__logo img { transition: none; }
}

/* Sehr schmale Geräte: Logo und Menüknopf müssen in eine Reihe passen.
 *
 * Gemessen: Bei 360 px stehen 288 px Innenbreite zur Verfügung, gebraucht
 * wurden 200 (Logo) + 16 (Abstand) + 104 (Knopf mit dem Wort "Menü") =
 * 320 px. Der Knopf rutschte unter das Logo, und der klebende Kopfbereich
 * war 175 px hoch — auf einem 320-px-Gerät über ein Fünftel der Bildhöhe.
 *
 * Zwei Maßnahmen: kleineres Logo und ein Knopf ohne Beschriftung. Das Wort
 * "Menü" verschwindet nur optisch, für Screenreader bleibt es über
 * .vs-sr-only erhalten — das Klickziel bleibt 48 × 48 px.
 */
@media (max-width: 23rem) {
  .vs-header          { --kopf-logo: 150px; }
  .vs-header--kompakt { --kopf-logo: 132px; }

  .vs-nav-toggle {
    padding: var(--space-2);
    min-width: var(--hit);
    justify-content: center;
  }
  .vs-nav-toggle__text { position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0; }
}



/* ------------------------------------------------------------
   Navigation
   ------------------------------------------------------------ */

.vs-nav__liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.vs-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--hit);
  /* Waagrecht knapp gehalten: "Sozialwirksame Schule" und
     "Wir suchen dich" sind lang, und daneben steht noch das Logo.
     Die Höhe bleibt bei 48 px — das Klickziel wird nicht kleiner. */
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-pill);
  font-weight: var(--fw-bold);
  font-size: 0.9375rem;
  color: var(--text-body);
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.vs-nav__link:hover {
  background: var(--surface-sunken);
  color: var(--text-strong);
}

/* Die aktive Seite wird nicht allein über die Farbe markiert — dazu
   kommt die getönte Fläche und im HTML aria-current. */
.vs-nav__link--aktiv {
  background: var(--color-brand-soft);
  color: var(--c-blue-900);
}

/* Menüpunkt mit Untermenü */
.vs-nav__punkt { position: relative; display: flex; align-items: center; }

/* Aufklappknopf neben dem Link. Eigenes Klickziel, mindestens 44 px,
   damit er am Handy nicht den Link mit trifft. */
.vs-nav__auf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  min-height: var(--hit);
  margin-left: calc(var(--space-2) * -1);
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--radius-pill);
  color: var(--text-body);
  cursor: pointer;
}
.vs-nav__auf:hover { background: var(--surface-sunken); color: var(--text-strong); }
.vs-nav__auf[hidden] { display: none; }

.vs-nav__pfeil {
  width: 0; height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid currentColor;
  transition: transform var(--dur-fast) var(--ease-out);
}
.vs-nav__punkt--offen .vs-nav__pfeil { transform: rotate(180deg); }

/* Untermenü */
.vs-nav__unter {
  list-style: none;
  margin: 0;
  padding: var(--space-2);
  display: grid;
  gap: 2px;
}

.vs-nav__unterlink {
  display: block;
  min-height: var(--hit);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  color: var(--text-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
  text-decoration: none;
  white-space: nowrap;
}
.vs-nav__unterlink:hover { background: var(--surface-sunken); color: var(--text-strong); }
.vs-nav__unterlink--aktiv {
  background: var(--color-brand-soft);
  color: var(--c-blue-900);
}

/* Umschaltknopf fürs Hauptmenü: nur mit JavaScript und nur schmal */
.vs-nav-toggle {
  display: none;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--hit);
  padding: var(--space-2) var(--space-4);
  font-family: var(--font-text);
  font-weight: var(--fw-extra);
  font-size: var(--fs-body);
  color: var(--text-strong);
  background: var(--surface-sunken);
  border: var(--border-width) solid var(--border-soft);
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.vs-nav-toggle__balken,
.vs-nav-toggle__balken::before,
.vs-nav-toggle__balken::after {
  display: block;
  width: 18px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
}
.vs-nav-toggle__balken { position: relative; }
.vs-nav-toggle__balken::before { content: ""; position: absolute; top: -6px; }
.vs-nav-toggle__balken::after  { content: ""; position: absolute; top: 6px; }

/* --- Breite Bildschirme: Untermenü schwebt unter dem Menüpunkt --- */
@media (min-width: 76rem) {
  .hat-js .vs-nav__unter {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 220px;
    z-index: 30;
    background: var(--surface-card);
    border: var(--border-width) solid var(--border-soft);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    /* Nicht display:none — sonst überspringt der Screenreader das Menü
       auch dann, wenn es geöffnet ist. visibility lässt sich animieren
       und nimmt das Element trotzdem aus der Tabreihenfolge. */
    visibility: hidden;
    opacity: 0;
    transition: opacity var(--dur-fast) var(--ease-out);
  }
  .hat-js .vs-nav__punkt--offen > .vs-nav__unter {
    visibility: visible;
    opacity: 1;
  }
}

/* --- Schmale Bildschirme: alles untereinander --- */
@media (max-width: 75.99rem) {
  .vs-nav-toggle[hidden] { display: none; }
  .hat-js .vs-nav-toggle { display: inline-flex; }

  .hat-js .vs-nav {
    display: none;
    width: 100%;
    order: 3;
  }
  .hat-js .vs-nav--offen { display: block; }

  .vs-nav__liste { flex-direction: column; gap: 0; align-items: stretch; }
  .vs-nav__punkt { flex-wrap: wrap; }
  .vs-nav__link { flex: 1; border-radius: var(--radius-md); }

  .hat-js .vs-nav__unter { display: none; width: 100%; padding-left: var(--space-5); }
  .hat-js .vs-nav__punkt--offen > .vs-nav__unter { display: grid; }
  .vs-nav__unterlink { white-space: normal; }
}


/* ------------------------------------------------------------
   Inhaltsbereich
   ------------------------------------------------------------ */

main { display: block; padding-block: var(--space-7) var(--space-8); }

/* Lesbare Zeilenlänge für Fließtext. 65 Zeichen ist die Spanne, in der
   das Auge die nächste Zeile noch sicher findet. */
.vs-prosa { max-width: 65ch; }
.vs-prosa > * + * { margin-top: var(--space-4); }
.vs-prosa h2 { margin-top: var(--space-7); }
.vs-prosa h3 { margin-top: var(--space-6); }
.vs-prosa ul, .vs-prosa ol { padding-left: var(--space-5); }
.vs-prosa li + li { margin-top: var(--space-2); }

.vs-lead { font-size: var(--fs-lead); color: var(--text-body); }

.vs-seitenkopf { margin-bottom: var(--space-6); }
.vs-seitenkopf h1 { margin-bottom: var(--space-3); }


/* ------------------------------------------------------------
   Fußbereich
   ------------------------------------------------------------ */

.vs-footer {
  background: var(--surface-sunken);
  border-top: var(--border-width) solid var(--border-soft);
  padding-block: var(--space-7) var(--space-5);
  margin-top: var(--space-9);
}

.vs-footer__inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: var(--space-6);
}

.vs-footer__block p { margin: 0 0 var(--space-2); }
.vs-footer__klein { font-size: var(--fs-sm); color: var(--text-muted); }

.vs-footer__liste { list-style: none; margin: 0; padding: 0; }
/* Kein Ausgleich für den negativen Außenabstand der Links nötig — nachgemessen
   an der Textzeile, nicht an der Elementbox: Alle vier Spalten beginnen 11 px
   unter ihrer Dachzeile. Die Box der Liste reicht zwar höher, weil die
   verkleinerten Zeilenboxen darüber hinausragen, aber sichtbar ist das nicht.
   Zwei Korrekturversuche daran sind gescheitert, weil ich die Box gemessen
   habe statt den Text. */

/* Klickziele im Fußbereich.
 *
 * Gemessen waren alle Links hier 22 px hoch: Telefonnummern, E-Mail-Adresse,
 * Impressum, Datenschutz, Barrierefreiheitserklärung. WCAG 2.2 verlangt
 * 24 × 24 px (Erfolgskriterium 2.5.8); die Ausnahme für Links mitten im Satz
 * greift nicht, das sind eigene Zeilen und Listeneinträge.
 *
 * Praktisch zählt vor allem die Telefonnummer: "Schule anrufen" ist die
 * wahrscheinlichste Handlung am Handy, und 22 px trifft man mit dem Daumen
 * nicht zuverlässig.
 *
 * Gilt auf allen Breiten, nicht nur am Handy — größere Ziele schaden der
 * Maus nicht, und ein Umbruchpunkt weniger ist ein Fehler weniger. Die
 * Polsterung ersetzt den bisherigen Abstand zwischen den Listeneinträgen,
 * sonst wird der Block optisch lockerer als vorher. */
.vs-footer__block a {
  display: inline-block;
  /* Polsterung für die Trefferfläche, negativer Außenabstand gleicher Größe
     dagegen. Beides zusammen ergibt 44 px Klickhöhe, ohne dass die Zeile im
     Layout höher wird.

     Nötig, weil die reine Polsterung den Fußbereich zerlegt hatte: Ein
     Link wuchs damit auf 49 px, und weil er in derselben Zeilenbox wie sein
     Beschriftungstext steht, wanderte "Konferenzzimmer" mit nach oben. Die
     Blöcke waren gemessen 74, 172 und 49 px hoch — jeder Abstand ein anderer.

     Die Zeilenhöhe des Fußbereichs ist 1.55, also rund 25 px; 11 px oben und
     unten ergeben 47 px. */
  padding-block: 11px;
  margin-block: -11px;
}
/* Die Rechtslinks stehen untereinander, und gestapelte Trefferflächen dürfen
   sich nicht überlappen — ein 47-px-Ziel erzwingt also 47 px Zeilenabstand.
   Gemessen ergab das 60 px zwischen den Einträgen gegen 28 px im Rest des
   Fußbereichs, und dieser Unterschied war genau die Unruhe.

   Deshalb hier kleinere Flächen: 33 px hoch bei 8 px Abstand, also 33 px
   Rasterabstand ohne Überlappung. 33 px erfüllt die 24 × 24 px, die WCAG 2.2
   in Erfolgskriterium 2.5.8 verlangt, bequem — die 44 px sind die strengere
   AAA-Empfehlung.
   
   Bei den Telefonnummern und der E-Mail-Adresse bleiben es 47 px: Die stehen
   einzeln, dort kostet die große Fläche nichts, und "Schule anrufen" ist die
   Handlung, bei der sie am Handy wirklich zählt. */
.vs-footer__liste a {
  display: block;
  padding-block: 4px;
  margin-block: -4px;
}
.vs-footer__liste li + li { margin-top: var(--space-2); }

.vs-footer__zeile {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-soft);
}


/* ------------------------------------------------------------
   Druck — Elternbriefe werden ausgedruckt
   ------------------------------------------------------------ */

@media print {
  .vs-header, .vs-footer, .vs-skip, .vs-nav-toggle,
  .vs-kopfmarke { display: none; }
  body { background: #fff; color: #000; }
  main { padding: 0; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; }
}


/* ------------------------------------------------------------
   Startseite
   ------------------------------------------------------------ */

/* Begrüßungsbereich der Startseite.
 *
 * Hellblaue Fläche wie im Prototyp. Der Rahmen unten entfällt dadurch — der
 * Farbwechsel trennt deutlich genug, zwei Signale für dieselbe Kante sind
 * eines zu viel.
 *
 * WICHTIG, und beim Einbauen aufgefallen: Auf --c-blue-100 verlieren die
 * 800er-Textwerte ihre Kontraste. --c-blue-800 kommt gegen #DBEFFB nur auf
 * 4.01:1, gemessen — das betrifft die Dachzeile "Schuljahr 2025 / 26" und
 * jeden Link in diesem Bereich. Genau dafür gibt es die 900er-Stufe, die
 * gegen die eigene -100-Tönung geprüft ist. Die Aliase werden deshalb hier
 * lokal umgesetzt und gelten für alles darin.
 */
.vs-hero {
  position: relative;
  overflow: hidden;
  background: var(--c-blue-100);
  padding-block: var(--space-8);
  margin-top: calc(var(--space-7) * -1);
  margin-bottom: var(--space-8);

  --color-info-text: var(--c-blue-900);   /* 4.01 → 4.54:1 */
  --text-link:       var(--c-blue-900);
  --text-muted:      var(--c-slate);      /* 4.03 → 7.45:1 */
}
.vs-hero h1 { font-size: var(--fs-display); margin-bottom: var(--space-4); }
/* Der Inhalt liegt über dem Konfetti, nicht darunter. */
.vs-hero__inhalt { position: relative; z-index: 1; }


/* --- Konfetti ---
   Rein dekorativ, aria-hidden, ohne Bewegung. Farbe, Größe, Deckung und Lage
   kommen als CSS-Variablen aus site/snippets/konfetti.php; hier steht nur,
   wie sie gelesen werden.

   Die Punkte dürfen nie hinter Text liegen. Standardmäßig sitzen sie
   deshalb in den Innenabständen oben und unten — die sind auf jeder Breite
   textfrei. Erst wenn das Fenster breiter ist als der Inhaltsrahmen,
   entstehen echte Seitenränder, und dann wandern sie dorthin. */

.vs-konfetti {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.vs-konfetti__punkt {
  position: absolute;
  width: var(--gr);
  height: var(--gr);
  border-radius: var(--radius-pill);
  background: var(--farbe);
  opacity: var(--deckung);
  left: var(--streif-pos);
}
/* Abstand vom oberen bzw. unteren Rand in Pixeln — er muss innerhalb der
   64 px Innenabstand liegen, und die sind ein fester Wert, kein Anteil der
   Kopfbereichshöhe. Mit Prozentwerten lagen die Punkte im Text. */
.vs-konfetti__punkt--oben  { top:    var(--streif-px); }
.vs-konfetti__punkt--unten { bottom: var(--streif-px); }

/* Höhe über das Seitenverhältnis, nicht gleich der Breite: Der Stern ist
   94 × 100 und würde sonst gestaucht. */
.vs-konfetti__stern {
  position: absolute;
  top: 2%;
  right: 3%;
  width: 44px;
  height: auto;
  opacity: 0.9;
  transform: rotate(-8deg);
}

/* Ab 1280 px ist der Seitenrand mindestens 40 px breit — erst dann lohnt er
   als Platz. Die Lage wird als Bruchteil dieses Randes berechnet, nicht als
   Prozent des Kopfbereichs: So liegt jeder Punkt bei 1280 px genauso im Rand
   wie bei 2560 px, und keiner rutscht in die Textspalte.

   Ein früherer Versuch mit festen Prozentwerten hatte bei 768 und 1250 px
   gemessen 6 von 10 Punkten hinter der Überschrift. */
@media (min-width: 80rem) {
  .vs-konfetti { --rand: calc((100vw - var(--container)) / 2); }

  .vs-konfetti__punkt {
    top: var(--rand-oben);
    bottom: auto;
    left: auto;
  }
  .vs-konfetti__punkt--links  { left:  calc(var(--rand-teil) * var(--rand)); }
  .vs-konfetti__punkt--rechts { right: calc(var(--rand-teil) * var(--rand)); }

  .vs-konfetti__stern {
    top: 12%;
    right: calc(0.12 * var(--rand));
    width: 76px;
  }
}


/* Kopf eines Abschnitts: Überschrift links, Verweisknopf rechts daneben.
 *
 * Diese Regeln waren zwischenzeitlich verschwunden — ich habe sie beim
 * Austauschen des Konfetti-Blocks mitgelöscht. Ohne sie ist der Kopf ein
 * gewöhnlicher Block, die h2 nimmt die ganze Breite und der Knopf rutscht
 * darunter. Betroffen waren "Aktuelles / Alle Beiträge" und
 * "Nächste Termine / Alle Termine" auf der Startseite.
 *
 * baseline, nicht center: Überschrift und Knopfbeschriftung sollen auf einer
 * Schriftlinie sitzen. Bei zwei Textelementen ist das richtig — anders als
 * beim Etikett neben dem Terminkopf, wo eine kleine Fläche neben großem Text
 * steht und die Mitte zählt. */
.vs-abschnittkopf {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.vs-abschnittkopf h2 { margin: 0; }


/* ------------------------------------------------------------
   Beitragskarten
   ------------------------------------------------------------ */

.vs-beitrag__bild {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  display: block;
}
/* Titel der Beitragskarte: --fs-h3 (26 px) auf --fs-h4 (20 px) herunter.
   Bei 26 px brauchten die längeren Titel in der 380 px breiten Karte drei
   Zeilen, bei 20 px eine oder zwei. h3 bezeichnet die Ebene in der
   Dokumentgliederung, nicht die Schriftgröße — die darf im Kartenkontext
   kleiner sein. Die Worttrennung steht global bei den Überschriften. */
.vs-beitrag__titel {
  margin: 0;
  font-size: var(--fs-h4);
  line-height: 1.25;
}

.vs-beitrag__kurz { margin: 0; }

/* Fußzeile: margin-top:auto drückt sie an den unteren Rand der Karte.
   Das Raster macht alle Karten einer Reihe gleich hoch, also liegen die
   Datumsangaben damit auf einer Linie — unabhängig davon, wie lang Titel
   und Anrisstext ausfallen. */
.vs-beitrag__fuss {
  margin: auto 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.vs-beitrag__klassen {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}
.vs-beitrag__datum {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}


/* ------------------------------------------------------------
   Klassenfilter
   ------------------------------------------------------------ */

.vs-filter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}
.vs-filter__titel {
  font-weight: var(--fw-bold);
  color: var(--text-strong);
  margin-right: var(--space-1);
}
.vs-filter__chip {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: var(--space-2) var(--space-4);
  border: var(--border-width) solid var(--border-soft);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  color: var(--text-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
  text-decoration: none;
}
.vs-filter__chip:hover { border-color: var(--border-strong); color: var(--text-strong); }
/* Aktiver Filter: Fläche UND Rahmen, nicht nur Farbe */
.vs-filter__chip--aktiv {
  background: var(--color-brand-soft);
  border-color: var(--color-brand-fill);
  color: var(--c-blue-900);
}
.vs-filter__ergebnis {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-bottom: var(--space-5);
}


/* ------------------------------------------------------------
   Seitennummern
   ------------------------------------------------------------ */

.vs-seiten {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-8);
}
.vs-seiten__liste {
  list-style: none;
  display: flex;
  /* Umbrechen, nicht überlaufen. Sieben Seitenzahlen à 48 px sind 360 px
     breit — mehr als die 288 px Innenbreite eines 320-px-Geräts. Ohne wrap
     ragte die Liste beidseitig hinaus (left = −27) und die ganze Seite
     bekam waagrechtes Scrollen. Am Handy werden daraus zwei Reihen. */
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
}
.vs-seiten__nr,
.vs-seiten__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--hit);
  min-height: var(--hit);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  font-weight: var(--fw-bold);
  color: var(--text-link);
  text-decoration: none;
}
.vs-seiten__nr:hover,
.vs-seiten__link:hover { background: var(--surface-sunken); }
.vs-seiten__nr--aktiv {
  background: var(--color-brand-fill);
  color: var(--text-on-fill);
}
.vs-seiten__link--aus { color: var(--text-muted); }


/* ------------------------------------------------------------
   Beitragsseite
   ------------------------------------------------------------ */

.vs-galerie {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: var(--space-4);
}
.vs-galerie__figur { margin: 0; }
.vs-galerie__figur img {
  width: 100%;
  border-radius: var(--radius-lg);
  display: block;
}

.vs-nachbarn {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--space-4);
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: var(--border-width) solid var(--border-soft);
}
.vs-nachbarn__link {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  border: var(--border-width) solid var(--border-soft);
  text-decoration: none;
  color: var(--text-strong);
  font-weight: var(--fw-bold);
}
.vs-nachbarn__link:hover { border-color: var(--border-strong); }
.vs-nachbarn__link--rechts { text-align: right; }
.vs-nachbarn__label {
  font-size: var(--fs-xs);
  font-weight: var(--fw-extra);
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--text-muted);
}


/* ------------------------------------------------------------
   Termine
   ------------------------------------------------------------ */

.vs-termine {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
  /* Begrenzte Zeilenlänge. Ohne das läuft eine Karte auf dem Desktop über
     1170 px, während darin eine Zeile mit fünf Wörtern steht.
     60rem waren noch zu viel: Bei einem Termin mit Titel, Zeitzeile und Ort
     blieb rechts etwa ein Drittel leer. 48rem passt zum längsten üblichen
     Inhalt ("Montag, 14. September · 08:00 Uhr · Turnsaal" plus Etiketten),
     ohne dass kurze Einträge verloren aussehen. */
  max-width: 48rem;
}

.vs-termin {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-4);
  background: var(--surface-card);
  border: var(--border-width) solid var(--border-soft);
  border-radius: var(--radius-lg);
}

/* Kalenderblatt über die Kartenhöhe — die durchgehende Kante links gibt der
   Liste beim Überfliegen Halt.
   Zwei Grenzen: min-height, damit es bei einem Termin ohne Zusatztext nicht
   flacher wird als breit; max-height, damit es bei einer langen Beschreibung
   nicht zum meterhohen Streifen wird. Oberhalb der Grenze hört das Mitwachsen
   auf, und der Block bleibt oben am Titel stehen — dort, wo er hingehört. */
.vs-termin__datum {
  flex: none;
  align-self: stretch;
  width: 4rem;
  min-height: 4rem;
  max-height: 8rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border-radius: var(--radius-md);
  border: 3px solid var(--c-blue-800);
  background: var(--surface-sunken);
}
.vs-termin__tag {
  font-family: var(--font-display);
  font-weight: var(--fw-extra);
  font-size: var(--fs-h3);
  line-height: 1;
  color: var(--text-strong);
}
.vs-termin__monat {
  font-size: var(--fs-xs);
  font-weight: var(--fw-extra);
  line-height: 1;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

/* flex:1 fehlte — die Inhaltsspalte war dadurch nur 356 px breit, egal wie
   breit die Karte war, und rechts blieben rund 500 px leer. Genau derselbe
   Fehler wie bei der Textspalte im Team: Ein Flex-Kind ohne flex-grow
   schrumpft auf seine Inhaltsbreite, statt den Platz zu nehmen.
   min-width:0 gehört dazu, sonst verhindert der längste unteilbare Text das
   Schrumpfen auf schmalen Bildschirmen. */
.vs-termin__inhalt { flex: 1; min-width: 0; }

/* Titel und Etiketten in einer Zeile.
   center, nicht baseline: Auf gemeinsamer Schriftlinie wirkt das kleine
   Etikett (12 px) neben dem großen Titel (20 px) nach oben gerutscht, weil
   das Auge die Mitte der Fläche vergleicht und nicht die Grundlinie.
   Der waagrechte Abstand ist knapp gehalten, damit das Etikett als Teil der
   Titelzeile gelesen wird und nicht als eigenes Element daneben. */
.vs-termin__kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-2);
}
/* line-height eng: Der Titel ist eine Zeile, und die Vorgabe von 1.5 aus
   dem Fließtext macht seine Zeilenbox 10 px höher als die Schrift. Beim
   Ausrichten auf die Mitte verschiebt das alles daneben mit. */
.vs-termin__titel {
  margin: 0;
  font-size: var(--fs-h4);
  line-height: 1.2;
}
.vs-termin__marken { display: inline-flex; flex-wrap: wrap; gap: var(--space-1); }

/* Abstände absichtlich ungleich: Titel und Zeitangabe gehören zusammen,
   der Zusatztext ist eine eigene Aussage. Gleich große Abstände lassen
   alles gleich wichtig aussehen. */
.vs-termin__meta {
  margin: var(--space-2) 0 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.vs-termin__trenner { margin-inline: 0.4em; }

.vs-termin__text {
  margin: var(--space-3) 0 0;
  color: var(--text-body);
}


/* ------------------------------------------------------------
   Team
   ------------------------------------------------------------ */

.vs-personen {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* Breitere Spalten, weil die Porträts groß sind — sonst rutscht der
     Name unter das Bild und die Zeile wird unruhig. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr));
  gap: var(--space-6);
}
.vs-person {
  display: flex;
  gap: var(--space-5);
  align-items: center;
}
/* Der Textblock neben dem Foto blieb konstant 156 px breit — auch bei
   1200 px Fensterbreite, wo die Zeile 1153 px hat und rund 700 px leer
   blieben. Als Flex-Kind ohne flex-grow schrumpft er auf seine
   Mindestbreite, und Namen wie E-Mail-Adressen brechen enger um als nötig.
   min-width:0 gehört dazu, sonst verhindert der längste unteilbare Text
   (die E-Mail-Adresse) das Schrumpfen unter die Spaltenbreite. */
.vs-person > :last-child { flex: 1; min-width: 0; }
/* Auf schmalen Bildschirmen Bild über den Namen statt daneben.
 *
 * Dabei muss der Abstand mitgeändert werden: Nebeneinander sind 24 px
 * zwischen Bild und Name richtig, untereinander nicht. Zwischen zwei
 * Personen liegen 32 px — bei 24 px innerhalb einer Person sind die beiden
 * Abstände fast gleich groß, und dann liest sich die Spalte als eine Reihe
 * lose gestapelter Elemente statt als Bild-mit-Namen-Paare. Näher heißt
 * zusammengehörig, und das muss deutlich näher sein.
 */
@media (max-width: 30rem) {
  .vs-person {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
  }
  /* Gegenprobe: mehr Luft zwischen den Personen, damit das Verhältnis
     eindeutig bleibt (8 px innen zu 48 px außen). */
  .vs-personen { gap: var(--space-7); }
}
.vs-person__name {
  font-family: var(--font-display);
  font-weight: var(--fw-bold);
  font-size: var(--fs-h4);
  color: var(--text-strong);
  margin: 0 0 var(--space-2);
}
.vs-person__klassen { display: flex; flex-wrap: wrap; gap: var(--space-1); margin: 0; }
.vs-person__mail { font-size: var(--fs-sm); margin: var(--space-2) 0 0; }


/* ------------------------------------------------------------
   Presse
   ------------------------------------------------------------ */

.vs-presse { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-6); }
.vs-presse__eintrag {
  display: grid;
  grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
  gap: var(--space-5);
  align-items: start;
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--border-soft);
}
@media (max-width: 40rem) {
  .vs-presse__eintrag { grid-template-columns: 1fr; }
}
.vs-presse__eintrag img {
  width: 100%;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  display: block;
}
.vs-presse__medium { margin: 0 0 var(--space-1); }
.vs-presse__titel { font-size: var(--fs-h3); margin: 0 0 var(--space-3); }


/* ------------------------------------------------------------
   Aufklappbereich (vergangene Termine)
   ------------------------------------------------------------ */

.vs-vergangen { margin-top: var(--space-8); }
.vs-vergangen > summary {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  min-height: var(--hit);
  padding: var(--space-2) var(--space-4);
  border: var(--border-width) solid var(--border-soft);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  font-weight: var(--fw-bold);
  color: var(--text-link);
}
.vs-vergangen > summary:hover { border-color: var(--border-strong); }


/* ------------------------------------------------------------
   Klassenübersicht
   ------------------------------------------------------------ */

/* Eigenes Raster statt vs-grid-3: Bei acht Klassen mit Gruppenfoto zählt
   nicht, wie viele Karten nebeneinander passen, sondern ob man die Kinder
   erkennt. Zwei bis drei Spalten statt vier — bei 1200 px Inhaltsbreite
   ist jedes Bild damit rund 380 statt 280 px breit. */
.vs-klassen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: var(--space-6);
}


/* ------------------------------------------------------------
   Galerie: Bild vergrößern
   ------------------------------------------------------------ */

.vs-galerie__link {
  display: block;
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  line-height: 0;
}
.vs-galerie__link:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; }

/* Lupensymbol als Hinweis, dass sich das Bild öffnen lässt. Rein
   dekorativ — die Information steht im aria-label des Links. */
.vs-galerie__lupe {
  position: absolute;
  right: var(--space-3);
  bottom: var(--space-3);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(35, 35, 35, 0.62);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.vs-galerie__lupe::before,
.vs-galerie__lupe::after {
  content: "";
  position: absolute;
  background: #fff;
}
/* Plus-Zeichen */
.vs-galerie__lupe::before { left: 11px; top: 17px; width: 14px; height: 2px; }
.vs-galerie__lupe::after  { left: 17px; top: 11px; width: 2px;  height: 14px; }

.vs-galerie__link:hover .vs-galerie__lupe,
.vs-galerie__link:focus-visible .vs-galerie__lupe { opacity: 1; }

/* Auf Touchgeräten gibt es kein Überfahren — dort dauerhaft zeigen. */
@media (hover: none) {
  .vs-galerie__lupe { opacity: 1; }
}


/* --- Der Dialog selbst --- */

.vs-lupe {
  width: min(96vw, 1400px);
  max-width: none;
  max-height: 96vh;
  padding: var(--space-5);
  border: 0;
  border-radius: var(--radius-xl);
  background: var(--surface-card);
  color: var(--text-body);
  overflow: visible;
}
.vs-lupe::backdrop { background: rgba(35, 35, 35, 0.82); }

.vs-lupe__buehne {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-sunken);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.vs-lupe__bild {
  display: block;
  max-width: 100%;
  /* Höhe begrenzen, damit Bildunterschrift und Leiste sichtbar bleiben —
     sonst schiebt ein Hochformatbild die Bedienung aus dem Fenster. */
  max-height: 74vh;
  width: auto;
  object-fit: contain;
}

.vs-lupe__text {
  margin: var(--space-4) 0 0;
  font-size: var(--fs-sm);
  color: var(--text-body);
  text-align: center;
}
.vs-lupe__text:empty { display: none; }

.vs-lupe__leiste {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.vs-lupe__knopf {
  min-height: var(--hit);
  padding: var(--space-2) var(--space-5);
  font-family: var(--font-text);
  font-weight: var(--fw-extra);
  font-size: var(--fs-body);
  color: var(--c-blue-800);
  background: var(--surface-card);
  border: var(--border-width) solid var(--color-brand-fill);
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.vs-lupe__knopf:hover { background: var(--color-brand-soft); color: var(--c-blue-900); }
.vs-lupe__zaehler {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  min-width: 7ch;
  text-align: center;
}

.vs-lupe__zu {
  position: absolute;
  top: calc(var(--space-4) * -1);
  right: calc(var(--space-4) * -1);
  width: 48px;
  height: 48px;
  font-size: var(--fs-h4);
  color: var(--text-strong);
  background: var(--surface-card);
  border: var(--border-width) solid var(--border-soft);
  border-radius: 50%;
  box-shadow: var(--shadow-md);
  cursor: pointer;
}
.vs-lupe__zu:hover { background: var(--surface-sunken); }

@media (max-width: 40rem) {
  .vs-lupe { padding: var(--space-4); border-radius: var(--radius-lg); }
  .vs-lupe__zu { top: var(--space-2); right: var(--space-2); }
  .vs-lupe__bild { max-height: 62vh; }
}
