/*
KAI-CMS - system.css

Basis-/Struktur-Regeln, die unabhaengig vom jeweiligen Projekt-Design funktionieren muessen:
- .lightbox_*: Struktur/Mechanik der Bild-Lightbox aus js/lightbox.js (Overlay-Positionierung,
  Sichtbarkeits-Umschaltung ueber .is_open, Bedienelemente). Visuelle Gestaltung
  (Abdunkelung, Typografie der Bildunterschrift, Look der drei Bedienknoepfe) liegt wie bei
  den anderen Bloecken hier in css/styles.css.
- .company-data[data-field="oeffnungszeiten"]: sorgt dafuer, dass mehrzeilige Oeffnungszeiten
  (aus company-data.json) unabhaengig vom umgebenden Container Zeilenumbrueche behalten.
- .popup_*: Struktur/Mechanik des Website-Popups aus js/popup.js (Overlay-Positionierung/
  -Layout, Groessenbegrenzung des Dialogs, Sichtbarkeits-Umschaltung ueber .is_open, wie
  .lightbox_*). Visuelle Gestaltung (Hintergrundfarben, Ausrichtung/Abstaende, Typografie)
  liegt wie bei den anderen Bloecken hier in css/styles.css - das sind die vorgesehenen
  Customization-Hooks fuer individuelles Kunden-Design pro Kunde.
- nav.mainnav .mainnav-*: Struktur/Mechanik der aus menu.json generierten Navigation
  (js/menu.js) - Dropdown-Positionierung/Sichtbarkeit fuer Untermenues, Anker-Scrolling.
  Visuelle Gestaltung (Farben, Abstaende) liegt wie beim uebrigen nav.mainnav in
  css/styles.css.
- .calendar-*: Struktur/Mechanik des Termin-Widgets aus js/calendar.js (Listen-/Monats-
  Umschaltung, Grid-Layout, Sichtbarkeit der Tagesdetails ueber .is_selected/.has_events).
  Visuelle Gestaltung (Farben, Abstaende, Pills) liegt wie bei den anderen Bloecken hier in
  css/styles.css.
- .cookieconsent_*: Struktur/Mechanik des Cookie-Consent-Banners aus js/cookieconsent.js
  (fixe Leiste am unteren Bildschirmrand, Sichtbarkeits-Umschaltung ueber .is_open, wie
  .popup_* bzw. .lightbox_*) sowie der Platzhalter-Mechanik fuer consent-pflichtige
  Einbettungen (z.B. Google Maps, siehe Hilfe-Sektion im CMS). Akzeptieren-Button-Farbe
  liegt wie bei .btn-link/anderen Akzent-Farben in css/styles.css.
- .kai_icon .cms_icon: Groesse des Icon-Picker-Markers im Kundencontent (siehe
  openIconPicker()/resolveIconMarkersInEditor() in cms.js, resolveIconMarkers() in
  iconhelper.php). Gehoert bewusst hierher, nicht in cms.css: cms.css ist die Backend-
  Stylesheet und wird auf einer echten Kundenseite (index.html etc.) gar nicht eingebunden
  (nur cms/css/system.css + css/styles.css, siehe deren <head>) - .cms_icon's Backend-Regel
  (width/height:19px, cms.css) griffe dort also gar nicht, ein frisch eingefuegtes Icon
  bliebe unskaliert (SVG-Default-Groesse, deutlich zu gross). 1em statt einer festen
  Pixelzahl, damit das Icon zur jeweils umgebenden Schriftgroesse passt (Ueberschrift,
  Fliesstext, ...) statt auf jeder Kundenseite gleich gross zu wirken unabhaengig vom
  Kontext.

Wird VOR css/styles.css eingebunden (siehe <head> der Seiten sowie content_css in
cms/settings.php), damit projektspezifisches Design bei Bedarf ueberschreiben kann.
*/

/* LIGHTBOX (Struktur/Mechanik fuer js/lightbox.js - Optik in css/styles.css, siehe dort
fuer die Liste der vorgesehenen Customization-Hooks) */

