/*
Theme Name: Ukulele Stammtisch FFM — Original
Theme URI: https://ukulele-stammtisch-ffm.de
Author: Frankfurter Ukulele Stammtisch
Description: Das »Songbook«-Theme in den Originalfarben: mauvebrauner Seitengrund, schwarze Fußzeile, cyanfarbene Links, weiße Überschriften — dazu das Originallogo im Kopf, dessen Farbverlauf randlos bis an beide Fensterkanten läuft und in dem unten rechts das gelbe Menü liegt. Aufbau, Layout, Typografie und alle Funktionen entsprechen dem aktuellen Theme, verändert sind nur Farben und Logo. Schriften (Young Serif, Familjen Grotesk) sind lokal gebündelt.
Version: 1.2.7
Requires at least: 6.0
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: ukulele-stammtisch-ffm
*/

/* ---------- Schriften (lokal, SIL OFL — siehe assets/fonts/) ---------- */

@font-face {
  font-family: "Young Serif";
  src: url("assets/fonts/young-serif-400-latin.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Familjen Grotesk";
  src: url("assets/fonts/familjen-grotesk-400-700-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Familjen Grotesk";
  src: url("assets/fonts/familjen-grotesk-italic-400-700-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: italic;
  font-display: swap;
}

/* ---------- Grundgerüst ---------- */

:root {
  /* Die Farben heißen nach ihrer Aufgabe, nicht nach ihrem Ton: welchen Ton
     sie tragen, ist einstellbar (siehe ukulele_ffm_custom_css() in
     functions.php) — ein Name wie »Mauve« oder »Cyan« stünde schon nicht mehr,
     sobald jemand etwas anderes einstellt. Welcher Ton in der Vorgabe hinter
     welcher Aufgabe steht, sagt der Wert daneben. Drei davon sind im Customizer
     einstellbar: --bg (»Seitengrund«), --accent (»Akzent«) und --nav-ink
     (»Menüschrift«); --bg-sunk, --accent-hover und --on-accent werden aus
     ihnen abgeleitet und stehen deshalb nicht als eigene Felder. */

  /* Seitengrund. Der Ton ist aus dem Farbverlauf der Logo-Grafik gegriffen —
     Logo und Grund gehen deshalb an der Unterkante des Logos ineinander über. */
  --bg: #704646;
  /* Abgesetzte Flächen auf dem Grund (Bildkästen, »Nächster Termin«). Sie
     dunkeln ab statt aufzuhellen: ein heller Schleier auf dem Grund kostet
     Kontrast, den der Fließtext nicht übrig hat. */
  --bg-sunk: #5c3a3a;
  /* Der dunkle Rahmen der Seite: Fußzeile, die Silhouette darüber und die
     eingerastete Menüleiste — die drei sind bewusst derselbe Ton. Das Schwarz
     der Logo-Grafik (Schriftzug), nicht #000 — wärmer, passt zum Grund. */
  --frame: #231f20;
  /* Oberster Stopp des Logo-Verlaufs (siehe .masthead) */
  --ramp-top: #f3dd11;
  /* Schriftfarbe der Navigation — in der Grafik wie auf der eingerasteten
     Leiste. Der Vorgabeton ist das Gelb der Ukulele, das andere Ende des
     Verlaufs; er trägt über jedem Untergrund, auf den die Links geraten
     können: tiefer Verlauf 4.6–5.7, Seitengrund 6.27, Leiste 12.9 — deshalb
     muss er beim Einrasten nicht wechseln. */
  --nav-ink: #fee702;
  /* Der Akzent (Links, Buttons, Chips, Pills, Auswahl, Fokusring) und die
     Schriftfarbe auf Flächen in ihm. */
  --accent: #0ae2ff;
  --on-accent: #00434c;
  --accent-hover: #7cf0ff;
  /* Überschriften und hervorgehobener Text */
  --text-strong: #ffffff;
  /* Termin-Titel: zwischen Überschrift-Weiß und Fließtext — hebt sich vom
     Text ab, das Datum bleibt trotzdem die hellste Stufe */
  --text-firm: #e6e6e6;
  /* Fließtext */
  --text: #cecece;
  /* Nebentext: #cecece auf dem Grund hat nur ~0,5 Kontrastpunkte Luft bis
     AA — stärker dämpfen geht nicht, die Abstufung trägt der wärmere Ton */
  --text-soft: #cac4c4;
  /* Nur die Datumszeile vergangener Termine — große Schrift, AA-Schwelle 3.0 */
  --text-faint: #bfa8a8;
  /* Trennlinien */
  --line: rgba(221, 221, 221, 0.28);
  --line-soft: rgba(221, 221, 221, 0.14);
  --font-display: "Young Serif", "Iowan Old Style", Georgia, serif;
  --font-body: "Familjen Grotesk", "Avenir Next", "Segoe UI", sans-serif;
  --measure: 64ch;
  --pad: clamp(1.25rem, 4vw, 3rem);
  /* Inhaltsbreite — .wrap und die linke Kante der Kopfgrafik hängen beide
     daran, deshalb steht sie als Wert und nicht zweimal als Zahl. */
  --wrap-w: 68rem;
  /* Breite der Textspalte — .wrap-narrow und die erste Spalte des
     Inhaltsrasters hängen beide daran, aus demselben Grund. */
  --wrap-narrow-w: 46rem;
  /* Seitenleiste: schmal genug, dass sie neben dem Text als Marginalie
     liest, breit genug für ein Bild oder eine Terminliste. */
  --aside-w: 15rem;
  --aside-gap: clamp(2rem, 4vw, 3.5rem);

  /* ---- Maße des Kopfes ----
     Alles hängt an der Breite der Kopfgrafik, nichts ist gesetzt: die Grafik
     ist 420x168, also 2.5:1 — jede Höhe hier ist Breite / 2.5.
     --head-logo-w-set ist der einzige Stellwert (Customizer, siehe
     ukulele_ffm_custom_css() in functions.php). Er ist bewusst nicht --wrap-w:
     die Grafik darf breiter oder schmaler als der Inhalt sein, ihre linke
     Kante bleibt dabei aber an der des Inhalts stehen (siehe .site-title).
     100vw statt 100%: ein Prozentwert in einer Custom Property löst erst an
     der Verwendungsstelle auf — er meinte dort die Breite des Elements, nicht
     die des Fensters. Der Preis ist die Scrollbar, die 100vw mitzählt: am
     rechten Rand fällt der Abstand um ihre Breite knapper aus, sobald die
     Deckelung greift. Die linke Kante ist davon nicht betroffen, sie rechnet
     an ihrer Verwendungsstelle über 100% (siehe .site-title). */
  --head-logo-w-set: 68rem;
  --head-logo-w: min(var(--head-logo-w-set),
    100vw - max(var(--pad), (100vw - var(--wrap-w)) / 2) - var(--pad));
  /* Breite, auf die die Grafik beim Scrollen zusammenschrumpft: 6rem = 2.4rem
     hoch, das trägt die Menüzeile (1lh) mit etwas Luft darüber und darunter. */
  --head-logo-w-min: 6rem;
  --head-logo-w-now: var(--head-logo-w);
  /* Das Polster über und unter der geschrumpften Grafik, sobald der Kopf
     eingerastet ist (siehe head-shrink). In Ruhe hat der Kopf keins: die
     Grafik sitzt bündig an der Fensterkante wie bisher, und der Verlauf läuft
     über ihre volle Höhe. */
  --head-pt: 0.35rem;
  /* Abstand der Links über der Unterkante der Grafik, solange der Kopf groß
     ist. Weiter hinauf als 1rem geht nicht: die Links sitzen im dunklen Ende
     des Verlaufs, und der wird nach oben hin heller — bei 1rem steht Gelb auf
     #995145 und hält 4.58, ab etwa 20px fällt es unter AA (4.5). Der Verlauf
     ist die Grenze, nicht der Geschmack. */
  --head-nav-b: 1rem;
  --head-line: 1.5px;
  /* Ruhe- und Endhöhe des Kopfes, jeweils inklusive Rahmen. Aus ihrer
     Differenz kommt der Scrollweg: der Kopf schrumpft damit exakt so schnell,
     wie der Inhalt hochscrollt — seine Unterkante bleibt auf dem ganzen Weg
     auf dem Inhalt kleben. (Das Bordeaux-Theme rechnet hier --head-pb heraus,
     damit der Kopf dem Inhalt um die Höhe des überlappenden »Nächster
     Termin«-Kastens vorauseilt; den gibt es hier nicht.) */
  --head-rest: calc(var(--head-logo-w) / 2.5 + var(--head-line));
  --head-compact-box: calc(2 * var(--head-pt) + var(--head-logo-w-min) / 2.5);
  --head-compact: calc(var(--head-compact-box) + var(--head-line));
  --head-shrink: calc(var(--head-rest) - var(--head-compact));
}

/* Ohne Registrierung wäre --head-logo-w-now für den Browser nur ein
   Token-Strom und zwischen Ruhe- und Kompaktbreite nicht interpolierbar — die
   Grafik spränge auf halbem Scrollweg von voller auf Sockelgröße, während der
   Platzhalter auf Ruhehöhe stünde. Getippt ist der Wert eine echte Länge und
   damit animierbar. */
@property --head-logo-w-now {
  syntax: "<length>";
  inherits: true;
  initial-value: 0px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--text);
  font-size: 1.0625rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

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

/* Korn + Lichtstimmung — nehmen der großen einfarbigen Fläche die Flachheit */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.35'/%3E%3C/svg%3E");
  opacity: 0.05;
}
/* Oben ein Hauch Gold (die obere Hälfte des Logo-Verlaufs), unten ein Abdunkeln
   als Anlauf auf das schwarze Footer-Band. Das Gold bleibt bei 0.04: heller
   aufgetragen fiele der Fließtext am Seitenkopf unter AA. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(120% 90% at 50% 0%, rgba(243, 221, 17, 0.04), transparent 55%),
    radial-gradient(140% 100% at 50% 115%, rgba(35, 31, 32, 0.28), transparent 60%);
}

.site-shell { position: relative; z-index: 1; display: flex; flex-direction: column; min-height: 100vh; }

.wrap { width: min(var(--wrap-w), 100% - 2 * var(--pad)); margin-inline: auto; }
.wrap-narrow { width: min(var(--wrap-narrow-w), 100% - 2 * var(--pad)); margin-inline: auto; }

/* ---------- Inhaltsraster (Text + Seitenleiste) ---------- */

/* Einspurig ist das Raster deckungsgleich mit .wrap-narrow (gleiche Spur,
   selbst zentriert); erst body.has-sidebar (siehe functions.php)
   stellt ab 60rem die Leiste daneben — siehe Responsiv-Block unten. Die
   Textspalte behält dabei exakt die Breite, die sie ohne Leiste hätte: die
   Leiste kommt daneben, statt dem Text etwas wegzunehmen. Deshalb ist die
   Spur --wrap-narrow-w und nicht 1fr, und das Raster zentriert seine Spuren
   selbst, statt sie über die vollen --wrap-w zu ziehen. Kopf und Inhalt
   tragen dasselbe Raster, damit der Titel in derselben Spur steht wie der
   Text darunter; die Spuren füllen sich per Auto-Platzierung. */
.content-grid {
  display: grid;
  grid-template-columns: minmax(0, var(--wrap-narrow-w));
  justify-content: center;
  align-items: start;
}
/* Lange URLs & Co. brechen um, statt in die Leiste (oder aus ihr heraus) zu
   laufen — die Spuren haben keine Reserve: minmax(0, …) bzw. fest --aside-w. */
.content-main, #secondary { overflow-wrap: break-word; }

::selection { background: var(--accent); color: var(--on-accent); }

/* Der voreingestellte Fokusring der Browser ist dunkel und verschwindet auf
   dem dunklen Grund — deshalb ein eigener in der Akzentfarbe. outline-offset
   hält ihn außerhalb der Buttons in der Akzentfarbe, wo er sonst unsichtbar
   wäre. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.skip-link {
  position: absolute; left: -999px; top: 0.5rem;
  background: var(--accent); color: var(--on-accent);
  padding: 0.5rem 1rem; border-radius: 6px; z-index: 50;
}
.skip-link:focus { left: 0.5rem; }

.screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px;
  clip-path: inset(50%);
  overflow: hidden;
  word-wrap: normal !important;
}

/* ---------- Kopf: das Menü liegt in der Grafik, die beim Scrollen einrastet ---------- */

/* Der Verlauf ist Stopp für Stopp der der Logo-Grafik (assets/svg/logo.svg,
   dort über dieselbe Höhe gelegt) — nicht nachempfunden, sondern derselbe,
   damit die Flächen links und rechts des Logos exakt weiterlaufen.
   Er liegt als eigene Ebene über dem schwarzen Grund statt als Hintergrund des
   Kopfes selbst: beim Einrasten blendet er weg und gibt das Schwarz frei —
   ein Verlauf lässt sich nicht in eine Farbe interpolieren, die Überblendung
   braucht deshalb zwei Ebenen. Das Schwarz ist dasselbe wie das der Silhouette
   und der Fußzeile (--frame): der Kopf schließt die Seite oben so ab, wie
   der Fuß sie unten abschließt.
   Der Schatten liegt in beiden Zuständen an — der Kopf ist auch in Ruhe die
   oberste Ebene und soll sich vom Seitengrund abheben. In Ruhe ist er aber
   deutlich zurückgenommen: unter einer über 400px hohen Fläche liest sich der
   Schatten der schmalen Leiste als harte Bank, nicht als Kante. Er wächst erst
   mit dem Einrasten auf sein volles Maß (siehe head-shrink). */
.masthead {
  position: relative;
  z-index: 40;
  background-color: var(--frame);
  border-bottom: var(--head-line) solid var(--line);
  box-shadow: 0 8px 18px -14px rgba(0, 0, 0, 0.3);
}
/* Der Verlauf spannt den Kopf in jeder Höhe, nicht die Ruhehöhe: in Ruhe liegt
   die Grafik dadurch im Originalverlauf, die eingerastete Leiste zeigt am Ende
   nur noch das Schwarz darunter. inset:0 endet am Polsterkasten, die
   Rahmenlinie bleibt also frei — sonst liefe der Verlauf golden in sie hinein,
   statt die Grafik in den Seitengrund auslaufen zu lassen. */
.masthead::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: linear-gradient(180deg,
    var(--ramp-top) 0%, #efd516 7.14%, #eacd1b 14.29%, #e4c321 21.43%,
    #deb927 28.57%, #d8af2d 35.71%, #d1a432 42.86%, #ca9837 50%,
    #c28c3c 57.14%, #ba7f40 64.29%, #b17243 71.43%, #a86545 78.57%,
    #9f5945 85.71%, #954c45 92.86%, #8b4044 100%);
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* Die Grafik trägt den Schriftzug bereits in sich — der Websitetitel steht
   deshalb nur noch für Screenreader im h1/p (siehe header.php).
   Die linke Kante rechnet wie .wrap (--wrap-w, zentriert), aber über 100%
   statt über 100vw: nur so fluchtet sie auf den Pixel mit dem Inhalt darunter,
   die Scrollbar zählt hier nicht mit. Sie hängt an --wrap-w, nicht an der
   eingestellten Breite — verstellt man die, wächst die Grafik nach rechts und
   die Kante bleibt stehen.
   line-height:0 hält den Inhaltskasten des Kopfes genau auf Bildhöhe — daran
   hängt, dass der Verlauf oben im Gold und unten im Seitengrund ankommt.
   z-index hebt Grafik und Menü über die Verlaufsebene. */
.site-title {
  position: relative;
  z-index: 1;
  margin: 0;
  margin-left: max(var(--pad), (100% - var(--wrap-w)) / 2);
  line-height: 0;
}
/* Auf der eingerasteten Leiste steht die bordeauxfarbene Skyline der Grafik
   (#4c0821, im SVG festgelegt) auf --frame bei 1.06 — sie verschwände, und
   der schwarze Schriftzug mit ihr. Der weiße Schein dahinter hebt beide ab,
   ohne einen Pfad umzufärben: die Grafik ist ein <img>, CSS kommt an ihre
   Farben nicht heran. In Ruhe liegt sie im Verlauf und braucht ihn nicht —
   dort ist er auf 0.
   drop-shadow folgt der Silhouette, box-shadow läge nur um den Rahmen. */
.site-title a {
  display: block;
  filter: drop-shadow(0 0 0 rgb(255 255 255 / 0));
}
/* min(…, 100%) fängt den Fall ab, dass 100vw in --head-logo-w die Scrollbar
   mitzählt und die Grafik dadurch breiter ausfiele als der Platz neben ihrer
   linken Kante. */
.site-title img { display: block; width: min(var(--head-logo-w-now), 100%); height: auto; }

/* Unten rechts, außerhalb des Flusses: so bestimmt allein die Grafik die
   Kopfhöhe und --head-rest bleibt rechenbar. Die rechte Kante rechnet wie die
   linke und fluchtet damit mit .wrap. In Ruhe hängen die Links im dunklen Ende
   des Verlaufs (Gelb 4.58 bei --head-nav-b, siehe dort); auf der eingerasteten
   Leiste stehen sie neben der geschrumpften Grafik auf Schwarz (12.9). Beide
   Zustände tragen — die Farbe muss deshalb nie wechseln. */
.masthead .nav {
  position: absolute;
  z-index: 1;
  right: max(var(--pad), (100% - var(--wrap-w)) / 2);
  bottom: var(--head-nav-b);
}
/* Der Fokusring der Seite (Akzentfarbe) säße hier auf dem tiefen Verlauf.
   currentColor ist im Kopf immer das Gelb der Links — das trägt auf jedem
   Untergrund, den er annehmen kann. */
.masthead :focus-visible { outline-color: currentColor; }

.nav ul {
  display: flex; gap: clamp(1rem, 3vw, 2.2rem); flex-wrap: wrap;
  list-style: none; margin: 0; padding: 0;
}
.masthead .nav ul { justify-content: flex-end; }
.nav a {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--nav-ink);
  padding: 0.2rem 0 0.45rem;
}

/* Die Kurzform einer Menübeschriftung (siehe UKULELE_FFM_SHORT_LABEL_KEY in
   functions.php) steht nur da, wo das Menü sonst umbräche — sonst gilt die
   Langform. */
.nav-label-short { display: none; }

/* Der feste Kopf und sein Platzhalter dürfen nur existieren, wo er auch
   schrumpfen kann: ohne scroll()-Timeline stünde er ewig auf Ruhehöhe und
   fräße auf dem Telefon das halbe Sichtfeld. Ohne Unterstützung bleibt er
   also im Fluss und scrollt weg — das Menü trägt dann der Footer. */
@supports (animation-timeline: scroll()) {
  /* Nicht sticky: ein klebendes Element behält seinen Platz im Fluss. Beim
     Schrumpfen zöge es alles darunter zusätzlich zum Scrollen nach oben — der
     Inhalt liefe doppelt so schnell. Fest + Platzhalter trennt beides.
     top nutzt WPs eigene Custom Property, damit der Kopf bei eingeloggten
     Redakteuren nicht unter der Admin-Bar verschwindet. */
  .site-shell { padding-top: var(--head-rest); }
  .masthead {
    position: fixed;
    top: var(--wp-admin--admin-bar--height, 0px);
    left: 0;
    right: 0;
    animation: head-shrink linear both;
  }
  .masthead::before { animation: ramp-fade linear both; }
  .site-title a { animation: logo-glow linear both; }
  .masthead .nav { animation: nav-drop linear both; }
  .masthead,
  .masthead::before,
  .site-title a,
  .masthead .nav {
    animation-timeline: scroll(root block);
    animation-range: 0 var(--head-shrink);
  }
}
/* Aus der Grafik wird eine schwarze Leiste mit Kante in der Akzentfarbe; die
   Grafik selbst
   schrumpft auf ihren Sockel und bleibt dort als Marke stehen. Der Schatten
   zieht dabei an: die schmale Leiste liegt über dem Inhalt und braucht die
   Kante, die große Grafik in Ruhe nicht (siehe .masthead). */
@keyframes head-shrink {
  to {
    --head-logo-w-now: var(--head-logo-w-min);
    padding-top: var(--head-pt);
    padding-bottom: var(--head-pt);
    border-bottom-color: var(--accent);
    box-shadow: 0 16px 28px -12px rgba(0, 0, 0, 0.55);
  }
}
@keyframes ramp-fade {
  to { opacity: 0; }
}
@keyframes logo-glow {
  to { filter: drop-shadow(0 0 7px rgb(255 255 255 / 0.85)); }
}
/* Auf der Leiste stehen die Links mittig neben der geschrumpften Grafik: 1lh
   ist ihre eigene Zeilenhöhe, --head-compact-box der Polsterkasten der Leiste
   — die Differenz, halbiert, ist ihr Abstand nach unten. */
@keyframes nav-drop {
  to { bottom: calc((var(--head-compact-box) - 1lh) / 2); }
}

/* Schmaler als 55rem wird die Grafik zu flach, als dass die Links in ihrem
   dunklen Ende Platz fänden: sie stünden mitten auf dem Schriftzug. Sie rücken
   deshalb unter die Grafik — dorthin, wo bis eben die Leiste stand — und
   stehen dabei wieder im Fluss. Damit bekommt der Kopf seine Höhe von selbst,
   und zwar auch dann, wenn die Links auf mehrere Zeilen umbrechen; gerechnet
   werden müsste sie sonst, und wie viele Zeilen ein Menü braucht, weiß CSS
   nicht. Der Kopf bleibt hier deshalb im Fluss und scrollt weg, statt zu
   schrumpfen: ein Platzhalter, der die Höhe nicht kennt, risse eine Lücke.
   Statt fest + Platzhalter klebt der Kopf hier mit negativem top in Höhe der
   Grafik: sie schiebt sich aus dem Bild, die Menüzeile(n) samt Polster
   bleiben oben stehen — wie hoch das Menü umbricht, muss dafür niemand
   wissen, und es funktioniert auch ohne scroll()-Timeline. Die Admin-Bar
   zählt im top mit, solange sie fest ist; unter 783px stellt WP sie auf
   position:absolute, dort fällt sie wieder heraus (siehe unten). */
@media (max-width: 55rem) {
  .site-shell { padding-top: 0; }
  .masthead {
    position: sticky;
    top: calc(var(--wp-admin--admin-bar--height, 0px) - var(--head-logo-w) / 2.5);
    padding-bottom: var(--head-pt);
  }
  .masthead,
  .masthead::before,
  .site-title a,
  .masthead .nav {
    animation: none;
  }
  /* Dieselbe Rechnung wie .wrap: die Links fluchten mit dem Inhalt darunter.
     relative statt static: z-index greift nur an positionierten Elementen, und
     ohne ihn lägen die Links hinter der Verlaufsebene (::before ist absolut
     positioniert und damit von sich aus die obere Ebene). inset setzt den
     Versatz zurück, den sie als absolut positionierte Ecke hatten. */
  .masthead .nav {
    position: relative;
    inset: auto;
    width: min(var(--wrap-w), 100% - 2 * var(--pad));
    margin-inline: auto;
    padding-top: var(--head-pt);
  }
  /* Mittig statt rechtsbündig: bricht das Menü doch um (siehe unten), stehen
     beide Zeilen als Block unter der Grafik — rechtsbündig hing die kürzere
     Zeile frei in der Fläche und las sich als Fehler.
     Die Lücke wandert in die Links hinein: als Polster ist sie mitgetippt,
     als gap wäre sie toter Raum zwischen zwei 26 px hohen Zielen. 0.75rem
     oben und unten bringen die Zeilenbox (0.8rem × 1.65) auf die 44 px, die
     iOS als Mindestmaß nennt. --underline-pos hält die Unterstreichung dabei
     am Text statt an der Unterkante des Polsters. */
  .masthead .nav ul { justify-content: center; gap: 0; }
  .masthead .nav a {
    display: inline-block;
    padding: 0.75rem 0.3rem;
    --underline-pos: calc(100% - 0.75rem);
  }
  /* Wo scroll()-Timelines tragen, blendet der Verlauf wie am Desktop zum
     schwarzen Balken ab; der Weg ist die Höhe der Grafik — genau die
     Strecke, bis der Kopf einrastet. Kein logo-glow: die Grafik ist dann
     aus dem Bild geschoben, ihr Schein schmierte nur in den Balken. */
  @supports (animation-timeline: scroll()) {
    .masthead { animation: head-bar linear both; }
    .masthead::before { animation: ramp-fade linear both; }
    .masthead,
    .masthead::before {
      animation-timeline: scroll(root block);
      animation-range: 0 calc(var(--head-logo-w) / 2.5);
    }
  }
}
/* Mobiler Endzustand: nur Kante und Schatten — die Grafik behält ihr Maß,
   sie ist beim Einrasten schon aus dem Bild geschoben. */
@keyframes head-bar {
  to {
    border-bottom-color: var(--accent);
    box-shadow: 0 16px 28px -12px rgba(0, 0, 0, 0.55);
  }
}
/* WP stellt die Admin-Bar unter 783px auf position:absolute — sie scrollt
   mit, ihre Custom Property bleibt aber auf 46px stehen und schöbe den
   eingerasteten Kopf um genau diese Lücke zu tief. */
@media (max-width: 782px) {
  .masthead { top: calc(-1 * var(--head-logo-w) / 2.5); }
}
/* Erst hier wird der Platz knapp: die fünf Punkte messen in Langform 399 px
   plus Polster — bis etwa 34rem trägt die Zeile das noch, darüber bleibt
   deshalb alles ausgeschrieben. Darunter greifen Kurzform, engere Laufweite
   und eine Spur kleinere Schrift und bringen sie zusammen auf 315 px. Alle
   drei werden gebraucht: die Kurzform allein spart 79 px und reicht nicht,
   die Laufweite allein 61 px und auch nicht.
   315 px passen in ein 360-px-Fenster (320 px zwischen den Polstern) und
   damit in jedes gängige Telefon. Was schmaler ist, bricht in zwei mittige
   Zeilen um (siehe oben) — der Rückfall ist gebaut, nicht zufällig.
   Der Fuß behält die Langform: dort ist Platz, und die Punkte stehen ohnehin
   untereinander. */
@media (max-width: 34rem) {
  .masthead .nav a { font-size: 0.75rem; letter-spacing: 0.06em; }
  .masthead .nav-label-full { display: none; }
  .masthead .nav-label-short { display: inline; }
}
/* Die Schrift bleibt in jedem Zustand gelb (siehe --nav-ink) — die
   aktuelle Seite und der Hover zeigen sich deshalb allein über die
   Unterstreichung. Sie ist hier dicker als sonst im Theme: sie ist der
   einzige Hinweis und muss auch auf der Grafik sofort ins Auge fallen. */
.nav a { --underline: 2.5px; }

/* Von links wachsende Unterstreichung für alle Link-Arten.
   box-decoration-break: clone lässt jede umbrochene Zeile ihre
   eigene Linie wachsen. */
.nav a, .footer-nav a, .footer-legal a, .entry h2 a, .entry-body a,
.post-navigation a, .back-link a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-size: 0% var(--underline, 1.5px);
  /* --underline-pos in em setzen, wenn die Inline-Box höher ist als die
     Zeilenhöhe (Young Serif: 1,42em Box) — sonst trifft die Linie der
     ersten Zeile die zweite */
  background-position: 0 var(--underline-pos, 100%);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  transition: background-size 0.25s ease, color 0.15s ease;
}
.nav a:hover, .nav a:focus-visible, .nav a[aria-current="page"],
.footer-nav a:hover, .footer-nav a:focus-visible,
.footer-legal a:hover, .footer-legal a:focus-visible,
.entry h2 a:hover, .entry h2 a:focus-visible,
.entry-body a:hover, .entry-body a:focus-visible,
.post-navigation a:hover, .post-navigation a:focus-visible,
.back-link a:hover, .back-link a:focus-visible {
  background-size: 100% var(--underline, 1.5px);
}

main { flex: 1; }

/* ---------- Termin-Chip ---------- */

.next-chip {
  display: inline-block;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0.7rem 1.4rem;
  transition: translate 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.next-chip .arrow { display: inline-block; margin-left: 0.35rem; transition: translate 0.18s ease; }
.next-chip:hover, .next-chip:focus-visible {
  translate: 0 -1px;
  filter: brightness(1.08);
  box-shadow: 0 12px 22px -14px rgba(10, 226, 255, 0.85);
}
.next-chip:hover .arrow { translate: 4px 0; }
.next-chip strong { font-weight: 700; }
.nowrap { white-space: nowrap; }

/* ---------- Beitrags-Feed ---------- */

.feed { padding: clamp(2rem, 5vh, 3rem) 0 clamp(3rem, 8vh, 5rem); }

.feed-head {
  display: flex; align-items: center; gap: 1rem 1.5rem; flex-wrap: wrap;
  margin-bottom: 0.5rem;
  animation: rise 0.6s 0.05s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.feed-head .section-label { flex: 1 1 14rem; margin-bottom: 0; }

.section-label {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  display: flex; align-items: center; gap: 1rem;
  margin-bottom: 0.5rem;
}
.section-label::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.entry {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: clamp(1.2rem, 4vw, 2.8rem);
  padding-block: clamp(2rem, 5vh, 2.8rem);
  border-top: 1px solid var(--line-soft);
  animation: rise 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.entry:first-of-type { border-top: 0; }
.entry:nth-of-type(1) { animation-delay: 0.12s; }
.entry:nth-of-type(2) { animation-delay: 0.2s; }
.entry:nth-of-type(3) { animation-delay: 0.28s; }
.entry:nth-of-type(4) { animation-delay: 0.36s; }
.entry:nth-of-type(5) { animation-delay: 0.44s; }

.stamp {
  align-self: start;
  justify-self: start;
  text-align: center;
  border: 1.5px solid var(--accent);
  border-radius: 10px;
  color: var(--accent);
  background: rgba(10, 226, 255, 0.07);
  padding: 0.55rem 0.9rem 0.6rem;
  min-width: 5.4rem;
  rotate: -2.5deg;
  transition: rotate 0.25s cubic-bezier(0.3, 1.4, 0.5, 1);
}
.entry:hover .stamp { rotate: 0deg; }
.stamp .day {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 2rem;
  line-height: 1;
}
.stamp .my {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-top: 0.3rem;
}

.entry h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.45rem, 3vw, 1.9rem);
  line-height: 1.3;
  letter-spacing: -0.005em;
  text-wrap: balance;
  color: var(--text-strong);
  margin-bottom: 0.9rem;
}
/* 1.05em Ascent + 0.25em Abstand — bei line-height 1.3 bleibt Luft zur
   Folgezeile (Ü ragt 0.99em über deren Grundlinie) */
.entry h2 a { color: inherit; --underline: 2.5px; --underline-pos: 1.3em; }
.entry h2 a:hover, .entry h2 a:focus-visible { color: var(--accent); }

.entry-body { max-width: var(--measure); color: var(--text); }
.entry-body p + p { margin-top: 0.9rem; }
.entry-body strong { color: var(--text-strong); }
.entry-body a { color: var(--accent); padding-bottom: 1px; }
.entry-body a:hover { color: var(--accent-hover); }

.entry-body figure {
  margin: 1.2rem 0;
  max-width: 34rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-sunk);
  box-shadow: 0 10px 28px -18px rgba(0, 0, 0, 0.65);
}
.entry-body figure img { display: block; width: 100%; height: auto; }
.entry-body figcaption {
  font-size: 0.85rem; color: var(--text-soft);
  padding: 0.5rem 0.9rem;
}

/* Beitragsnavigation */
.posts-navigation, .post-navigation { margin-top: 1.5rem; }
.posts-navigation .nav-links, .post-navigation .nav-links {
  display: flex; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap;
}

/* „Ältere/Neuere Beiträge" (Blog-Liste) als Button — selbes Muster wie
   .next-chip und die Formular-Buttons, feste Labels vertragen die Pille. */
.posts-navigation a {
  display: inline-block;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--on-accent);
  background: var(--accent);
  border-radius: 999px;
  padding: 0.7rem 1.4rem;
  text-decoration: none;
  transition: translate 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.posts-navigation a:hover, .posts-navigation a:focus-visible {
  color: var(--on-accent);
  translate: 0 -1px;
  filter: brightness(1.08);
  box-shadow: 0 12px 22px -14px rgba(10, 226, 255, 0.85);
}

/* Vorheriger/nächster Einzelbeitrag (Titel sind lang) bleibt Textlink */
.post-navigation a {
  font-weight: 600;
  color: var(--text-strong);
  --underline: 2px;
  padding-bottom: 0.2rem;
}
.post-navigation a:hover { color: var(--accent); }

/* ---------- Unterseiten ---------- */

.page-head { padding: clamp(2.8rem, 7vh, 4.5rem) 0 0; }
.back-link {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-soft);
  margin-bottom: 1rem;
}
.back-link a { color: inherit; }
.back-link a:hover, .back-link a:focus-visible { color: var(--accent); }
.eyebrow {
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 1rem;
}
.page-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  line-height: 1.1;
  letter-spacing: -0.005em;
  text-wrap: balance;
  color: var(--text-strong);
  animation: rise 0.7s 0.05s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.lede {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.2rem, 2.5vw, 1.5rem);
  color: var(--accent);
  margin-top: 1.4rem;
  text-wrap: balance;
  animation: rise 0.7s 0.15s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.page-content { padding: clamp(1.8rem, 4vh, 2.5rem) 0 clamp(3.5rem, 9vh, 5.5rem); }
