/*
 * GEDO Theme
 * Farben/Wappen/Oder-Foto an die bisherige Joomla-Seite (gedo-seelow.de,
 * Stand Wayback-Archiv 2026-05-14) angelehnt, sonst komplett neu:
 * kein Tailwind-/Google-Fonts-CDN (DSGVO: keine Drittanbieter-Requests),
 * System-Font-Stack, eigenes CSS mit Custom Properties.
 *
 * Bewusst KEIN prefers-color-scheme: dark: das Original ist ein durchgehend
 * helles, papierartiges Institutions-Design ohne Dark-Variante. Ein
 * automatischer Dark-Mode-Wechsel wuerde bei Besuchern mit dunklem
 * System-Theme genau die angestrebte "an die alte Seite angelehnt"-Optik
 * zerstoeren (sah in der Praxis fast schwarz/komplett anders aus).
 */

:root {
	color-scheme: light;
	--gedo-navy: #0f3d63;
	--gedo-navy-dark: #082944;
	/* Aus dem Logo (public/theme/img/crest.png) per ImageMagick ausgelesenes
	   Gold (#E2BB42) statt des vorherigen, nicht logo-bezogenen Gruens
	   (Kunden-Feedback: Farbkonzept soll auf den Logo-Farben aufbauen).
	   --gedo-accent (das helle Gold) ist NUR fuer Flaechen/Fuellungen gedacht,
	   auf denen dunkler (Navy-)Text sitzt - als Fliesstext-Farbe auf Weiss
	   faellt reines Gold unter WCAG-AA (Kontrast 1,84:1). --gedo-accent-dark
	   ist ein abgedunkeltes Gold speziell fuer Text auf Weiss bzw. weissen
	   Text auf goldenem Grund (beide De 4,5:1/5,07:1, AA-konform) - siehe
	   a:hover/.read-more weiter unten. */
	--gedo-accent: #e2bb42;
	--gedo-accent-dark: #8c6914;
	--gedo-sky: #eaf4fb;
	--gedo-surface: #ffffff;
	--gedo-text: #262b30;
	--gedo-text-muted: #5b6570;
	--gedo-border: #dfe6ec;
	--gedo-radius: 12px;
	--gedo-shadow: 0 2px 14px rgba(15, 61, 99, 0.08);
	--gedo-font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	/* Nur fuer Ueberschriften (siehe @font-face unten + h1-h3/.brand/... weiter
	   unten) - Fliesstext bleibt bewusst auf dem schnellen System-Font-Stack
	   (--gedo-font), das ist nicht das, was beim Vergleich mit der
	   Referenz-Seite "lam" wirkte. Kunden-Feedback: Ueberschriften sollen
	   kraeftiger/praesenter wirken (Referenz nutzt Open Sans, Schriftschnitt
	   900 - Systemschriften bieten selten einen echten, nicht kuenstlich
	   verfetteten so schweren Schnitt). */
	--gedo-heading-font: "Open Sans", var(--gedo-font);
	--gedo-max-width: 1120px;
	/* Fallback, bevor hero-parallax.js die tatsaechliche Hoehe misst (siehe
	   dort) - der Header ist jetzt position: fixed und schwebt ueber dem
	   Jumbotron, der Titel-Text im Hero braucht also entsprechend Abstand
	   von oben, um nicht dahinter zu verschwinden. */
	--gedo-header-height: 70px;
}

/* Selbst gehostet (Open Sans, Apache-2.0/OFL, einmalig von Google
   heruntergeladen - gleiches Vorgehen wie die Material-Symbols-Icons in
   public/locker/assets/vendor/material-symbols/), kein Nachladen von
   fonts.googleapis.com/fonts.gstatic.com im Browser der Besucher - siehe
   Datenschutzerklaerung (public/content/pages/impressum.md), dort
   entsprechend aktualisiert. Nur der "latin"-Subset (deckt deutsche
   Umlaute/ß bereits ab, U+0000-00FF) - kein kyrillisch/griechisch/etc.
   noetig. Eine Datei deckt 700-800 ab (von Google selbst so ausgeliefert,
   vermutlich ein intern variables File) - font-weight als Bereich
   deklariert, verwendet wird ueberwiegend 800. */
@font-face {
	font-family: "Open Sans";
	font-style: normal;
	font-weight: 700 800;
	font-display: swap;
	src: url("fonts/open-sans-bold.woff2") format("woff2");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122;
}

* { box-sizing: border-box; }

/* Ohne dieses Reset rendern manche Browser/Desktop-Themes (v.a. unter Linux
   mit GTK-Theming) <button> weiterhin mit nativer Chrome-Optik (Grauverlauf,
   sichtbarer 3D-Rand) OBEN AUF/durchscheinend durch jede selbst gesetzte
   Hintergrundfarbe - eigene Farben (z.B. der aktive Zustand der GEDO-
   Kartenfilter) verschwinden dadurch praktisch unsichtbar hinter der
   nativen Optik. appearance:none nimmt den Button komplett aus dem
   nativen Theming raus, nur noch unser eigenes CSS zaehlt. */
button {
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
	font-family: inherit;
}