.lightbox_overlay {
	position: fixed; inset: 0;
	display: flex; align-items: center; justify-content: center;
	z-index: 1000; padding: 40px;
	/* display bleibt immer "flex" - Ein-/Ausblenden laeuft rein ueber opacity/visibility,
	damit beides (anders als bei display:none/flex) animierbar ist. visibility wird beim
	Oeffnen sofort auf "visible" umgeschaltet, beim Schliessen aber erst NACH der
	Opacity-Transition (transition-delay = gleiche Dauer wie die Opacity-Transition) - so
	bleibt das Overlay waehrend des Fade-outs klickbar/sichtbar und verschwindet danach
	komplett aus der Interaktions-/Tab-Reihenfolge, ganz ohne JS-Timer. */
	opacity: 0; visibility: hidden; pointer-events: none;
	transition: opacity 0.25s ease, visibility 0s linear 0.25s;
}
.lightbox_overlay.is_open {
	opacity: 1; visibility: visible; pointer-events: auto;
	transition: opacity 0.25s ease, visibility 0s linear 0s;
}
.lightbox_figure {
	/* text-align zentriert die Bildunterschrift unter dem Grossbild. Bleibt hier, obwohl es
	Typografie ist: das Bild wird von der Mechanik zentriert, eine linksbuendige Unterschrift
	darunter saehe nach Fehler aus, nicht nach Gestaltung. Ueberschreibbar bleibt es
	trotzdem - styles.css wird nach dieser Datei geladen. */
	margin: 0; max-width: 90vw; max-height: 90vh; text-align: center;
	/* Spalte statt Standard-Blockfluss, seit unter der Bildunterschrift noch die Feldliste
	stehen kann (renderFields() in js/lightbox.js): zusammen mit "min-height: 0" am Bild
	gibt das Grossbild Platz ab, wenn Unterschrift und Felder sonst unter den unteren
	Bildschirmrand rutschen wuerden. Ohne das schneidet die max-height der figure die
	letzten Zeilen ab - mit Feldern war genau das der Fall. */
	display: flex;
	flex-direction: column;
	align-items: center;
	/* Leichtes Scale-up beim Oeffnen (0.92 -> 1), laeuft parallel zur Opacity-Transition
	des Overlays - zusammen ergibt das ein sanftes "Einwachsen" statt hartem Erscheinen. */
	transform: scale(0.92);
	transition: transform 0.25s ease;
}
.lightbox_overlay.is_open .lightbox_figure { transform: scale(1); }
.lightbox_img {
	max-width: 90vw; max-height: 80vh; object-fit: contain; display: block;
	/* Siehe .lightbox_figure: erlaubt dem Bild, unter seine Inhaltsgroesse zu schrumpfen,
	damit die Textzeilen darunter im Bild bleiben. */
	min-height: 0;
	/* Kurzes Abblenden beim Bildwechsel (siehe lightbox.js: Klasse wird vor dem
	src-Tausch gesetzt, danach wieder entfernt) - kein voller Fade auf 0, damit der
	Wechsel zuegig/knackig bleibt statt zu "blinken".

	Diese beiden Regeln bleiben als GANZES hier, obwohl der Wert 0.15 fuer sich genommen eine
	gestalterische Entscheidung waere: die Dauer 0.15s ist die CSS-Haelfte einer Mechanik, deren
	andere Haelfte im Skript steht (SWITCH_FADE_MS = 150 in lightbox.js, siehe den Kommentar
	dort - "must match the CSS transition on .lightbox_img"). Faende sich die Transition in
	styles.css und eine Installation haette sie nicht, wartete das Skript weiterhin 150 ms, das
	Bild stuende so lange hart bei 15 % Deckkraft und spraenge dann um. */
	opacity: 1;
	transition: opacity 0.15s ease;
}
.lightbox_img.lightbox_img_switching { opacity: 0.15; }
.lightbox_close, .lightbox_prev, .lightbox_next {
	position: fixed;
	/* Reset gegen die Browser-Defaults des <button> - die eigentliche Optik (Hintergrund,
	Textfarbe, Schriftgroesse des Symbols, Eckenradius, Hover-Zustand) liegt komplett in
	styles.css, wie bei .calendar-filter/.calendar-view-button weiter unten. Groesse und
	Position dagegen bleiben hier: die Knoepfe haben keinen Innenabstand, die 44 bzw. 52 px
	SIND die Trefferflaeche.

	"background: none" gehoert mit in den Reset, obwohl die Farbe selbst Optik ist: ohne die
	Zeile faellt eine Installation, deren styles.css den Optik-Block noch nicht hat, nicht auf
	"keinen Hintergrund" zurueck, sondern auf den grauen Standardknopf des Browsers - drei
	graue Kaesten ueber dem Bild, die aussehen, als waeren sie so gemeint. Ein Reset, der die
	Defaults nur halb neutralisiert, verschiebt den Fehler bloss; sichtbar nichts ist besser
	als sichtbar etwas Falsches. Die Kundenregel gewinnt trotzdem: gleiche Spezifitaet,
	styles.css wird nach dieser Datei geladen. */
	background: none;
	border: none; cursor: pointer; line-height: 1;
}
/* Feldliste unter der Bildunterschrift (renderFields() in js/lightbox.js). Nur zwei Regeln
gehoeren hierher, alles Weitere - Farben, Schriftgroessen, Abstaende, Spaltenaufteilung -
liegt in css/styles.css:
- :empty aus dem Fluss nehmen. Der Container steht immer im Overlay, auch bei einem Bild
  ganz ohne Felder; ohne diese Regel bliebe dort ein leerer Block mit Aussenabstand stehen.
- text-align: left, weil .lightbox_figure zentriert. Gleiche Begruendung wie bei der
  Bildunterschrift: zentrierte Label/Wert-Paare untereinander saehen nach Fehler aus, nicht
  nach Gestaltung. Ueberschreibbar bleibt es, styles.css wird spaeter geladen. */