.prose { max-width: var(--measure); color: var(--text); font-size: 1.125rem; animation: rise 0.7s 0.25s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.prose p + p { margin-top: 1.1rem; }
.prose strong { color: var(--text-strong); }
.prose a { color: var(--accent); }
.prose a:hover { color: var(--accent-hover); }

/* Überschriften im Seiteninhalt tragen die Display-Schrift —
   die erste Zeile einer Seite darf groß auftreten */
.prose h1, .prose h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 5vw, 3.2rem);
  line-height: 1.08;
  letter-spacing: -0.005em;
  color: var(--text-strong);
  text-wrap: balance;
  margin: 1.8rem 0 1rem;
}
.prose h1:first-child, .prose h2:first-child { margin-top: 0; }
.prose h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.4rem;
  color: var(--text-strong);
  margin: 1.6rem 0 0.6rem;
}
.prose ul, .prose ol { padding-left: 1.3rem; margin: 1rem 0; }

/* Formulare im Seiteninhalt (z. B. Jetpack-Kontaktformular) */
.prose label {
  display: block;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
  margin-bottom: 0.45rem;
}
.prose input[type="text"],
.prose input[type="email"],
.prose input[type="url"],
.prose input[type="tel"],
.prose textarea {
  width: 100%;
  max-width: 36rem;
  font: inherit;
  color: var(--text-strong);
  background: rgba(0, 0, 0, 0.22);
  border: 1.5px solid var(--line);
  border-radius: 10px;
  padding: 0.75rem 0.95rem;
  margin-bottom: 1.1rem;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.prose textarea { min-height: 9rem; resize: vertical; }
.prose input:focus, .prose textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(10, 226, 255, 0.25);
}
.prose button,
.prose input[type="submit"],
.prose .wp-block-button__link,
.widget button,
.widget input[type="submit"] {
  font: inherit;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--on-accent);
  background: var(--accent);
  border: 0;
  border-radius: 999px;
  padding: 0.8rem 2.2rem;
  cursor: pointer;
  transition: translate 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.prose button:hover,