body {
	margin: 0;
	font-family: var(--gedo-font);
	color: var(--gedo-text);
	background: var(--gedo-sky);
	line-height: 1.6;
	/* Deutsche Komposita ("Gewässerunterhaltungspläne") koennen sehr lang
	   und ohne jede Umbruch-Stelle (Leerzeichen/Bindestrich) sein - ohne das
	   liess der Browser so ein einzelnes Wort lieber die Seite seitlich
	   aufbrechen, als es (als letzten Ausweg) mitten im Wort umzubrechen. */
	overflow-wrap: break-word;
	/* hyphens:auto (erbt an alle Nachfahren, hyphens ist eine vererbte
	   Eigenschaft) nutzt html[lang="de"] fuer echte, sprachrichtige
	   Trennstellen statt des harten break-word-Nur-Notnagels oben - wichtig
	   v.a. im Blocksatz (z.B. .section-tile p): ohne Trennung reisst der
	   Browser dort lange Woerter ganz in die naechste Zeile statt sie zu
	   trennen, was die Wortabstaende in der aktuellen Zeile unschoen
	   auseinanderzieht. */
	hyphens: auto;
	-webkit-hyphens: auto;
}

/* Frueher: dezentes, verwaschenes Foto (background-river.jpg) als
   sitewide Hintergrundtextur hinter allen Karten/Inhalten. Kunden-Feedback
   beim Vergleich mit der Referenz-Seite (gwv-sonnewalde.de): wirkt neben
   deren klarem, flaechigem Hintergrund "lamer"/unruhig - deshalb entfernt,
   body bleibt bei der reinen --gedo-sky-Flaeche (siehe body{background}
   oben). .card/article.single/.home-tile hatten dafuer extra einen
   Frosted-Glass-Look (halbtransparent + backdrop-filter), der nur mit
   dieser Foto-Textur dahinter einen Sinn ergab - beide jetzt auf einfaches,
   deckendes Weiss zurueckgestellt (siehe dortige Regeln). */

a { color: var(--gedo-navy); text-decoration: none; }
a:hover { color: var(--gedo-accent-dark); text-decoration: underline; }

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

/* Ueberschriften ueberall (auch redaktionell in prose-content, z.B. "##" im
   Markdown) auf der kraeftigeren Ueberschriften-Schrift statt der System-
   Schrift des Fliesstexts - einzelne Stellen (.hero h1, .card h2, ...)
   setzen darauf aufbauend nur noch Groesse/Zeilenabstand je Kontext. */
h1, h2, h3, h4, h5, h6 {
	font-family: var(--gedo-heading-font);
	font-weight: 800;
	letter-spacing: -0.01em;
	line-height: 1.15;
	/* hyphens:auto kommt (vererbt) schon von body, siehe dortiger
	   Kommentar - hier nichts Eigenes mehr noetig. */
}

.container {
	max-width: var(--gedo-max-width);
	margin: 0 auto;
	padding: 0 20px;
}

.sr-only {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
.skip-link:focus {
	position: fixed;
	top: 8px; left: 8px;
	width: auto; height: auto;
	background: var(--gedo-navy);
	color: #fff;
	padding: 10px 16px;
	border-radius: var(--gedo-radius);
	z-index: 1000;
}

/* Header / Navigation
   ------------------------------------------------------------------ */
/* position: fixed statt sticky: sticky wuerde weiterhin seine eigene Flow-
   Hoehe belegen und das Jumbotron dadurch nach unten schieben - der Wunsch
   war aber, dass das (frosted, halbtransparente) Menue schon beim ersten
   Aufruf ohne Scrollen ueber das Bild ragt. Mit fixed nimmt der Header
   keinen Platz im Dokumentfluss mehr ein, das Hero-Bild rutscht dadurch bis
   ganz nach oben (siehe .hero, keine Aenderung noetig) und der Header
   schwebt von Anfang an darueber.
   ------------------------------------------------------------------ */
.site-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
	background: var(--gedo-surface);
	border-bottom: 1px solid var(--gedo-border);
}
/* Frosted-Glass-Look nur, wenn der Browser backdrop-filter unterstuetzt -
   sonst bleibt es beim deckenden Weiss oben (Fallback, kein kaputtes
   Halbtransparent-ohne-Blur). */
/* Der Effekt liegt auf einem ::before statt auf dem <header> selbst: ein
   Element mit backdrop-filter wird "Backdrop Root", und ein Element darin
   mit eigenem backdrop-filter (das Aufklappmenue, .site-subnav) saehe dann
   nur den Header-Inhalt statt der Seite dahinter - es waere durchsichtig,
   aber nicht weichgezeichnet. */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
	.site-header {
		background: none;
		border-bottom: 1px solid rgba(255, 255, 255, 0.35);
	}
	/* .site-header davor: die Grundregel fuer .site-subnav::before steht
	   weiter unten und wuerde bei gleicher Spezifitaet gewinnen. */
	.site-header::before,
	.site-header .site-nav .site-subnav::before {
		background: rgba(255, 255, 255, 0.55);
		-webkit-backdrop-filter: blur(14px) saturate(160%);
		backdrop-filter: blur(14px) saturate(160%);
	}
	.site-header::before {
		content: '';
		position: absolute;
		inset: 0;
		z-index: -1;
	}
	.site-header .site-nav .site-subnav::before {
		border-color: rgba(255, 255, 255, 0.35);
	}
}

.site-header .bar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 12px 20px;
}

.brand {
	display: flex;
	align-items: center;
	gap: 12px;
	font-family: var(--gedo-heading-font);
	font-weight: 800;
	font-size: 1.2rem;
	color: var(--gedo-navy);
}
.brand:hover { color: var(--gedo-navy); text-decoration: none; }
.brand img { height: 44px; width: auto; }
.brand .slogan {
	display: block;
	font-size: 0.72rem;
	font-weight: 400;
	color: var(--gedo-text-muted);
}