.lightbox_fields:empty { display: none; }
.lightbox_fields { text-align: left; }
.lightbox_close { top: 20px; right: 24px; width: 44px; height: 44px; }
.lightbox_prev, .lightbox_next { top: 50%; transform: translateY(-50%); width: 52px; height: 52px; }
.lightbox_prev { left: 20px; }
.lightbox_next { right: 20px; }

/* COMPANY DATA (Struktur, unabhaengig vom umgebenden Container) */

.company-data[data-field="oeffnungszeiten"] {
	white-space: pre-line;
}

/* POPUP (Struktur/Mechanik fuer js/popup.js - Optik in css/styles.css, siehe dort fuer die
Liste der vorgesehenen Customization-Hooks) */

.popup_overlay {
	position: fixed; inset: 0;
	display: flex; align-items: center; justify-content: center;
	z-index: 1000; padding: 40px;
	/* Analog zu .lightbox_overlay (siehe dort fuer Details): display bleibt immer "flex",
	Ein-/Ausblenden laeuft nur ueber opacity/visibility (animierbar, anders als display:none/
	flex). transition-delay auf visibility haelt das Overlay waehrend des Fade-outs sichtbar/
	klickbar und schaltet es erst danach komplett aus der Interaktion, ganz ohne JS-Timer. */
	opacity: 0; visibility: hidden; pointer-events: none;
	transition: opacity 0.25s ease, visibility 0s linear 0.25s;
}
.popup_overlay.is_open {
	opacity: 1; visibility: visible; pointer-events: auto;
	transition: opacity 0.25s ease, visibility 0s linear 0s;
}
.popup_dialog {
	position: relative;
	max-width: 560px; width: 100%;
	max-height: 90vh; overflow-y: auto;
	box-sizing: border-box;
	/* Leichtes Scale-up beim Oeffnen (0.92 -> 1), analog zu .lightbox_figure - laeuft
	parallel zur Opacity-Transition des Overlays. */
	transform: scale(0.92);
	transition: transform 0.25s ease;
}
.popup_overlay.is_open .popup_dialog { transform: scale(1); }
.popup_close {
	position: absolute; top: 10px; right: 14px;
	border: none; cursor: pointer;
	font-size: 28px; line-height: 1;
}
.popup_image { display: block; max-width: 100%; height: auto; }

/* COOKIE CONSENT (Struktur/Mechanik fuer js/cookieconsent.js) */