.prose input[type="submit"]:hover,
.prose .wp-block-button__link:hover,
.widget button:hover,
.widget input[type="submit"]:hover {
  translate: 0 -1px;
  filter: brightness(1.08);
  box-shadow: 0 12px 22px -14px rgba(10, 226, 255, 0.85);
}

/* Jetpacks Formular-CSS (grunion.css) setzt .pushbutton-wide auf width:100%
   und lädt nach unserem Stylesheet — ohne !important gewinnt sonst Jetpack,
   weil wir bislang gar keine width für den Button gesetzt hatten. */
.prose .pushbutton-wide {
  width: auto !important;
  margin-top: 1.1rem;
}

/* [naechster_termin_chip]-Shortcode landet als <a>/<strong> in .prose —
   .prose a/strong (Klasse+Element) schlagen sonst .next-chips eigene
   Farbregel (nur eine Klasse) und der Chip wird auf sich selbst unlesbar. */
.prose .next-chip,
.prose .next-chip:hover,
.prose .next-chip:focus-visible,
.prose .next-chip strong {
  color: var(--on-accent);
}
/* shortcode_unautop entfernt das <p> um den Shortcode, der Chip sitzt also
   als Geschwister zwischen den Absätzen — .prose p + p greift hier nicht,
   der Chip braucht seinen Abstand nach oben und unten selbst. */