.nav-toggle {
	display: none;
	background: none;
	border: 1px solid var(--gedo-border);
	border-radius: 8px;
	padding: 8px 10px;
	cursor: pointer;
	color: var(--gedo-navy);
}

.site-nav ul {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	margin: 0;
	padding: 0;
}

.site-nav a {
	display: inline-block;
	padding: 8px 12px;
	border-radius: 8px;
	color: var(--gedo-text);
	font-weight: 500;
	font-size: 0.95rem;
}
.site-nav a:hover,
.site-nav a.active {
	background: var(--gedo-sky);
	color: var(--gedo-navy);
	text-decoration: none;
}

/* Unterpunkte (PageStore::mainMenu(), "parent"): Dropdown beim Ueberfahren
   bzw. per Tastatur (:focus-within), in derselben Milchglas-Optik wie die
   Kopfzeile und direkt an deren Unterkante. Dafuer ist das <li> bewusst NICHT
   positioniert: das Dropdown richtet sich vertikal an .site-header aus
   (top: 100% = Unterkante der Kopfzeile), horizontal bleibt es an seiner
   natuerlichen Stelle unter dem Hauptpunkt (left: auto). Das obere,
   durchsichtige padding reicht bis in den Hauptpunkt hinein, damit die Maus
   auf dem Weg nach unten nicht durch eine Luecke faellt und es sich
   schliesst. */
.site-nav .has-children > a::after {
	content: '';
	display: inline-block;
	margin-left: 6px;
	border: 4px solid transparent;
	border-top: 5px solid currentColor;
	border-bottom: 0;
	vertical-align: middle;
	opacity: 0.6;
}
.site-nav .site-subnav {
	display: none;
	position: absolute;
	top: calc(100% - 18px);
	left: auto;
	z-index: 110;
	min-width: 220px;
	flex-direction: column;
	gap: 0;
	padding: 18px 0 0;
}
.site-nav .site-subnav::before {
	content: '';
	position: absolute;
	inset: 18px 0 0;
	z-index: -1;
	background: var(--gedo-surface);
	border: 1px solid var(--gedo-border);
	border-top: none;
	border-radius: 0 0 10px 10px;
	box-shadow: 0 10px 24px rgba(15, 61, 99, 0.10);
}
.site-nav .site-subnav li { padding: 0 6px; }
.site-nav .site-subnav li:first-child { padding-top: 6px; }
.site-nav .site-subnav li:last-child { padding-bottom: 6px; }
.site-nav .site-subnav a { display: block; white-space: nowrap; }
.site-nav .has-children:hover > .site-subnav,
.site-nav .has-children:focus-within > .site-subnav { display: flex; }

@media (max-width: 800px) {
	.nav-toggle { display: inline-flex; align-items: center; gap: 6px; }
	.site-nav {
		display: none;
		width: 100%;
		border-top: 1px solid var(--gedo-border);
	}
	.site-nav.open { display: block; }
	.site-nav ul { flex-direction: column; padding: 8px 0; }
	/* Handy: kein Hover - Unterpunkte immer sichtbar, eingerueckt. */
	.site-nav .site-subnav { display: flex; position: static; min-width: 0; padding: 0 0 0 16px; }
	.site-nav .site-subnav::before { display: none; }
	.site-nav .site-subnav li { padding: 0; }
	.site-nav .has-children > a::after { display: none; }
	.site-header .bar { flex-wrap: wrap; }
}

/* Jumbotron: auf jeder Seite gleich, Foto mit Parallax. background-attachment:
   fixed (erster Versuch) ist browseruebergreifend unzuverlaessig - iOS Safari
   ignoriert es komplett, Chrome/Firefox brechen es teils ab, sobald ein
   Vorfahre einen eigenen Compositing-Layer erzeugt. Stattdessen bewegt
   hero-parallax.js das Bild per transform: translateY(), gesteuert ueber die
   CSS-Variable --hero-parallax-y (Fallback 0px ohne JS/bei
   prefers-reduced-motion). Das Bild ist oben/unten ueber den Rand hinaus
   ("Bleed") positioniert, damit die Verschiebung nie eine leere Kante
   freilegt - der sichtbare Ausschnitt wird durch overflow: hidden auf .hero
   gekappt.
   Text lag vorher direkt auf dem Foto (nur weisser Schein als Kontrast) -
   das versagt sobald der Fotohintergrund an der Textstelle nicht hell ist
   (z.B. die Bruecken-Stahltraeger). Ein dunkler Scrim-Gradient (::after,
   oben staerker, wo der Text sitzt) plus weisse Schrift ist unabhaengig
   vom Bildinhalt lesbar. Bewusst neutral dunkel statt blau gehalten (siehe
   frueheres Feedback "sehr blau").
   ------------------------------------------------------------------ */
.hero {
	position: relative;
	height: 400px;
	overflow: hidden;
	display: flex;
	align-items: flex-start;
}
.hero::before {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	top: -160px;
	bottom: -160px;
	background: var(--gedo-hero-image, url('img/hero-startseite.jpg')) center/cover no-repeat;
	transform: translateY(var(--hero-parallax-y, 0px));
	will-change: transform;
}
.hero::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(8, 20, 32, 0.6) 0%, rgba(8, 20, 32, 0.25) 60%, rgba(8, 20, 32, 0.1) 100%);
}
.hero .container {
	position: relative;
	z-index: 1;
	max-width: var(--gedo-max-width);
	/* + --gedo-header-height: der Header liegt jetzt (position: fixed) von
	   Anfang an ueber dem Jumbotron, der Titel muss also darunter beginnen
	   statt direkt am oberen Bildrand. */
	padding-top: calc(var(--gedo-header-height) + 34px);
	text-align: center;
	width: 100%;
}
.hero h1 {
	margin: 0 0 10px;
	font-size: clamp(2rem, 5vw, 3.4rem);
	font-weight: 800;
	color: #fff;
	text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}