.cookieconsent_banner {
	position: fixed; left: 0; right: 0; bottom: 0;
	z-index: 1000;
	background: #fff;
	border-top: 1px solid #eee;
	box-shadow: 0 -4px 20px rgba(0,0,0,0.08);
	/* Analog zu .popup_overlay/.lightbox_overlay (siehe dort fuer Details): display bleibt
	immer vorhanden, Ein-/Ausblenden laeuft nur ueber opacity/visibility/transform
	(animierbar). Zusaetzlich ein leichtes Herein-/Heraus-Gleiten von unten (transform),
	passend zur Position am unteren Bildschirmrand - bei Popup/Lightbox (mittig) war
	stattdessen ein Scale-Effekt passender. */
	opacity: 0; visibility: hidden; pointer-events: none;
	transform: translateY(12px);
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0.25s;
}
.cookieconsent_banner.is_open {
	opacity: 1; visibility: visible; pointer-events: auto;
	transform: translateY(0);
	transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0s;
}
.cookieconsent_banner_inner {
	max-width: 1100px; margin: 0 auto;
	padding: 18px 24px;
	display: flex; flex-wrap: wrap; align-items: center; gap: 16px 24px;
}
.cookieconsent_text { flex: 1 1 380px; font-size: 14px; line-height: 1.5; color: #333; }
.cookieconsent_text p { margin: 0 0 8px; }
.cookieconsent_text p:last-child { margin-bottom: 0; }
.cookieconsent_actions { flex: 0 0 auto; display: flex; gap: 10px; }
.cookieconsent_accept, .cookieconsent_reject {
	font-family: inherit; font-size: 14px;
	padding: 10px 20px;
	border-radius: 6px;
	cursor: pointer;
	white-space: nowrap;
}
.cookieconsent_accept {
	border: none;
	background: #333; color: #fff;
}
.cookieconsent_reject {
	border: 1px solid #ccc;
	background: transparent; color: #555;
}

/* Cookies setzende Einbettungen (z.B. Google Maps) - siehe Hilfe-Sektion im CMS fuer die
von Redakteuren zu verwendende Syntax. Das iframe bleibt ohne src, bis entweder global
zugestimmt wurde oder gezielt auf den Platzhalter-Button geklickt wird (js/cookieconsent.js
kopiert dann data-cookieconsent-src -> src). */
.cookieconsent_embed { position: relative; }
.cookieconsent_embed iframe { display: block; width: 100%; border: 0; }
.cookieconsent_embed_placeholder {
	position: absolute; inset: 0;
	display: flex; flex-direction: column; align-items: center; justify-content: center;
	gap: 12px;
	text-align: center; padding: 20px; box-sizing: border-box;
	background: #f0f0ee;
}
.cookieconsent_embed.is_consented .cookieconsent_embed_placeholder { display: none; }
.cookieconsent_embed_accept {
	font-family: inherit; font-size: 14px;
	padding: 10px 20px;
	border: none; border-radius: 6px;
	background: #333; color: #fff;
	cursor: pointer;
}

/* MAINNAV (Struktur/Mechanik fuer js/menu.js) */

/* Sanftes Scrollen zu Section-Ankern (#id) - deckt sowohl Klicks auf einen
Section-Menuepunkt auf der bereits offenen Zielseite ab (nativer Anker-Sprung des
Browsers wird dadurch automatisch sanft) als auch, in Kombination mit dem
scrollIntoView-Aufruf in menu.js, den Seitenwechsel-Fall. */
html { scroll-behavior: smooth; }

nav.mainnav ul.mainnav-list {
	list-style: none;
	margin: 0;
	padding: 0;
}
nav.mainnav li.mainnav-item {
	position: relative;
}
/* Dropdown ist standardmaessig unsichtbar UND aus dem Layout-Fluss (display:none) - anders
als beim Lightbox-/Popup-Overlay reicht hier reines display, da kein Ein-/Ausblenden
animiert werden muss (ein Untermenue klappt bewusst hart auf/zu, nicht sanft). */
nav.mainnav ul.mainnav-dropdown {
	list-style: none;
	margin: 0;
	padding: 0;
	position: absolute;
	top: 100%;
	left: 0;
	min-width: 180px;
	display: none;
	z-index: 100;
}
/* Aufklappen per Hover (Desktop-Komfort) ODER per .is_open-Klasse (von menu.js beim Klick
gesetzt - noetig fuer Touch-Geraete, wo :hover nicht zuverlaessig feuert). Beide Wege
fuehren zum selben sichtbaren Zustand. */
nav.mainnav li.mainnav-item.has-dropdown:hover > ul.mainnav-dropdown,
nav.mainnav li.mainnav-item.has-dropdown.is_open > ul.mainnav-dropdown {
	display: block;
}
nav.mainnav ul.mainnav-dropdown li {
	list-style: none;
}

/* Burger-Umschalter (nur auf schmalen Viewports, siehe Media Query unten) - Basis-Reset
hier, visuelle Gestaltung (Balken-Farbe/-Abstand) liegt wie beim uebrigen mainnav in
css/styles.css. */
.mainnav-burger {
	display: none;
	background: transparent;
	border: none;
	cursor: pointer;
	padding: 0;
}

@media (max-width: 720px) {
	/* display:flex statt nur "block" - die drei Balken-Spans werden per
	flex-direction:column gestapelt (siehe .mainnav-burger span in css/styles.css), das
	muss also schon hier beim Sichtbarmachen mitkommen. */
	.mainnav-burger {
		display: flex;
	}
	nav.mainnav {
		position: relative;
	}
	/* .mainnav-list dient auf schmalen Viewports gleichzeitig als aufklappbares
	Burger-Panel - standardmaessig unsichtbar, erst .is_open (vom Burger-Button in
	menu.js gesetzt) blendet sie ein. Auf breiten Viewports (ausserhalb dieser Media
	Query) bleibt sie immer sichtbar, die Klasse wird dort schlicht ignoriert. */
	nav.mainnav ul.mainnav-list {
		display: none;
		position: absolute;
		top: 100%;
		right: 0;
		z-index: 200;
		flex-direction: column;
	}
	nav.mainnav ul.mainnav-list.is_open {
		display: flex;
	}
	/* Untermenues stapeln sich eingerueckt innerhalb der bereits senkrechten
	Burger-Liste, statt wie auf dem Desktop schwebend danebenzuklappen. */
	nav.mainnav ul.mainnav-dropdown {
		position: static;
	}
}

/* TERMINE/KALENDER (Struktur/Mechanik fuer js/calendar.js) */

.calendar-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
}