.prose .next-chip {
  margin: 1.75rem 0;
}

/* ---------- Akkord-Suche (eingebettetes Tool) ---------- */

.tool-embed {
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.18);
  margin-top: 1.5rem;
  animation: rise 0.7s 0.35s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.tool-embed-bar {
  display: flex;
  justify-content: flex-end;
  border-bottom: 1px solid var(--line);
  padding: 0.6rem 1rem;
}
.tool-embed-link {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-soft);
  text-decoration: none;
}
.tool-embed-link:hover, .tool-embed-link:focus-visible { color: var(--accent); }
.tool-embed-link .arrow { display: inline-block; margin-left: 0.15rem; transition: translate 0.18s ease; }
.tool-embed-link:hover .arrow { translate: 4px 0; }
.tool-embed iframe {
  display: block;
  width: 100%;
  height: min(85vh, 62rem);
  border: 0;
}

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

.termine-layout {
  display: grid;
  gap: 2.5rem clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
@media (min-width: 55rem) {
  .termine-layout { grid-template-columns: 1fr minmax(17rem, 21rem); }
  .termine-layout .termine-col { grid-column: 1; grid-row: 1; }
  .termine-layout .wannwo { grid-column: 2; grid-row: 1; position: sticky; top: 1.5rem; }
  /* Wo der Kopf fest stehen bleibt, klebt der Kasten unter ihm statt unter dem
     Sichtfeldrand — sonst schöbe der Kopf seine Oberkante zu. Dieselbe
     Bedingung wie dort: ohne scroll()-Timeline scrollt der Kopf weg und der
     Kasten braucht nichts (siehe .masthead). Die Admin-Bar zählt mit, weil der
     Kopf selbst unter ihr hängt. width > 55rem (exklusiv), weil der Kopf bei
     exakt 55rem schon wieder mitscrollt (max-width schließt die Grenze ein). */
  @supports (animation-timeline: scroll()) {
    @media (width > 55rem) {
      .termine-layout .wannwo {
        top: calc(var(--wp-admin--admin-bar--height, 0px) + var(--head-compact) + 1.5rem);
      }
    }
  }
}

/* Wann & Wo — Infokasten (Seiteninhalt) neben der Terminliste */
.wannwo {
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(0, 0, 0, 0.18);
  padding: 1.4rem 1.5rem 1.6rem;
  color: var(--text);
  font-size: 0.98rem;
  line-height: 1.55;
  margin-top: 1rem;
  animation: rise 0.7s 0.35s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.wannwo p { margin: 0.6rem 0 0; }
.wannwo h2, .wannwo h3 {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  display: flex; align-items: center; gap: 1rem;
  margin: 1.4rem 0 0.5rem;
}
.wannwo h2::after, .wannwo h3::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.wannwo h2:first-child, .wannwo h3:first-child { margin-top: 0; }
.wannwo strong { color: var(--text-strong); }
.wannwo ul { list-style: none; margin: 0.6rem 0 0; padding: 0; }

/* Mobil startet der Kasten zugeklappt vor der Liste: sichtbar bleiben Label
   und Datum. Aufklappen tut ein Tap irgendwo im Kasten (siehe Script im
   Template), zuklappen nur der Pfeil-Balken an der Unterkante — so bleibt
   aufgeklappter Text markierbar. Der Balken ankert am Kasten (position:
   relative), nicht am <details> — so liegt er in beiden Zuständen unten; das
   Bodenpolster des Kastens hält ihm die Fläche frei. Ab 55rem ist der Kasten
   immer offen und der Balken weg. */
.wannwo { position: relative; }
.wannwo-fold summary {
  list-style: none;
  cursor: pointer;
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2.2rem;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.1rem;
  color: var(--accent);
}
.wannwo-fold summary::-webkit-details-marker { display: none; }
/* Ein Glyph für beide Richtungen — ▾ und ▴ sind je nach Font verschieden
   groß; gedreht bleibt der Pfeil exakt gleich. */
.wannwo-fold summary::after { content: "▾"; transition: rotate 0.25s ease; }
.wannwo-fold[open] summary::after { rotate: 180deg; }
@media (max-width: 55rem) {
  .wannwo { padding-bottom: 2.6rem; }
  /* Zugeklappt ist der ganze Kasten das Tap-Ziel zum Aufklappen. */
  .wannwo:has(.wannwo-fold:not([open])) { cursor: pointer; }
  /* Zugeklappt eine Zeile des Inhalts anschneiden und zur Pfeilzeile hin in den
     Grund ausblenden (Maske: oben deckend, unten durchsichtig) — so wird
     sichtbarer, dass der Kasten mehr birgt. content-visibility überstimmt die
     UA-Vorgabe »hidden«, sonst bliebe der Anschnitt leer. */
  .wannwo-fold:not([open])::details-content {
    height: 2.8rem;
    content-visibility: visible;
    -webkit-mask-image: linear-gradient(to bottom, #000 2rem, transparent);
            mask-image: linear-gradient(to bottom, #000 2rem, transparent);
  }
}
@media (min-width: 55rem) {
  .wannwo-fold summary { display: none; }
  /* Am Desktop immer offen — auch ohne `open`-Attribut, sofern der Browser
     ::details-content kennt; sonst setzt es das Script im Template. */
  .wannwo-fold::details-content { height: auto; content-visibility: visible; }
}

/* Sanft auf-/zuklappen. Browser ohne ::details-content/interpolate-size
   lassen die Regeln fallen und schalten hart um. */
.wannwo-fold { interpolate-size: allow-keywords; }
.wannwo-fold::details-content {
  height: 0;
  overflow: clip;
  transition: height 0.25s ease, content-visibility 0.25s allow-discrete;
}
.wannwo-fold[open]::details-content { height: auto; }

.zeiten { margin: 1.1rem 0 1.3rem; display: grid; gap: 0.35rem; justify-items: start; }
.zeiten div { display: flex; align-items: baseline; gap: 0.5rem; }
.zeiten dt {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--text-soft);
}
.zeiten dt::after { content: ":"; }
.zeiten dd { font-weight: 600; color: var(--text-strong); font-variant-numeric: tabular-nums; }

.ort { font-style: normal; }
.ort strong {
  display: block;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.15rem;
  color: var(--text-strong);
  margin-bottom: 0.15rem;
}

.termine { list-style: none; margin-top: 1rem; padding: 0; animation: rise 0.7s 0.25s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.termine-past { margin-top: 0.25rem; }
/* Wie ein Abschnittstitel, aber im Ton der hellen Überschriften statt der
   Akzent-Versalien der übrigen Section-Labels: Display-Serife in gemischter
   Schreibung, keine Trennlinie. */
.past-label {
  margin-top: 3rem;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.2rem, 2.5vw, 1.45rem);
  letter-spacing: normal;
  text-transform: none;
  color: var(--text-strong);
}
.past-label::after { content: none; }

/* Kopfzeile als hängender Einzug: Zeile 1 beginnt links (Wochentag | Datum |
   Titel); bricht der Titel um, rücken die Folgezeilen auf 4.5rem ein — dieselbe
   Kante wie Motto/Ort und Beschreibung darunter. text-indent hebt den Einzug
   nur für die erste Zeile wieder auf, padding-left setzt die Kante der übrigen.
   Die Pills schwimmen rechts, damit lange Titel unter ihnen weiterlaufen. */
.termin {
  padding: 0.95rem 0.8rem;
  border-top: 1px solid var(--line-soft);
  border-radius: 8px;
  transition: background 0.15s ease;
}
.termin:hover { background: rgba(0, 0, 0, 0.1); }

.termin-head {
  padding-left: 4.5rem;
  text-indent: -4.5rem;
}
.termin-head .wd {
  display: inline-block;
  width: 1.5rem;
  margin-right: 0.35rem;
  font-size: 0.8rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--text-soft);
}
.termin-head .date, .termin-head .title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.2rem, 2.5vw, 1.45rem);
  color: var(--text-strong);
}
.termin-head .date {
  font-variant-numeric: tabular-nums;
}
.termin-head .title {
  margin-left: 0.35rem;
  color: var(--text-firm);
}
.termin-head .note {
  float: right;
  text-indent: 0;
  margin-left: 0.75rem;
  display: flex; flex-wrap: wrap; gap: 0.35rem; justify-content: flex-end;
}