.hero p {
	margin: 0;
	color: #fff;
	font-size: 0.95rem;
	text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}
@media (max-width: 640px) {
	.hero { height: 200px; }
	.hero .container { padding-top: calc(var(--gedo-header-height) + 20px); }
}
@media (prefers-reduced-motion: reduce) {
	.hero::before { transform: none; }
}

/* Content
   ------------------------------------------------------------------ */
main { display: block; padding: 40px 0 64px; }
/* Kein Hero auf dieser Seite (siehe theme/header.php, $showHero): nur noch
   so viel Platz oben, wie der fixe Header hoch ist (--gedo-header-height,
   von hero-parallax.js live gemessen) - sonst bliebe eine sichtbare Luecke
   zwischen Navigation und Inhalt (z.B. der randlosen GEDO-Karte), obwohl
   gar kein Hero mehr da ist, der diese Luecke rechtfertigen wuerde. */
main.no-hero { padding-top: var(--gedo-header-height); }

/* Auto-fill-Grid statt einer einzelnen Spalte: bei ausreichender Breite
   stehen mehrere Karten nebeneinander (min. 280px je Karte), auf schmalen
   Bildschirmen faellt es von selbst auf eine Spalte zurueck - kein extra
   Media-Query noetig. */
.page-list {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 24px;
}

/* Einfache, deckende Karten (frueher Frosted-Glass ueber der jetzt entfernten
   sitewide Foto-Textur, siehe body::before-Kommentar oben - ohne die Textur
   ergibt Halbtransparenz keinen Sinn mehr). */
.card, article.single {
	background: var(--gedo-surface);
	border: 1px solid var(--gedo-border);
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
}
article.single { padding: 28px 30px; }

/* Seiten mit eigenem Hero-Foto (siehe index.php: hero === "custom") zeigen
   Titel/Unterzeile bereits im Foto - der Intro-Text braucht dann keine
   zusaetzliche Karten-Optik mehr, sonst wirkt er wie eine zweite, unnoetige
   Box direkt unter dem Foto (Kunden-Feedback, Referenz-Seite zeigt den Text
   dort frei auf dem Seitenhintergrund). */
article.single.single-plain {
	background: none;
	border: none;
	box-shadow: none;
	border-radius: 0;
	padding: 36px 0 8px;
}

/* Material-Design-Card-Look (User-Wunsch, Vorbild Material-Design-Karten-
   Beispiele): Bild randlos ganz oben, darunter ein gepolsterter Textblock
   mit Titel/Auszug/Aktion. .card selbst bleibt padding-los (das Bild soll
   die Kartenkanten beruehren), .card-body traegt den Innenabstand. */
.card {
	display: flex;
	flex-direction: column;
	overflow: hidden;
}
.card-thumb {
	display: block;
	aspect-ratio: 16 / 9;
	overflow: hidden;
}
.card .card-thumb img {
	/* ".card " davor: reine Spezifitaets-Erhoehung, kein Verschachtelungs-
	   Zwang - ".card-thumb img" hat dieselbe Spezifitaet wie ".prose-content
	   img" weiter unten in dieser Datei, wodurch dessen margin/border auf
	   dem Karten-Thumbnail landete (spaeter in der Kaskade gewinnt bei
	   Gleichstand). Mit ".card" davor ist die Regel spezifischer und gewinnt
	   unabhaengig von der Reihenfolge. */
	width: 100%;
	height: 100%;
	object-fit: cover;
	margin: 0;
	border: none;
	border-radius: 0;
	box-shadow: none;
}
.card-body {
	padding: 20px 22px 22px;
	display: flex;
	flex-direction: column;
	flex: 1;
}

.card h2 {
	margin: 0 0 8px;
	font-size: 1.25rem;
}
.card h2 a { color: var(--gedo-navy); }

.meta {
	font-size: 0.85rem;
	color: var(--gedo-text-muted);
	margin-bottom: 10px;
}

.excerpt { color: var(--gedo-text); flex: 1; }

.card-actions { margin-top: 18px; }
.read-more {
	display: inline-block;
	font-size: 0.8rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--gedo-accent-dark);
}
.read-more:hover { text-decoration: underline; }

article.single h1 {
	color: var(--gedo-navy);
	font-size: clamp(1.8rem, 3.5vw, 2.6rem);
	margin: 0 0 16px;
}

/* Redakteure duerfen im Editor formatieren (fett/kursiv/Listen/Tabellen),
   aber weder eingefuegter Inhalt (Copy-Paste aus Word/Google Docs bringt
   oft eigene font-family/color als Inline-Style mit) noch altes,
   migriertes Joomla-Markup (das teils genau solche Inline-Styles enthaelt,
   siehe z.B. die Bibermanagement-Seite) sollen das Website-Design
   ueberschreiben koennen. !important gewinnt hier bewusst gegen JEDE
   Inline-style-Angabe auf einem einzelnen Element - "der Style der Website
   hat immer Vorrang" ist damit keine Konvention mehr, sondern erzwungen. */