.calendar-view-toggle {
	display: flex;
	flex: 0 0 auto;
}

.calendar-filters {
	display: flex;
	flex-wrap: wrap;
	flex: 1 1 auto;
}

.calendar-filter, .calendar-view-button {
	cursor: pointer;
	background: none;
	/* Reset gegen Browser-Default-Buttonrahmen/-Innenabstand - die eigentliche Optik
	(Rahmenfarbe, Radius, aktiver Zustand) liegt komplett in styles.css. */
	border: 0;
	font: inherit;
}

.calendar-month-group {
	width: 100%;
}

.calendar-list-item {
	display: flex;
	width: 100%;
	box-sizing: border-box;
}

.calendar-list-date {
	display: flex;
	flex-direction: column;
	flex: 0 0 auto;
}

.calendar-list-body {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	min-width: 0; /* erlaubt text-overflow/Umbruch in Titel/Beschreibung innerhalb des flex-Items */
}

.calendar-grid-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
}

.calendar-grid-nav {
	cursor: pointer;
	background: none;
	border: 0;
	font: inherit;
}

.calendar-grid-weekdays, .calendar-grid-days {
	display: grid;
	grid-template-columns: repeat(7, 1fr);
}

.calendar-grid-day {
	cursor: default;
	background: none;
	border: 0;
	font: inherit;
	display: flex;
	flex-direction: column;
	align-items: center;
	width: 100%;
	box-sizing: border-box;
}

.calendar-grid-day.has_events {
	cursor: pointer;
}

.calendar-grid-day.is_empty {
	cursor: default;
	visibility: hidden;
}

.calendar-grid-dots {
	display: flex;
}

.calendar-grid-dot {
	border-radius: 50%;
	display: inline-block;
}

@media (max-width: 720px) {
	.calendar-toolbar {
		flex-direction: column;
		align-items: flex-start;
	}
}

/* CONTENT ITEMS / NEWS / AKTUELLES (Struktur/Mechanik fuer js/content-items.js) */

.content-items-widget {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.content-items-card {
	display: flex;
	flex-direction: column;
	text-decoration: none;
}

.content-items-card-image {
	width: 100%;
	object-fit: cover;
	object-position: center;
	display: block;
}

.content-items-card-body {
	display: flex;
	flex-direction: column;
}

/* PREISLISTE (Struktur/Mechanik fuer js/pricelist.js - Optik in css/styles.css, siehe dort
fuer die Liste der vorgesehenen Customization-Hooks) */

.pricelist-toc {
	list-style: none;
	margin: 0;
	padding: 0;
}

.pricelist-table {
	width: 100%;
	border-collapse: collapse;
}

/* KONTAKTFORMULAR (Struktur/Mechanik fuer js/contactform.js - Optik in css/styles.css,
siehe dort fuer die Liste der vorgesehenen Customization-Hooks) */

/* Honeypot-Feld fuer den Spam-Schutz - MUSS ausserhalb des sichtbaren Bereichs bleiben
(nicht display:none/visibility:hidden, das erkennen manche Bots und lassen das Feld dann
ebenfalls leer) - echte Struktur/Sicherheitsmechanik, deshalb hier statt in styles.css,
nicht als Customization-Hook gedacht. */
.contact-form-honeypot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* ICON-PICKER (Struktur fuer den Kundencontent-Marker, siehe die Erklaerung am Kopf dieser
Datei) */

.kai_icon .cms_icon {
	width: 1em;
	height: 1em;
	vertical-align: -0.125em;
}