/* Motto/Ort: eine Klartext-Zeile, halb eingerückt unter dem Datum */
.termin-teaser {
  margin: 0.35rem 0 0 4.5rem;
  color: var(--text);
  font-weight: 500;
}
/* Pin-Icon vor dem Ort: Emoji statt gezeichnetem Icon — eindeutig als
   Stecknadel erkennbar, skaliert einfach mit font-size, keine
   Icon-Font/-Datei nötig */
.termin-ort {
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
}
.termin-ort::before {
  content: "📍";
  font-size: 1.15em;
  line-height: 1;
}

.termin-desc {
  margin: 0.5rem 0 0 4.5rem;
  max-width: var(--measure);
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--text);
}
.termin-desc p + p { margin-top: 0.5rem; }
.termin-desc ul, .termin-desc ol { padding-left: 1.2rem; margin: 0.35rem 0 0; }
.termin-desc li + li { margin-top: 0.15rem; }
.termin-desc a { color: var(--accent); }
.termin-desc a:hover { color: var(--accent-hover); }

/* Filter »Alle | Nur Stammtisch-Termine« über der Liste — nur vorhanden, wenn
   es »Sonstiges«-Termine zum Ausblenden gibt (siehe page-templates/termine.php).
   Segmentierter Umschalter im Pill-Vokabular der Badges. */