.prose-content, .prose-content * {
	font-family: var(--gedo-font) !important;
	color: inherit !important;
}
/* !important hier ebenfalls noetig: sonst wuerde die eigene !important-Regel
   oben (die jedes Inline-style ueberstimmen soll) versehentlich auch diese
   bewusst gesetzten Design-Farben (Navy fuer Ueberschriften/Links) mit
   ueberschreiben - !important schlaegt IMMER normale Regeln, unabhaengig
   von Spezifitaet, deshalb muss die gewollte Ausnahme das gleiche Gewicht
   bekommen. */
.prose-content :is(h2, h3) { color: var(--gedo-navy) !important; }
.prose-content a { color: var(--gedo-navy) !important; text-decoration: underline; }
/* Plain "![alt](url)"-Markdown traegt keine Groessenangabe mehr (anders als
   die migrierten <img width="..." height="...">-Tags vorher) - ohne Deckel
   rendert jedes Bild in seiner tatsaechlichen Pixelgroesse, was bei den sehr
   unterschiedlichen Quellbildern (kleine Buerofotos neben 3000px-Aufnahmen)
   wild/uneinheitlich aussieht. max-width + zentriert + dezenter Rahmen
   sorgt fuer ein einheitliches Bild unabhaengig von der Quellaufloesung. */
.prose-content img {
	/* min() statt eines festen max-width: 480px - sonst blieb das Bild auf
	   schmalen (Mobile-)Viewports bei voller 480px-Breite und brach seitlich
	   aus Karte/Container/Viewport aus, weil die konkretere Klassenregel die
	   globale "img { max-width: 100% }" (siehe oben) einfach ueberschreibt.
	   min(480px, 100%) begrenzt gleichzeitig nach oben (Desktop) UND nach
	   unten auf die tatsaechliche Containerbreite (Mobile). */
	max-width: min(480px, 100%);
	border-radius: var(--gedo-radius);
	border: 1px solid var(--gedo-border);
	margin: 16px auto;
	box-shadow: var(--gedo-shadow);
}

/* Klick-zum-Vergroessern (siehe theme/image-lightbox.js): die Klasse wird
   dort automatisch nur auf Bilder gesetzt, deren tatsaechliche Aufloesung
   groesser ist als die oben gedeckelte Anzeigegroesse - kein manuelles
   Markieren beim Hochladen noetig. */
.prose-content img.is-zoomable { cursor: zoom-in; }

.image-lightbox {
	position: fixed;
	inset: 0;
	z-index: 2000;
	align-items: center;
	justify-content: center;
	background: rgba(15, 23, 32, 0.9);
	padding: 24px;
	cursor: zoom-out;
}
/* :not([hidden]) noetig, sonst gewinnt unser "display: flex" gegen die
   UA-Regel "[hidden] { display: none }" bei Gleichstand (siehe Kommentar
   bei .inplace-fab-menu weiter unten - gleiches Problem). */
.image-lightbox:not([hidden]) { display: flex; }
.image-lightbox-img {
	max-width: 92vw;
	max-height: 92vh;
	object-fit: contain;
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
	cursor: default;
}
.image-lightbox-close {
	position: fixed;
	top: 20px;
	right: 20px;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	border: none;
	background: rgba(255, 255, 255, 0.15);
	color: #fff;
	font-size: 1.6rem;
	line-height: 1;
	cursor: pointer;
}
.image-lightbox-close:hover { background: rgba(255, 255, 255, 0.3); }

body.image-lightbox-open { overflow: hidden; }

/* display: block + overflow-x: auto macht die Tabelle selbst zum
   Scroll-Container (Zeilen/Zellen bleiben trotzdem table-row/-cell, Browser
   behalten deren Default-Display auch wenn das <table> block wird) - ohne
   das sprengten die migrierten Tabellen (4+ Spalten, teils lange
   unbrechbare Inhalte, siehe die ~46 Schöpfwerk-Infoboxen) die Seite auf
   schmalen Bildschirmen seitlich, statt nur innerhalb der Tabelle zu
   scrollen. */
.prose-content table {
	display: block;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	/* !important: viele der migrierten Tabellen tragen noch ihr Original-
	   Inline-"style=\"width: 801px\"" (siehe Klassenkommentar oben zu
	   .prose-content, .prose-content * - gleicher Grund) - das schlaegt eine
	   normale Regel und war der eigentliche Grund, warum die Tabelle trotz
	   "overflow-x: auto" die ganze Seite aufgebrochen hat statt nur intern zu
	   scrollen: der Browser hat schlicht nie unser width:100% angewendet. */
	width: 100% !important;
	max-width: 100% !important;
	border-collapse: collapse;
	margin: 16px 0;
}
.prose-content th, .prose-content td {
	border: 1px solid var(--gedo-border);
	padding: 8px 10px;
	text-align: left;
	white-space: nowrap;
}

.breadcrumb {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	list-style: none;
	margin: 0 0 20px;
	padding: 0;
	font-size: 0.85rem;
	color: var(--gedo-text-muted);
}
.breadcrumb li:not(:last-child)::after { content: '/'; margin-left: 6px; }

.tags {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 24px;
	padding-top: 20px;
	border-top: 1px solid var(--gedo-border);
}
.tag {
	font-size: 0.78rem;
	font-weight: 600;
	padding: 4px 10px;
	border-radius: 999px;
	background: var(--gedo-sky);
	color: var(--gedo-navy);
}

.pagination {
	display: flex;
	justify-content: space-between;
	margin-top: 32px;
	padding-top: 20px;
	border-top: 1px solid var(--gedo-border);
	font-weight: 600;
}

.back-link { display: inline-block; margin-top: 28px; font-weight: 600; }

.not-found { text-align: center; padding: 60px 0; }
.not-found .code {
	font-size: 4rem;
	font-weight: 800;
	color: var(--gedo-border);
	margin: 0;
}

/* Footer
   ------------------------------------------------------------------ */
.site-footer {
	background: var(--gedo-navy-dark);
	color: rgba(255, 255, 255, 0.85);
	margin-top: 40px;
}
.site-footer .container {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: space-between;
	align-items: center;
	padding: 24px 20px;
	font-size: 0.85rem;
}
.site-footer a { color: #fff; text-decoration: underline; }
.site-footer .footer-links { display: flex; gap: 16px; }
.site-footer p { margin: 0; }

/* Schnellzugriff-FAB fuer eingeloggte Redakteure (siehe $canEdit in
   public/index.php) - verlinkt nur noch ins Backend (locker/edit.php etc.),
   kein Inline-Editing mehr auf den oeffentlichen Seiten (Abschnitte lassen
   sich ohnehin nur dort pflegen). z-index bewusst deutlich ueber .site-header
   (100, siehe oben) - beides sind eigene Stacking-Contexts auf Root-Ebene
   (position: fixed direkt unter <body>), ohne genuegend Abstand landet der
   FAB sonst hinter dem (halbtransparenten) Frosted-Glass-Header. */
.inplace-fab {
	position: fixed;
	right: 20px;
	bottom: 20px;
	z-index: 500;
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 10px;
}
.inplace-fab-main {
	width: 56px;
	height: 56px;
	border-radius: 50%;
	border: none;
	background: var(--gedo-navy);
	color: #fff;
	font-size: 1.4rem;
	line-height: 1;
	cursor: pointer;
	box-shadow: var(--gedo-shadow);
}
.inplace-fab-main:hover { background: var(--gedo-navy-dark); }
.inplace-fab-main.is-open { background: var(--gedo-navy-dark); }

.inplace-fab-menu {
	flex-direction: column;
	align-items: stretch;
	gap: 6px;
	background: var(--gedo-surface);
	border: 1px solid var(--gedo-border);
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
	padding: 8px;
	min-width: 220px;
}
.inplace-fab-menu-item {
	display: block;
	padding: 10px 12px;
	border-radius: 8px;
	border: none;
	background: transparent;
	color: var(--gedo-text);
	font-size: 0.9rem;
	text-align: left;
	text-decoration: none;
	cursor: pointer;
	white-space: nowrap;
}
.inplace-fab-menu-item:hover { background: var(--gedo-sky); }

/* [hidden] hat dieselbe Spezifitaet (0-1-0) wie eine Klasse - ohne
   :not([hidden]) hier wuerde unser eigenes "display: flex" die
   UA-Stylesheet-Regel "[hidden] { display: none }" ueberstimmen (spaeter im
   Stylesheet = gewinnt bei Gleichstand) und das Element bliebe trotz
   hidden-Attribut sichtbar UND klickbar (fing echte Klicks auf den
   dahinterliegenden FAB-Button ab - per Playwright-Test gefunden). */
.inplace-fab-menu:not([hidden]) {
	display: flex;
}

/* Seitenweite Abschnitte (Sections, theme/sections.php)
   ------------------------------------------------------------------ */
.home-intro { margin-bottom: 36px; }

/* Ein Abschnitt = volle Breite (gleicher "Full Bleed"-Trick wie
   .gedo-map-shell in gedo-site.css: 100vw + negative Raender um die Haelfte
   der Differenz zur 50%-Position), Inhalt darin wieder auf --gedo-max-width
   zentriert (.page-section-inner nutzt die bestehende .container-Klasse).
   Ohne eigenes Hintergrundbild wechseln sich Abschnitte per Zebra-Musters ab
   (Kunden-Wunsch) statt alle gleich auszusehen; MIT Bild (aus der
   Mediathek) zeigt es das Bild direkt (kein Abdunkel-Overlay - bewusst
   einfach gehalten, die Redaktion waehlt ein zum eigenen Text passendes
   Bild, wie beim Hero schon heute). */
.page-section {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
	padding: 56px 0;
}
.page-section-odd { background: var(--gedo-surface); }
.page-section-even { background: var(--gedo-sky); }
/* Hintergrundbild liegt (wie beim Hero, siehe .hero::before) auf einem
   ueberstehenden ::before statt direkt als background-image auf dem
   Abschnitt selbst - nur so kann section-parallax.js es per transform
   langsamer scrollen lassen als den Rest der Seite (Kunden-Wunsch,
   background-attachment: fixed ist dafuer browseruebergreifend
   unzuverlaessig, siehe hero-parallax-Kommentar dort). overflow: hidden
   kappt den Ueberstand; die Bild-URL kommt weiterhin inline vom Editor als
   CSS-Variable (--gedo-section-image, siehe sections.php), keine sonstige
   Aenderung am Redaktions-Workflow noetig. */
.page-section-has-image {
	position: relative;
	overflow: hidden;
}
.page-section-has-image::before {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	top: -260px;
	bottom: -260px;
	background: var(--gedo-section-image) center/cover no-repeat;
	transform: translateY(var(--gedo-section-parallax-y, 0px));
	will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
	.page-section-has-image::before { transform: none; }
}
/* Anker-Spruenge (z.B. /#stellenangebote) landen sonst unter dem fixen
   Header. */
.page-section[id] { scroll-margin-top: var(--gedo-header-height); }
.page-section-inner { position: relative; z-index: 1; }

/* Auf einem Hintergrundfoto ist Text direkt auf dem Bild je nach Motiv kaum
   lesbar (Navy-Titel auf Baum/Himmel). Titel und Fliesstext bekommen dort
   deshalb dieselbe weisse Kartenflaeche wie die Kacheln - funktioniert
   unabhaengig vom Foto, ohne dass die Redaktion ein "passendes" Bild
   suchen oder ein Overlay einstellen muss. */
.page-section-has-image .section-title {
	width: fit-content;
	max-width: 100%;
	margin: 0 auto 32px;
	padding: 14px 32px 30px;
	background: rgba(255, 255, 255, 0.6);
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
}
.page-section-has-image .section-title::after { bottom: 16px; }
.page-section-has-image .prose-content {
	padding: 28px 30px;
	background: rgba(255, 255, 255, 0.6);
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
}

/* Zentrierter Abschnittstitel mit kleinem Unterstrich-Akzent - selbes
   Grundprinzip wie auf der Referenz-Seite ("Unsere Kompetenzen" etc.), damit
   Abschnitte klarer voneinander abgesetzt sind statt kommentarlos
   ineinander ueberzugehen. Akzentfarbe Gold statt deren Gruen. */
.section-title {
	text-align: center;
	font-size: 1.7rem;
	color: var(--gedo-navy);
	margin: 0 0 32px;
	position: relative;
	padding-bottom: 16px;
}
.section-title::after {
	content: '';
	position: absolute;
	left: 50%;
	bottom: 0;
	transform: translateX(-50%);
	width: 48px;
	height: 3px;
	background: var(--gedo-accent);
	border-radius: 2px;
}

/* Datenblatt (Section-Typ "datasheet", siehe renderDatasheetSection() in
   sections.php): Karte mit Foto links und den Angaben rechts, darin die
   Spalten ("groups") als Raster - schmaler Bildschirm: alles untereinander.
   Bezeichnung klein/gedaempft ueber dem Wert statt daneben, damit auch lange
   Bezeichnungen wie "Förderstrom / Pumpe (m³/h)" nicht umbrechen muessen. */
.datasheet {
	display: grid;
	gap: 0;
	background: var(--gedo-surface);
	border: 1px solid var(--gedo-border);
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
	overflow: hidden;
}
.datasheet-has-photo { grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); }
.datasheet-photo { margin: 0; min-height: 260px; }
.datasheet-photo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	cursor: zoom-in;
}
.datasheet-body { padding: 26px 28px 28px; }
.datasheet-title {
	margin: 0 0 20px;
	font-size: 1.3rem;
	color: var(--gedo-navy);
}
.datasheet-groups {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
	gap: 22px 28px;
}
.datasheet-group h3 {
	margin: 0 0 10px;
	padding-bottom: 6px;
	font-size: 0.8rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--gedo-accent-dark);
	border-bottom: 2px solid var(--gedo-accent);
}
.datasheet-group dl { margin: 0; }
.datasheet-row { padding: 7px 0; border-bottom: 1px solid var(--gedo-border); }
.datasheet-row:last-child { border-bottom: none; }
.datasheet-row dt {
	font-size: 0.78rem;
	color: var(--gedo-text-muted);
}
.datasheet-row dd {
	margin: 2px 0 0;
	font-weight: 600;
	color: var(--gedo-text);
}
.datasheet-row-note dd { font-weight: 400; }
@media (max-width: 760px) {
	.datasheet-has-photo { grid-template-columns: 1fr; }
	.datasheet-photo { min-height: 0; aspect-ratio: 4 / 3; }
	.datasheet-body { padding: 20px; }
}