.termine-filter {
  position: relative;
  display: inline-flex;
  gap: 0.25rem;
  margin-top: 1rem;
  padding: 0.25rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
}
/* Gleitender Hintergrund des aktiven Knopfs; Breite und X-Versatz setzt das
   Script (unterschiedlich breite Labels), Höhe kommt aus top/bottom. */
.termine-filter-thumb {
  position: absolute;
  top: 0.25rem;
  bottom: 0.25rem;
  left: 0.25rem;
  z-index: 0;
  border-radius: 999px;
  background: var(--accent);
}
.termine-filter.is-ready .termine-filter-thumb {
  transition: transform 0.28s cubic-bezier(0.4, 0.8, 0.3, 1),
              width 0.28s cubic-bezier(0.4, 0.8, 0.3, 1);
}
.termine-filter-btn {
  position: relative;
  z-index: 1;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--text-soft);
  font-family: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
  transition: color 0.28s ease;
}
.termine-filter-btn:hover { color: var(--text-strong); }
.termine-filter-btn.is-active { color: var(--on-accent); }

/* Beim Umschalten blendet die Liste kurz aus, wird umsortiert und wieder ein —
   die Neuordnung passiert unsichtbar, kein harter Sprung (siehe termine.php). */
.termine-lists {
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.termine-lists.is-switching {
  opacity: 0;
  transform: translateY(8px);
}

@media (prefers-reduced-motion: reduce) {
  .termine-filter.is-ready .termine-filter-thumb,
  .termine-filter-btn,
  .termine-lists {
    transition: none;
  }
}

.badge {
  /* inline-flex + line-height:1 statt inline-block: sonst erbt der Pill
     body's line-height (1.65) als unsichtbare Zeilenbox und der Text sitzt
     trotz gleicher padding-top/bottom nicht wirklich mittig */
  display: inline-flex;
  align-items: center;
  line-height: 1;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text);
  border: 1.5px solid currentColor;
  border-radius: 999px;
  padding: 0.16rem 0.55rem;
  white-space: nowrap;
}
/* Der Akzent markiert alles, was einen Stammtisch-Termin auszeichnet — ob
   als eigener Pill oder mit »Nächster Termin« kollabiert */