/* Kacheln (Section-Typ "tiles", Layout "grid"): Auto-fill-Grid wie
   .page-list, aber als anklickbare Karten (die ganze Kachel ist ein <a>,
   sofern ein Link gesetzt ist - sonst ein normaler <div>, siehe
   sections.php). */
.section-tiles {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
	gap: 20px;
}
.section-tile {
	display: block;
	background: var(--gedo-surface);
	border: 1px solid var(--gedo-border);
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
	padding: 26px 24px;
	color: var(--gedo-text);
	transition: transform 0.15s ease, box-shadow 0.15s ease;
}
a.section-tile:hover {
	transform: translateY(-3px);
	box-shadow: 0 10px 28px rgba(15, 61, 99, 0.16);
	text-decoration: none;
	color: var(--gedo-text);
}
/* Farb-Badge in Logo-Gold um jedes Kachel-Icon - "Farben als
   gestalterisches Element auf der gesamten Website" (Ueberschriften/
   Kacheln/grafische Elemente/Buttons). */
.section-tile-icon {
	/* display:flex statt inline-flex + margin:auto statt nur margin-bottom:
	   inline-level Boxen lassen sich nicht per margin:auto zentrieren (dafuer
	   noetig: ein block-artiger Level, den auch "flex" ohne "inline-"-Praefix
	   erfuellt) - Kunden-Feedback: Icon soll zentriert statt linksbuendig
	   stehen. */
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border-radius: 50%;
	background: var(--gedo-accent);
	color: var(--gedo-navy);
	margin: 0 auto 14px;
}
.section-tile-icon svg { width: 26px; height: 26px; }
/* Titel zentriert wie schon das Icon darueber (Kunden-Feedback); der
   Beschreibungstext selbst im Blocksatz statt linksbuendig - zentriert waere
   bei mehrzeiligem Flieesstext schwerer lesbar (wechselnde Zeilenlaengen). */