.badge-next, .badge-category {
  color: var(--on-accent);
  background: var(--accent);
  border-color: var(--accent);
}

/* Vergangene Termine treten zurück: Datum UND Titel — die ganze Kopfzeile —
   werden gedämpft, damit ein Termin sichtbar »archiviert« liest und nicht nur
   zur Hälfte. Volle Deckung über die Farbe, nicht über opacity: das ließ
   früher Pills und Text »kaputt« statt vorbei wirken. Ort, Beschreibung und
   Pills bleiben normal lesbar. */
.termin.past .date, .termin.past .title { color: var(--text-faint); }
.termin.next { background: var(--bg-sunk); border-top-color: transparent; box-shadow: inset 0 0 0 1.5px var(--accent); }
.termin.next .date { color: var(--accent); }

/* ---------- Seitenleiste ---------- */

/* Die Leiste setzt sich als eigene Fläche vom Grund ab — wie die Bildkästen
   und der nächste Termin, und wie dort nach unten (--bg-sunk) statt nach
   oben: ein heller Schleier auf dem Grund kostet Kontrast, den der Text
   hier nicht übrig hat. Auf der dunkleren Fläche steht --text-soft sogar
   etwas besser als im Fließtext daneben. */
#secondary {
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text-soft);
  background: var(--bg-sunk);
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  padding: 1.1rem 1.25rem;
  /* Einspurig steht die Leiste unter dem Text; nebeneinander (siehe
     Responsiv-Block) fällt der Abstand weg. */
  margin-top: 2.5rem;
  animation: rise 0.7s 0.35s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.widget + .widget {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-soft);
}