.section-tile h3 { margin: 0 0 8px; font-size: 1.1rem; color: var(--gedo-navy); text-align: center; }
.section-tile p { margin: 0; font-size: 0.92rem; color: var(--gedo-text-muted); text-align: justify; }

/* Kennzahlen (Section-Typ "tiles", Layout "stats"): grosse Zahl (Gold) +
   Label (Navy), wie auf der Referenz-Seite (gwv-sonnewalde.de) - hier in
   den eigenen Logo-Farben statt deren Blau/Gruen. Dieselben Kachel-Felder
   (title/text), nur anders dargestellt - kein Kartenrahmen/Icon/Link. */
.section-stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 24px;
	text-align: center;
	padding: 28px 20px;
	background: var(--gedo-surface);
	border: 1px solid var(--gedo-border);
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
}
.section-stat { display: flex; flex-direction: column; gap: 4px; }
.section-stat strong { font-family: var(--gedo-heading-font); font-size: 2.4rem; font-weight: 800; color: var(--gedo-accent-dark); line-height: 1.1; }
.section-stat span { font-size: 0.88rem; color: var(--gedo-navy); font-weight: 600; }

/* Zeitleiste (Section-Typ "tiles", Layout "timeline"): Mittellinie mit
   abwechselnd links/rechts angeordneten Karten und nummerierten Kreis-
   Markern statt Icon (Kunden-Wunsch, Referenzbild). Teaser/Volltext ueber
   natives <details>/<summary> (siehe theme/sections.php) statt eigenem JS -
   funktioniert ohne Skript, ist per Tastatur bedienbar; list-style/
   ::-webkit-details-marker blenden nur das browsereigene Dreieck aus, der
   eigene Pfeil kommt von .timeline-toggle::after. */
.section-timeline {
	position: relative;
	max-width: 880px;
	margin: 0 auto;
	padding: 12px 0;
}
.section-timeline::before {
	content: '';
	position: absolute;
	left: 50%;
	top: 0;
	bottom: 0;
	width: 3px;
	background: var(--gedo-border);
	transform: translateX(-50%);
}
/* Eine Karte pro Eintrag statt zwei (Kunden-Feedback: die Volltext-Box
   wirkte als zweite, unverbundene Box unter dem Teaser) - Rahmen/Schatten
   sitzen direkt auf .timeline-item (dem <details>/<div> selbst), <summary>
   und .timeline-full sind nur noch unstrukturierter Inhalt darin, kein
   eigener Kasten mehr. Feste Breite (nicht mehr inhaltsbreit/inline-block)
   ist der Preis dafuer - noetig, damit Teaser und aufgeklappter Volltext
   exakt dieselbe Kartenbreite/-kante behalten. */
.timeline-item {
	position: relative;
	width: calc(50% - 40px);
	box-sizing: border-box;
	margin-bottom: 24px;
	background: var(--gedo-surface);
	border: 1px solid var(--gedo-border);
	border-radius: var(--gedo-radius);
	box-shadow: var(--gedo-shadow);
	padding: 16px 20px;
}
.timeline-item-left { left: 0; }
.timeline-item-right { left: calc(50% + 40px); }
.timeline-marker {
	position: absolute;
	top: 16px;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	background: var(--gedo-accent);
	color: var(--gedo-navy);
	font-family: var(--gedo-heading-font);
	font-weight: 800;
	display: flex;
	align-items: center;
	justify-content: center;
	box-shadow: 0 0 0 4px var(--gedo-surface);
	z-index: 1;
}
.timeline-item-left .timeline-marker { right: -57px; }
.timeline-item-right .timeline-marker { left: -57px; }
.timeline-summary {
	display: block;
	list-style: none;
	cursor: pointer;
}
summary.timeline-summary::-webkit-details-marker { display: none; }
summary.timeline-summary::marker { content: ''; }
div.timeline-summary { cursor: default; }
.timeline-title { display: block; color: var(--gedo-navy); font-family: var(--gedo-heading-font); font-weight: 800; margin-bottom: 6px; }
.timeline-teaser { display: block; color: var(--gedo-text-muted); font-size: 0.92rem; }
.timeline-toggle {
	display: inline-block;
	margin-top: 8px;
	color: var(--gedo-accent-dark);
	font-size: 0.85rem;
	font-weight: 700;
}
.timeline-toggle::after { content: ' \203A'; }
details[open] > summary.timeline-summary .timeline-toggle::after { content: ' \2039'; }
.timeline-full {
	margin-top: 10px;
	padding-top: 10px;
	border-top: 1px solid var(--gedo-border);
}
.timeline-full p { margin: 0 0 10px; color: var(--gedo-text); font-size: 0.92rem; }
.timeline-full p:last-child { margin-bottom: 0; }
.timeline-link { font-weight: 700; }
@media (max-width: 720px) {
	.section-timeline::before { left: 17px; }
	.timeline-item, .timeline-item-left, .timeline-item-right {
		width: calc(100% - 46px);
		left: 0;
		margin-left: 46px;
	}
	.timeline-item-left .timeline-marker, .timeline-item-right .timeline-marker { left: -46px; right: auto; }
}