/* Block-Widgets (der einzige Weg im heutigen Widget-Editor) kennen kein
   before_title — ihre Überschrift kommt als Überschriftsblock. */
.widget-title,
.widget .wp-block-heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.05rem;
  line-height: 1.25;
  color: var(--text-strong);
  margin-bottom: 0.6rem;
  text-wrap: balance;
}

.widget a { color: var(--accent); }
.widget a:hover, .widget a:focus-visible { color: var(--accent-hover); }
.widget p + p { margin-top: 0.7rem; }
.widget strong { color: var(--text); }

/* Widget-Listen (Seiten, Kategorien, letzte Beiträge) tragen die Aufzählung
   im Zeilenabstand, nicht im Punkt davor — der stünde in der schmalen Spur
   nur im Weg. */
.widget ul { list-style: none; }
.widget li + li { margin-top: 0.5rem; }
.widget ul ul { margin-top: 0.5rem; padding-left: 0.9rem; }

.widget img { border-radius: 8px; }

/* Das Feld sitzt auf --bg-sunk und darf sich davon nicht noch einmal
   abheben — der Grund der Seite ist hier heller als die Fläche darunter. */
.widget input[type="search"],
.widget input[type="text"] {
  width: 100%;
  font: inherit;
  color: var(--text-strong);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.5rem 0.7rem;
}
.widget label { display: block; margin-bottom: 0.4rem; }

/* Der Pill aus dem Fließtext (dort mitselektiert), nur enger: 2.2rem
   Polsterung sprengten die 15rem der Leiste. */
.widget button,
.widget input[type="submit"] {
  margin-top: 0.5rem;
  font-size: 0.875rem;
  padding: 0.5rem 1.3rem;
}

/* Der Suchen-Block setzt Feld und Knopf per Flex nebeneinander — in der
   schmalen Spur stapeln sie wie das klassische Suchformular. */
.widget .wp-block-search__inside-wrapper { display: block; }
.widget .wp-block-search__button { margin-left: 0; }

/* ---------- Fußzeile mit Skyline ---------- */

.site-footer { margin-top: auto; }
/* Silhouette und Band tragen dieselbe Farbe — die Skyline ist die Oberkante
   des Bandes. Schwarz statt Akzentfarbe: gegen den Seitengrund trüge der
   Akzent allein den Farbton, kaum Helligkeit — die Kontur verschwämme.
   Schwarz ist zudem die Kontur der Logo-Grafik. */
.skyline { color: var(--frame); margin-bottom: -1px; }
.skyline svg { display: block; width: 100%; height: auto; min-height: 3.5rem; }

.footer-band { background: var(--frame); color: var(--text); }
.footer-inner {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem 2rem; flex-wrap: wrap;
  padding: 1.6rem 0 1.4rem;
}
.footer-brand {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.05rem;
  color: var(--text-strong);
  text-decoration: none;
}
.footer-brand em { font-style: normal; color: var(--accent); }
.footer-nav ul {
  display: flex; gap: 0.3rem 1.6rem; flex-wrap: wrap;
  list-style: none; margin: 0; padding: 0;
}
.footer-nav a {
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text);
  padding-bottom: 0.4rem;
}
.footer-nav a:hover, .footer-nav a:focus-visible { color: var(--text-strong); }

.footer-legal {
  padding: 0.9rem 0 1.8rem;
  margin-top: 0.7rem;
  border-top: 1px solid rgba(206, 206, 206, 0.22);
  display: flex; gap: 1.2rem; flex-wrap: wrap; justify-content: flex-end;
  font-size: 0.72rem;
  color: var(--text);
}
.footer-legal a { color: inherit; }
.footer-legal a:hover, .footer-legal a:focus-visible { color: var(--text-strong); }

/* ---------- Animationen ---------- */

@keyframes rise {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

/* ---------- Responsiv ---------- */

/* Nebeneinander erst, wenn neben der Leiste eine lesbare Textspalte bleibt:
   unter ~60rem unterschritte der Text seine Zeilenbreite (--measure), noch
   bevor die Leiste selbst zu schmal wird. */
@media (min-width: 60rem) {
  .has-sidebar .content-grid {
    grid-template-columns: minmax(0, var(--wrap-narrow-w)) var(--aside-w);
    column-gap: var(--aside-gap);
  }
  .has-sidebar #secondary { margin-top: 0; }
}

@media (max-width: 44rem) {
  .next-chip { font-size: 0.875rem; padding: 0.6rem 1.1rem; }
  .entry { grid-template-columns: 1fr; gap: 1rem; }
  .stamp { rotate: -1.5deg; }
  /* wenig Breite zu verschenken: hängenden Einzug und Teaser/Beschreibung
     bündig nach links, Pills dürfen unter wd+Datum umbrechen */
  .termin-head { padding-left: 0; text-indent: 0; }
  .termin-teaser, .termin-desc { margin-left: 0; }
  /* .badge { white-space: nowrap } gilt nur ab Desktop-Breite (siehe oben);
     auf schmalen Screens darf der Pill-Text selbst umbrechen statt den
     Termin-Kopf zu sprengen */
  .badge { white-space: normal; }
}

/* Kopf, Grafik, Verlauf und Menü sind ausgenommen: ihre Animation ist keine
   Bewegung um ihrer selbst willen, sondern trägt das Layout — ohne sie bliebe
   der feste Kopf auf Ruhehöhe stehen und fräße dauerhaft das halbe Sichtfeld.
   Sie folgt ohnehin nur dem Scrollen, läuft also nie von selbst los.
   Das ::before des Kopfes braucht eine eigene Ausnahme: :not() greift am
   Element, nicht am Pseudoelement. */
@media (prefers-reduced-motion: reduce) {
  *:not(.masthead, .site-title a, .masthead .nav),
  *:not(.masthead)::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}
