/* ==========================================================================
   Geoportal – Grundlayout

   Nur Struktur: Anordnung (grid, flex), Größen, Abstände, Positionierung,
   Scrollverhalten, Stapelreihenfolge. Farben, Schrift, Rahmen, Rundungen
   und Schatten gehören nicht hierher.

   Drei Ansichten. Welche gilt, meldet die Custom Property --geo-ansicht
   (Abschnitt 1, gesetzt in Abschnitt 7); js/panel.js liest sie.

   - fluss, Dokumentfluss (unter 30rem Höhe, und im Druck): Die Seite
     scrollt, die Kopfleiste bleibt oben stehen. Reihenfolge: Inhalte,
     Karte, Darstellung, Pflichtlinks. Kooperative Gesten an (js/map.js).
     Die Objektauskunft erscheint als Sheet.
   - schmal (unter 70rem Breite, ab 30rem Höhe, nur Bildschirm): Die Seite
     füllt den Viewport und scrollt nicht. Die Karte füllt den Platz unter
     der zweizeiligen Kopfleiste. Inhalte, Informationen, Darstellung und
     Pflichtlinks liegen als Leiste über ihrem linken Rand, geöffnet über
     einen Knopf vorn in der Werkzeugleiste; er ersetzt dort "Gesamten
     Amtsbereich anzeigen". Die Objektauskunft erscheint als Sheet.
     Kooperative Gesten aus.
   - breit (ab 70rem Breite und 30rem Höhe, nur Bildschirm): Die Seite füllt
     den Viewport und scrollt nicht. Links die Seitenleiste, die in sich
     scrollt, rechts die Karte bis an den Rand, die Kopfleiste ohne eigene
     Fläche darüber. Kooperative Gesten aus.

   Die Bedingungen stehen nur in den @media-Regeln der Abschnitte 7 und 8;
   das Skript liest das Ergebnis und kennt sie nicht.

   rem in @media bezieht sich auf die Standardschriftgröße des Browsers,
   nicht auf die Wurzelschrift des Themes: 70rem sind bei 16px 1120px. Mit
   größerer Browserschrift schalten die Ansichten entsprechend später um.

   Gliederung:
     1. Maße
     2. Korrekturen am Theme
     3. Verborgenes
     4. Kopfleiste
     5. Werkzeugleiste und Bedienelemente
     6. Inhalt im Dokumentfluss
     7. Anwendung (7a breite, 7b schmale Ansicht)
     8. Kopfleiste über der Karte
     9. Menü-Dialog
	 10. Geo Help
	 11. Geo Druck
	 12. Allgemeines
   ========================================================================== */


/* --- 1. Maße ----------------------------------------------------------- */

@font-face {
	font-family: abco-mono;
	font-style: normal;
	src: url("f/abco-mono.woff2") format(woff2) tech(variations);
	font-display: swap;
	font-weight: 300 800;
}

:root {

	--gap-2xs: calc(var(--gap-xs) / 2);
	--c-code: oklch(.50 .12 70);
	--c-promiment: black;

	/* Breite des Logos. Die Einrückung des Titels braucht sie; beide in rem,
	   damit sie bei jeder Schriftgröße zusammenpassen. Seitenverhältnis wie
	   die viewBox (297 × 178). */
	/*--geo-logo-breite: 2.5rem;*/

	/* Eine Höhe für alle Bedienelemente der Kopfleiste. In rem und nicht in
	   lh: lh hängt an Schriftgröße und Zeilenhöhe des jeweiligen Elements,
	   und die Knöpfe des Themes bringen eigene mit. 2.75rem sind bei 16px
	   44px, die Zielgröße aus WCAG 2.5.5 (AAA); AA (2.5.8) verlangt 24px. */
	--geo-steuer-hoehe: 2rem;

		/* Breite der Seitenleiste in der Anwendung. Als Variable, weil auch der
	   Hintergrund der Kopfleiste sie braucht. Die Prozentangabe löst sich
	   erst dort auf, wo die Variable verwendet wird: im Grid gegen die
	   Breite von #geo-app, im Verlauf gegen die Breite der Kopfleiste.
	   Beide sind in der Anwendung so breit wie der Viewport. */
	--geo-sidebar-breite: clamp(18rem, 28%, 22rem);

	/* Welche Ansicht gilt: fluss, schmal oder breit (siehe Kopf). Hier der
	   Ausgangswert; die @media-Regeln in Abschnitt 7 überschreiben ihn.
	   js/panel.js liest den Wert und richtet danach Sheet und Leiste ein.
	   Die Bedingungen stehen damit nur in diesem Stylesheet. */
	--geo-ansicht: fluss;
}

@media (prefers-color-scheme: dark) {
	:root {
		--c-code: oklch(.85 .1 70);
		--c-prominent: white;
	}
}

/* --- 2. Korrekturen am Theme ------------------------------------------- */

/* Das Theme begrenzt die Breite von body und .main für Textseiten. Das
   Geoportal nutzt die volle Breite. !important, weil das Theme die Breite
   selbst mit !important setzt. */
body.geoportal,
#main {
	block-size: unset;
	inline-size: 100%;
	max-inline-size: 100%;
	padding: 0;
}

/* Das Theme setzt an der Bildunterschrift nowrap. unset wirkte hier wie
   inherit und übernähme das nowrap vom Elternelement; der Quellenvermerk
   liefe dann über den Rand und erzeugte einen waagerechten Scrollbalken. */
.figcaption .creator {
	white-space: normal;
}


/* --- 3. Verborgenes ---------------------------------------------------- */

/* Was mit hidden ausgeliefert wird, bleibt verborgen, auch wenn unten ein
   display gesetzt ist. Die IDs heben die Spezifität über jede Regel mit
   Klassen. */
:is(#geo-toolbar, #geo-panel, #geo-settings, #geo-leiste-knopf)[hidden] {
	display: none;
}


/* --- 4. Kopfleiste ----------------------------------------------------- */

/* Schmal: Marke links, Menü rechts, die Werkzeugleiste in einer eigenen
   Zeile darunter. */
.geo-header {
	align-items: center;
	column-gap: var(--gap-s);
	display: grid;
	grid-template-areas:
		"brand menu"
		"tools tools";
	grid-template-columns: minmax(0, 1fr) auto;
	padding: var(--gap-s);
	position: relative;
	/* Eigener Stapelkontext über der Karte: Die Trefferliste der Suche hängt
	   an der Kopfleiste und muss über der Karte liegen. Die Controls von
	   MapLibre tragen z-index 2. */
	z-index: 3;
}

/* Nur bei ausreichender Höhe: Bei starker Vergrößerung oder auf einem
   Smartphone quer fräße eine stehende Kopfleiste den halben Viewport. */
@media (height >= 30rem) {
	.geo-header {
		inset-block-start: 0;
		position: sticky;
	}
}

/* Marke: zwei Spalten, zwei Zeilen. Links das Logo über beide Zeilen,
   rechts Amtsname und Titel untereinander. Nur so breit wie ihr Inhalt. */
.geo-header__brand {
	align-items: center;
	column-gap: var(--gap-xs);
	display: grid;
	font-size: var(--f-size-s);
	grid-area: brand;
	grid-template-columns: auto minmax(0, 1fr);
	grid-template-rows: auto auto;
	justify-self: start;
	line-height: 1.1;
}

/* Das Logo steckt im Link, die Überschrift steht daneben. Der Link
   übernimmt deshalb Spalten und Zeilen der Marke (subgrid) und reicht über
   beide Zeilen, damit das Logo darin über beide Zeilen reichen kann.

   Die Überschrift liegt in der zweiten Zeile über dem Kasten des Links:
   Ein Klick auf "Geoportal" trifft sie, nicht den Link. Der Fokusring des
   Links umschließt die ganze Marke.

   Nicht display: contents am Link: Ohne eigenen Kasten zeichnet der
   Browser keinen Fokusring (WCAG 2.4.7). */
.geo-header__home {
	display: grid;
	grid-column: 1 / -1;
	grid-row: 1 / -1;
	grid-template-columns: subgrid;
	grid-template-rows: subgrid;
}

.geo-header__logo {
	align-self: center;
	aspect-ratio: 297 / 178;
	block-size: calc(1lh + 1cap);
	grid-column: 1;
	grid-row: 1 / -1;
	inline-size: auto;
}

.geo-header__name {
	grid-column: 2;
	grid-row: 1;
}

.geo-header__title {
	font-weight: var(--f-weight-xb);
	grid-column: 2;
	grid-row: 2;
}

.geo-header__menu {
	align-self: center;
	aspect-ratio: 1;
	grid-area: menu;
	padding: 0;
}

/* Breit: Marke links, Werkzeuge in der Mitte, Menü rechts, eine Zeile. */
@media (width >= 70rem) {
	.geo-header {
		grid-template-areas: "brand tools menu";
		grid-template-columns: auto minmax(0, 1fr) auto;
	}
}

/* --- 5. Werkzeugleiste und Bedienelemente ------------------------------ */

.geo-toolbar {
	align-items: center;
	align-self: center;
	display: flex;
	gap: var(--gap-s);
	grid-area: tools;
	margin-block-start: var(--gap-s);
	min-inline-size: 0;
}

@media (width >= 70rem) {
	.geo-toolbar {
		justify-content: flex-end;
		margin-block-start: 0;
	}
}

.geo-toolbar__search {
	align-items: center;
	display: flex;
	flex: 0 1 auto;
	min-inline-size: 0;
}

/* nowrap: Das Theme lässt die Suche umbrechen; hier sollen Feld, Suchen
   und Hilfe in einer Zeile bleiben und nur das Feld nachgeben. */
.geo-toolbar .search-wrapper {
	align-items: center;
	display: flex;
	flex: 1 1 auto;
	flex-wrap: nowrap;
	gap: var(--gap-s);
	min-inline-size: 0;
}

.geo-toolbar .input__group--search {
	align-items: center;
	flex: 1 1 auto;
	min-inline-size: 0;
}

.geo-toolbar .input--search {
    background-color: var(--c-canvas);
}

/* Lupe im Suchfeld. Rand, Größe der Lupe und Abstand zum Text in rem und
   nicht über --gap-s: Das wächst mit der Fensterbreite, die Lupe nicht.
   Vorher reichte der Innenabstand nur bei voller Breite, im schmaleren
   Fenster klebte der Platzhalter an der Lupe.

   Der Text beginnt nach Rand, Lupe und noch einmal demselben Abstand. */
.geo-toolbar .input__group--search {
	--geo-lupe-rand: .6rem;
	--geo-lupe-groesse: 1rem;
	--geo-suche-text: calc(2 * var(--geo-lupe-rand) + var(--geo-lupe-groesse));
}

.geo-toolbar .input__group--search .icon {
	block-size: var(--geo-lupe-groesse);
	inline-size: var(--geo-lupe-groesse);
	inset-inline-start: var(--geo-lupe-rand);
}

/* Breite: der ganze Platzhalter plus Innenabstände. "Orte, Flurstücke,
   Adressen…" hat 27 Zeichen; ch ist die Breite der Ziffer 0 und damit
   breiter als ein durchschnittlicher Buchstabe, 27ch reichen also sicher.
   Wird der Platzhalter in inc/panel.php geändert, hier mitändern.

   flex-shrink 1 und min-inline-size 0: Reicht die Leiste nicht, gibt das
   Feld nach — dann ist der Platzhalter abgeschnitten, die Knöpfe bleiben
   ganz.

   Beide Selektoren wie bisher: Das Theme setzt den Innenabstand bei Fokus
   und mit Inhalt eigens. Mit .geo-toolbar davor gilt die Regel nur hier,
   nicht für die Suche der Website im Menü-Dialog. */
.geo-toolbar .input__group:has(.icon) .input,
.geo-toolbar .input__group:has(.icon) .input:is(:focus-visible, :not(:placeholder-shown)) {
	flex: 0 1 auto;
	/*inline-size: calc(var(--geo-suche-text) + 26ch + var(--geo-lupe-rand));*/
	inline-size: calc(var(--geo-suche-text) + 26ch);
	min-inline-size: 0;
	/*padding-inline: var(--geo-suche-text) var(--geo-lupe-rand);*/
	padding-inline: var(--geo-suche-text) 0;
}

.geo-toolbar__actions {
	align-items: center;
	display: flex;
	gap: var(--gap-s);
}

.geo-toolbar .icon-maximize,
.geo-toolbar .icon-layers,
.geo-toolbar .icon-help,
.geo-toolbar .icon-link,
.geo-toolbar .icon-print {
	stroke-width: 1.75px;
}

.icon.icon-menu {
	block-size: auto;
	margin-inline-start: 0;
}

/* Trefferliste der Suche: links bündig mit dem Suchfeld, rechts bis zum
   Ende der Werkzeugleiste, oben direkt unter der Leiste.

   Bezugsrahmen ist die Werkzeugleiste. Die Elemente dazwischen dürfen
   deshalb nicht positioniert sein; .search-wrapper ist es im Theme, das
   wird hier zurückgenommen.

   Der linke Rand ergibt sich aus dem Aufbau der Leiste: zuerst ein
   quadratischer Knopf (--geo-steuer-hoehe breit), dann der Abstand der
   Leiste, dann das Suchfeld. Der Knopf ist in der schmalen Ansicht der für
   die Leiste, sonst "Gesamten Amtsbereich anzeigen" (Abschnitt 7b); es steht
   immer genau einer da, der Wert gilt also in jeder Ansicht. Ändert sich
   die Reihenfolge in geo_werkzeuge() (inc/panel.php), muss dieser Wert mit.

   Die Höhe ist begrenzt, damit unter der Liste Karte sichtbar bleibt; bei
   bis zu 20 Treffern scrollt sie in sich. Kein display hier: Ein- und
   ausgeblendet wird über [hidden] und die Klasse "show" (js/panel.js). */
.geo-toolbar {
	position: relative;
}

.geo-toolbar__search,
.geo-toolbar .search-wrapper {
	position: static;
}

#geo-treffer-box {
	inline-size: auto;
	inset-block-start: calc(100% + var(--gap-xs));
	inset-inline: calc(var(--geo-steuer-hoehe) + var(--gap-s)) 0;
	margin: 0;
	max-block-size: min(60dvb, 36rem);
	max-inline-size: none;
	overflow-y: auto;
	overscroll-behavior: contain;
	position: absolute;
}

#geo-treffer .result-item {
	padding: var(--gap-xs) var(--gap-s);
}

.result-item[aria-selected="true"] {
	background: var(--c-canvas-subtle);
	outline: 2px solid var(--c-accent);
	outline-offset: -2px;
}

p.geo-treffer-hinweis {
	padding: var(--gap-xs) var(--gap-s);
	font-size: var(--f-size-s);
	color: var(--c-error);
	border-block-end: 1px solid var(--c-canvas-subtle);
}

/* Alle Knöpfe und Felder der Kopfleiste gleich hoch. Die Container darüber
   richten mittig aus (align-items: center), statt zu strecken: Strecken
   übernähme die Höhe des höchsten Elements und machte die Variable
   wirkungslos. */
.geo-header .button {
	align-items: center;
	block-size: var(--geo-steuer-hoehe);
	display: inline-flex;
	gap: var(--gap-xs);
	justify-content: center;
	padding-block: 0;
}

.geo-header .input {
	block-size: var(--geo-steuer-hoehe);
	padding-block: 0;
}

/* Symbolknöpfe quadratisch, über die Breite statt aspect-ratio: Das Theme
   setzt an .button einen Innenabstand, der aspect-ratio aushebeln kann. */
/* flex: none, damit die Knöpfe in einer engen Zeile nicht schmaler werden
   als hoch; nachgeben soll allein das Suchfeld. */
.geo-header :is(.button--leiste, .button--maximize, .button--help, .button--link, .button--print) {
	flex: none;
	inline-size: var(--geo-steuer-hoehe);
	justify-content: center;
	padding-inline: 0;
}


/* --- 6. Inhalt im Dokumentfluss ---------------------------------------- */

#geo-app {
	display: grid;
	gap: var(--gap-m);
	grid-template-areas:
		"panel"
		"map"
		"settings"
		"legal";
	grid-template-columns: minmax(0, 1fr);
}

/* Die Seitenleiste löst sich auf: Ihre Teile werden Grid-Items und lassen
   sich um die Karte herum anordnen. Unbedenklich, weil .geo-sidebar ein
   <div> ohne Rolle ist — display: contents nimmt einem Element ohne
   Semantik nichts. */
.geo-sidebar {
	display: contents;
	scrollbar-width: thin;
}

.geo-panel {
	grid-area: panel;
}

.geo-map__figure {
	grid-area: map;
	margin: 0;
}

/* Im Dokumentfluss eine feste Höhe: MapLibre legt Canvas und Controls
   absolut positioniert in den Container, er hat also keine Höhe aus seinem
   Inhalt. In der Anwendung kommt sie aus der Grid-Zelle (Abschnitt 7). */
#geo-map {
	block-size: 70svb;
	inline-size: 100%;
}

.geo-settings {
	display: grid;
	gap: var(--gap-s);
	grid-area: settings;
}

.geo-settings__style {
	align-items: start;
	display: grid;
	grid-template-columns: 1fr 1fr;
}

.geo-settings .geo-heading {
	margin-block-end: 0;
}

.geo-legal {
	font-size: var(--f-size-s);
	grid-area: legal;
}

.geo-legal__list {
	column-gap: var(--gap-s);
	display: flex;
	flex-wrap: wrap;
}

/* Objektauskunft als Sheet, in der schmalen Ansicht und im Dokumentfluss.
   Das popover-Attribut setzt js/panel.js nur außerhalb der breiten Ansicht;
   die Regel greift also nur dort. Das UA-Stylesheet zentriert ein Popover
   im Viewport (inset: 0, margin: auto, fit-content); hier liegt es am
   unteren Rand, über die volle Breite.

   Höchstens 40dvb hoch: einpassPolster() in js/panel.js rechnet die Höhe
   des Sheets mit höchstens 40 % der Kartenhöhe ein. Ein höheres Sheet
   verdeckte den Teil der Karte, in den das Objekt eingepasst wird.

   visibility: visible, weil das Sheet in der schmalen Ansicht in der
   geschlossenen Leiste steckt (Abschnitt 7b). visibility wird vererbt und
   lässt sich am Nachfahren aufheben, anders als display. Verschiebung und
   overflow der Leiste wirken auf ein Element im Top-Layer nicht. */
.geo-panel__objectinfo[popover] {
	background-color: var(--c-canvas);
	block-size: auto;
	inline-size: auto;
	inset: auto 0 0;
	margin: 0;
	max-block-size: 40dvb;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: var(--gap-s);
	visibility: visible;
}

/* Schließen bleibt sichtbar, wenn eine lange Auskunft im Sheet scrollt. */
.geo-panel__sheet-close {
	inset-block-start: 0;
	position: sticky;
}

/* --- 7. Anwendung ------------------------------------------------------ */

/* Gemeinsam für die breite und die schmale Ansicht: Die Seite ist genau so
   hoch wie der Viewport und scrollt nicht, die Karte füllt den Platz. Nur
   bei ausreichender Höhe; darunter bleibt es beim Dokumentfluss
   (Abschnitt 6). */
@media screen and (height >= 30rem) {

	/* Scrollt das Dokument trotzdem um ein paar Pixel, bleiben die
	   kooperativen Gesten an — siehe seiteScrollt() in js/map.js. */
	body.geoportal {
		block-size: 100dvb;
		display: flex;
		flex-direction: column;
		margin: 0;
	}

	/* Wirkt nur in der schmalen Ansicht. In der breiten liegt die
	   Kopfleiste absolut über der Karte (Abschnitt 8) und ist kein
	   Flex-Item mehr. */
	.geo-header {
		flex: none;
	}

	/* Breite und Innenabstand aus dem Theme zurücksetzen: Die Karte geht
	   bis an den Rand. */
	#main {
		display: flex;
		flex: 1 1 auto;
		flex-direction: column;
		margin: 0;
		max-inline-size: none;
		min-block-size: 0;
		padding: 0;
	}

	#geo-app {
		flex: 1 1 auto;
		gap: 0;
		grid-template-rows: minmax(0, 1fr);
		min-block-size: 0;
	}

	/* Ein Scrollcontainer für Inhalte, Informationen, Darstellung und
	   Pflichtlinks — als Spalte (7a) wie als Leiste (7b). Die grid-area
	   der Kinder (Abschnitt 6) greift hier nicht, sie stehen im Fluss der
	   Leiste.

	   position: relative macht die Leiste zum Containing Block ihrer absolut
	   positionierten Nachkommen — vor allem .screen-reader-only aus dem
	   Theme (die Legenden unter "Darstellung"). Ohne das schneidet
	   overflow sie nicht ab: Ihr Containing Block liegt dann außerhalb der
	   Leiste, und sie zählen zum Scrollbereich der Seite. Bei einer langen
	   Objektauskunft rutschten sie unter die Fensterkante, und die Seite
	   scrollte. In 7b ersetzt absolute den Wert und leistet dasselbe. */
	.geo-sidebar {
		background-color: var(--c-canvas);
		display: flex;
		flex-direction: column;
		gap: var(--gap-m);
		overflow-y: auto;
		overscroll-behavior: contain;
		padding: var(--gap-m) 1.2rem var(--gap-s) 1.2rem;
		position: relative;
		scrollbar-gutter: stable;
	}

	/* Pflichtlinks ans Ende der Leiste, auch wenn sie nicht voll ist. */
	.geo-legal {
		margin-block-start: auto;
	}

	/* Karte und Quellenvermerk in derselben Zelle: Die Karte reicht bis an
	   den unteren Rand, der Vermerk liegt als Leiste darüber. */
	.geo-map__figure {
		display: grid;
		grid-template: minmax(0, 1fr) / minmax(0, 1fr);
		min-block-size: 0;
	}

	#geo-map,
	.geo-map__figure .figcaption {
		grid-area: 1 / 1;
	}

	/* Höhe aus der Grid-Zelle statt 70svb. MapLibre braucht eine bestimmte
	   Höhe; die liefert die Kette body → #main → #geo-app. */
	#geo-map {
		block-size: auto;
		min-block-size: 0;
	}

	.geo-map__figure .figcaption {
		align-self: end;
		background-color: oklch(from var(--c-canvas) l c h / .75);
		color: var(--c-prominent);
		font-size: var(--f-size-2xs);
		line-height: 1.2;
		padding: .2rem;
		position: relative;
		z-index: 2;
	}

	/* Controls unten über den Vermerk. Die Höhe misst js/map.js. */
	.maplibregl-ctrl-bottom-left,
	.maplibregl-ctrl-bottom-right {
		inset-block-end: var(--geo-quellen-hoehe, 0px);
	}
}

/* --- 7a. Breite Ansicht: Seitenleiste als Spalte ----------------------- */

/* Dieselbe Bedingung wie Abschnitt 8. */
@media screen and (width >= 70rem) and (height >= 30rem) {

	:root {
		--geo-ansicht: breit;
	}

	.geo-header {
		padding: var(--gap-s) var(--gap-s) var(--gap-s) 1.2rem;
	}

	.geo-header__brand {
		font-size: var(--f-size-m);
		line-height: 1.2;
	}

	#geo-app {
		grid-template-areas: "sidebar map";
		grid-template-columns: var(--geo-sidebar-breite) minmax(0, 1fr);
	}

	.geo-sidebar {
		grid-area: sidebar;
	}

	.geo-toolbar .input__group:has(.icon) .input,
	.geo-toolbar .input__group:has(.icon) .input:is(:focus-visible, :not(:placeholder-shown)) {
		border-color: transparent;
	}
}

/* --- 7b. Schmale Ansicht: Seitenleiste als Leiste über der Karte ------- */

/* Range-Syntax mit "<" statt max-width: max-width schlösse den Grenzwert
   ein, und bei genau 70rem gälten 7a und 7b zugleich. */
@media screen and (width < 70rem) and (height >= 30rem) {

	:root {
		--geo-ansicht: schmal;
	}

	/* Der Knopf für die Leiste tritt an die Stelle von "Gesamten
	   Amtsbereich anzeigen": vorn in der Werkzeugleiste, links neben dem
	   Suchfeld, auf der Seite, von der die Leiste einfährt. Den Amtsbereich
	   braucht es hier nicht als Knopf — auf dem Touchscreen ist er mit zwei
	   Fingern schneller erreicht.

	   Hier die Klasse und nicht die ID: Zwei Klassen genügen, um
	   ".geo-header .button" (Abschnitt 5) zu schlagen, das weiter oben steht
	   und display: inline-flex setzt. Den Knopf für die Leiste blendet
	   js/panel.js über [hidden] ein (Abschnitt 3). */
	.geo-header .button--maximize {
		display: none;
	}

	/* Trefferliste über die ganze Breite, mit gleichem Abstand links und
    rechts. Bezugsrahmen ist hier die Kopfleiste und nicht die
    Werkzeugleiste (Abschnitt 5): Die Werkzeugleiste verliert ihre
    Positionierung, damit die Liste nicht mehr am Aufbau der Leiste hängt.
    Die Kopfleiste ist positioniert (sticky, Abschnitt 4) und so breit wie
    der Viewport.

    Der Abstand ist der Innenabstand der Kopfleiste: Die Liste fluchtet
    links mit dem Knopf für die Leiste und rechts mit dem Menü-Knopf.
    100 % in inset-block-start ist damit die Höhe der Kopfleiste; die
    Liste beginnt knapp unter ihr. */
	.geo-toolbar {
		position: static;
	}

	#geo-treffer-box {
		inset-inline: var(--gap-s);
	}

	/* Eine Zelle für die Karte; die Leiste liegt absolut darüber und ist
	   kein Grid-Item. position: relative macht #geo-app zu ihrem Containing
	   Block.

	   Kein eigener Stapelkontext (isolation): Abdeckung und Leiste müssen
	   über der Kopfleiste liegen können, und ein Stapelkontext an #geo-app
	   hielte beide darunter. */
	#geo-app {
		grid-template-areas: "map";
		grid-template-columns: minmax(0, 1fr);
		position: relative;
	}

	/* Abdeckung hinter der offenen Leiste; js/panel.js legt sie an. Über
	   dem ganzen Viewport, auch über der Kopfleiste: Ein Tipp daneben
	   trifft sie und schließt die Leiste, statt in Karte oder Suche zu
	   landen. Ein- und ausgeblendet über [hidden], deshalb kein display.

	   Stapelung: Controls von MapLibre 2, Kopfleiste 3, Abdeckung 4,
	   Leiste 5.

	   Die Farbe ist ein Startwert. Hell genug, dass die Wirkung einer
	   geschalteten Ebene neben der Leiste zu sehen bleibt. */
	.geo-app__abdeckung {
		background-color: oklch(0 0 0 / .25);
		inset: 0;
		position: fixed;
		z-index: 4;
	}

	/* Nicht so breit wie der Viewport: Rechts bleibt ein Streifen Karte
	   sichtbar. Er zeigt, dass die Leiste über der Karte liegt; ein Tipp
	   darauf trifft die Abdeckung und schließt sie (js/panel.js). */
	.geo-sidebar {
		inline-size: min(22rem, 85%);
		inset-block: 0;
		inset-inline-start: 0;
		position: absolute;
		z-index: 5;
	}

	/* Schließen oben rechts in der Leiste und beim Scrollen stehend, wie im
	   Sheet. Den Hintergrund braucht es, weil der Inhalt beim Scrollen
	   darunter durchläuft. */
	.geo-sidebar__close {
		align-self: flex-end;
		flex: none;
		inset-block-start: 0;
		position: sticky;
		z-index: 1;
	}

	.button.geo-header__menu {
		background: none;
		color: var(--c-primary);
	}

	.icon.icon-menu {
		block-size: 1.6rem;
	}

	/* visibility ohne eigene Dauer, aber mit Verzögerung beim Schließen:
	   Beim Öffnen ist die Leiste sofort sichtbar — sonst nähme die
	   Schaltfläche "Schließen" den Fokus nicht an, den js/panel.js im selben
	   Moment setzt. Beim Schließen bleibt sie sichtbar, bis sie hinaus-
	   gefahren ist. Es gilt jeweils die transition des Zielzustands. */
	@media (prefers-reduced-motion: no-preference) {
		.geo-sidebar {
			transition: translate .2s ease-out, visibility 0s linear .2s;
		}

		.geo-sidebar.ist-offen {
			transition: translate .2s ease-out, visibility 0s;
		}
	}
}

/* Geschlossen nur mit JavaScript: Ohne Skript gibt es keinen Knopf, und
   die Pflichtlinks in der Leiste müssen erreichbar bleiben.

   visibility statt display (Begründung in js/panel.js, Abschnitt
   "Seitenleiste als Leiste"): Das Sheet der Objektauskunft steckt in der
   Leiste und muss sich auch bei geschlossener Leiste zeigen können
   (Abschnitt 6). visibility nimmt die Leiste zugleich aus Tab-Reihenfolge
   und Barrierefreiheitsbaum. Die Verschiebung nach links erzeugt keinen
   Scrollbereich; Überlauf nach links ist nicht scrollbar.

   (scripting: enabled) ab Chrome 120, Firefox 113, Safari 17. Ältere
   Engines ignorieren die Regel; die Leiste steht dort offen. */
@media screen and (width < 70rem) and (height >= 30rem) and (scripting: enabled) {
	.geo-sidebar:not(.ist-offen) {
		translate: -100% 0;
		visibility: hidden;
	}

}

/* Smartphone: schmale Ansicht unter 40rem (640px bei 16px Browserschrift).
   Die Werkzeugleiste wird eine Zeile aus Leiste, Suchfeld und Hilfe.

   Ausgeblendet:
   - "Suchen": Die Suche läuft beim Tippen, und die Bildschirmtastatur hat
     eine eigene Suchen-Taste (enterkeyhint="search"); Enter behandelt
     js/panel.js.
   - Link kopieren und Drucken: Die Adresse trägt den ganzen Zustand
     (schreibeUrl() in js/panel.js), das Teilen-Menü des Browsers gibt also
     denselben Permalink weiter. Gedruckt wird über das Browsermenü; die
     Druckansicht entsteht dann bei 'beforeprint' (js/druck.js).

   Zwei Klassen genügen gegen ".geo-header .button" (Abschnitt 5), weil
   diese Regel später steht. */
@media screen and (width < 37rem) and (height >= 30rem) {

	.geo-header .button--search,
	.geo-header .geo-toolbar__actions {
		display: none;
	}

	/* Das Suchfeld füllt den Rest der Zeile. Die feste Breite aus
	   Abschnitt 5 (Platzhalter in voller Länge) gilt hier nicht. */
	.geo-toolbar__search {
		flex: 1 1 auto;
	}

	/* Das Suchfeld füllt seine Gruppe ganz aus. 100 % statt auto: auto
	   streckt nur in einem Flex-Container, und als welcher die Gruppe im
	   Theme gesetzt ist, ist hier nicht festgelegt. Ein <input> mit auto
	   bliebe sonst bei seiner Eigenbreite. max-inline-size gegen eine
	   Begrenzung aus dem Theme. */
	.geo-toolbar .input__group:has(.icon) .input,
	.geo-toolbar .input__group:has(.icon) .input:is(:focus-visible, :not(:placeholder-shown)) {
		flex: 1 1 auto;
		inline-size: 100%;
		max-inline-size: none;
	}
}

.maplibregl-ctrl.geo-map__zoomlevel {
	background-color: oklch(1 0 270 / .75);
	color: #404040;
	padding-inline: 6px;
}

.maplibregl-ctrl.geo-map__zoomlevel,
.maplibregl-ctrl-scale {
	font-size: .6rem;
}

/* --- 8. Kopfleiste über der Karte -------------------------------------- */

/* Nur in der breiten Ansicht, mit einzeiliger Kopfleiste. Dieselbe
   Bedingung wie Abschnitt 7a. Muss nach Abschnitt 4 stehen: absolute löst
   dort sticky ab. */
@media screen and (width >= 70rem) and (height >= 30rem) {

	:root {
		/* Höhe der Kopfleiste, geschätzt. Bei Bedarf im Inspektor
		   nachmessen oder wie den Quellenvermerk in js/map.js messen. */
		--geo-header-hoehe: 3.5rem;
	}

	.geo-header {
		inset: 0 0 auto;
		pointer-events: none;
		position: absolute;
	}

	/* Alle Kinder wieder bedienbar, auch der Menü-Dialog. pointer-events
	   wird vererbt; ohne diese Regel wären auch Suchfeld und Knöpfe tot. */
	.geo-header > * {
		pointer-events: auto;
	}

	/* Die Werkzeugleiste nur so breit wie ihr Inhalt. Sonst überdeckte ihr
	   Kasten die ganze Spalte zwischen Titel und Menü und finge dort die
	   Klicks in die Karte ab. */
	.geo-toolbar {
		justify-self: end;
	}

	/* Logo und Titel liegen über der Seitenleiste. */
	.geo-sidebar {
		padding-block-start: calc(var(--geo-header-hoehe) + var(--gap-m));
	}

	/* Karten-Controls oben unter die Kopfleiste. */
	.maplibregl-ctrl-top-left,
	.maplibregl-ctrl-top-right {
		inset-block-start: var(--geo-header-hoehe);
	}

	.geo-header {
		background: linear-gradient(
			to right,
			var(--c-canvas) var(--geo-sidebar-breite),
			color-mix(in srgb, var(--c-canvas) 0%, transparent) 0
		);
	}
}


/* --- 9. Menü-Dialog ---------------------------------------------------- */

.geo-menu {
	block-size: 100dvb;
	inline-size: min(24rem, 100%);
	inset: 0 0 0 auto;
	margin: 0;
	max-block-size: none;
	max-inline-size: none;
	overflow-y: auto;
	padding: var(--gap-m);
	position: fixed;
}

.geo-menu[open] {
	display: flex;
	flex-direction: column;
	gap: var(--gap-m);
}

.geo-menu__close {
	align-self: flex-end;
}

/* Bausteine der Website im Dialog. Der Header der Website zeigt Navigation
   und Suche je nach Breite verschieden; hier sollen beide immer offen und
   untereinander stehen. Die Werte setzen nur zurück — welche Theme-Regeln
   dagegenhalten, zeigt der Inspektor. */
.geo-menu .site__navigation,
.geo-menu .search-container {
	display: block;
	position: static;
}

.geo-menu .site-menu,
.geo-menu .site-submenu {
	display: grid;
	gap: var(--gap-2xs);
}

.geo-menu .site-submenu {
	padding-inline-start: var(--gap-m);
	position: static;
}

/* --- 10. Geo Help ---------------------------------------------------- */

.geo-help {
	all: unset;
	display: revert;
}

.geo-help {
	--geo-help-column: 60ch;

	background: var(--c-canvas);
	block-size: fit-content;
	border-radius: 2px;
	font-family: abco-serif, fbserif, serif;
	hyphens: auto;
	inset: 2vw 2vw auto;
	margin-inline: auto;
	max-inline-size: calc(3 * var(--geo-help-column) + 2 * var(--gap-m));
	padding: var(--gap-m);
	position: absolute;
	opacity: 0;
	transform: scale(0.9);
	transition:
			opacity 0.4s ease,
			transform 0.4s ease,
			display 0.4s ease allow-discrete;
}

.geo-help::backdrop {
	background: oklch(0 .1 270 / .2);
	opacity: 0;
	transition:
			opacity 0.4s ease,
			display 0.4s ease allow-discrete;
}

.geo-help[open] {
	display: flex;
	flex-direction: column;
	opacity: 1;
	transform: scale(1);
}

@starting-style {
	.geo-help[open] {
		opacity: 0;
		transform: scale(0.9);
	}
}

.geo-help[open]::backdrop {
	opacity: 1;
}

@starting-style {
	.geo-help[open]::backdrop {
		opacity: 0;
	}
}
.geo-help__content {
	columns: var(--geo-help-column) 3;
	column-gap: var(--gap-m);
	column-rule: 1px solid var(--c-canvas-subtle);
}

.geo-help .geo-heading {
	border: none;
	font-size: var(--f-size-xl);
}

.geo-help .subheading {
	font-family: abco-sans, fbsans, sans-serif;
}

.geo-help .button {
	block-size: auto;
}

html:has(.geo-help[open]) body {
	filter: blur(5px) opacity(0.5);
}

.geo-help p {
	letter-spacing: -.003em;
	margin-block-end: .75lh;
}

.geo-help dt {
	font-style: italic;
 }

.geo-help dd {
	margin-inline-start: .75lh;
	margin-block-end: .75lh;
}

.geo-help code {
	background: var(--c-canvas-subtle);
	border-radius: 2px;
	color: var(--c-code);
	font-family: abco-mono, monospace;
	font-size: var(--f-size-s);
	font-weight: 450;
	hyphens: none;
	padding: .1em .3em;
}

.button.geo-hilfe__schliessen {
	align-self: self-end;
	font-family: abco-sans, sans-serif;
	inline-size: fit-content;
	padding-inline: var(--gap-xs);
}

/* --- 11. Geo Druck ---------------------------------------------------- */

@media print {
    /* Theme-Rahmen und alles neben der Anwendung */
    body > :not(#main),
    #main > :not(#geo-app),
    #geo-app > :not(.geo-druck) {
        display: none;
    }

    #geo-app {
        display: block;          /* Grid aufheben */
    }

    .geo-druck {
        display: block;          /* hebt [hidden] auf */
        padding-inline: 1px;
    }

    .geo-druck__karte {
        display: block;
        inline-size: 100%;
        block-size: auto;
        break-inside: avoid;
    }

    .geo-druck__objekt,
    .geo-druck__angaben {
        break-inside: avoid;
        margin-block-end: var(--gap-m);
    }

    .geo-druck__angaben dd {
        overflow-wrap: anywhere; /* der Permalink ist lang */
    }

    .geo-druck .geo-druck__quellen {
    	color: var(--c-secondary);
    	/*font-size: var(--f-size-2xs);*/
    	font-size: .7rem;
    	hyphens: auto;
    	line-height: 1.1;
    	margin-block-start: var(--gap-xs);
    }

    .geo-druck__quellen .link {
    	color: var(--c-secondary);
    	text-decoration: none;
    }

    .geo-druck__quellen span:first-child,
    .geo-druck__quellen .maplibre,
    .geo-druck__angaben,
    .geo-druck .geo-heading {
  		display: none;
	}

	.geo-druck .geo-objectinfo dl {
		font-size: var(--f-size-s);
	    grid-template-columns: auto 1fr auto 1fr;
		hyphens: auto;
	}

	.geo-druck__meta {
			display: flex;
			gap: var(--gap-m);
			margin-block-start: var(--gap-m);
	}

	.geo-druck__qr {
		flex: none;
		inline-size: 25mm;
		block-size: 25mm;
	}

	.geo-druck__meta-text {
		display: flex;
		flex: 1;
		flex-direction: column;
		font-size: var(--f-size-s);
		justify-content: space-evenly;
		min-inline-size: 0;
	}

	.geo-druck__link {
		font-variant-ligatures: none;
		line-height: 1.2;
	  	overflow-wrap: anywhere;
	}

	.geo-druck__karte {
		border: 1px solid #000;
	    display: block;
	    inline-size: auto;
	    max-inline-size: 100%;
	/*    max-block-size: 160mm;*/
	}

	@page {
	    size: A4 portrait;
	    margin-block-start: 20mm;
    }
/*
    #geo-app {
        display: grid;
        align-content: center;
        min-block-size: 265mm;
    }
*/
    html,
    body,
    #main {
        margin: 0;
        padding: 0;
        block-size: auto;
        min-block-size: 0;
    }
}

/* --- 12. Allgemeines ---------------------------------------------------- */

.geo-heading {
	border-block-end: 1px solid oklch(from currentcolor l c h / .25);
	font-family: abco-sans, fbsans, sans-serif;
	font-size: var(--f-size-l);
	font-weight: var(--f-weight-bd);
	margin-block-end: .5lh;
}

.button.button--search {
	font-weight: var(--f-weight-lb);
}

.geo-panel  {
	display: grid;
	gap: var(--gap-m);
}

.geo-panel__group::details-content {
	block-size: 0;
	overflow: clip;
	transition: block-size .2s ease-out,
	content-visibility .2s allow-discrete;
}

.geo-panel__group[open]::details-content {
	block-size: auto;
}

.geo-panel__group .icon-chevron {
	rotate: -90deg;
	transition: rotate .15s ease-out;
}

.geo-panel__group[open] > summary .icon-chevron {
	rotate: 0deg;
}

.geo-panel__group > summary {
	align-items: start;
	cursor: pointer;
	display: flex;
	gap: var(--gap-xs);
}

.geo-panel .icon.icon-chevron {
	aspect-ratio: 1;
	stroke: currentcolor;
	stroke-width: 2px;
	flex-shrink: 0;
	block-size: 1lh;
	inline-size: 1em;
}

.geo-panel__notice {
	color: var(--c-secondary);
	font-size: var(--f-size-2xs);
	grid-column: 2;
	line-height: 1.2;
}

.geo-panel__content .geo-panel__option {
	margin-inline-start: calc(1em + var(--gap-xs));
}

.geo-panel__objectinfo .geo-leer {
	color: var(--c-secondary);
	line-height: 1.3;
	text-wrap: balance;
}

.geo-objectinfo dl {
	border-block-start: 1px solid var(--c-canvas-subtle);
	display: grid;
	font-size: var(--f-size-s);
	grid-template-columns: fit-content(35%) minmax(0, 1fr);
	hyphens: auto;
	margin-block-start: .25rem;
}

.geo-objectinfo dt {
	color: var(--c-secondary);
	hyphens: manual;
	padding-inline-end: var(--gap-s);
}

.geo-objectinfo dt,
.geo-objectinfo dd {
	padding-block: var(--gap-2xs);
}

.geo-objectinfo dt:not(:last-of-type),
.geo-objectinfo dd:not(:last-of-type) {
	border-block-end: 1px solid var(--c-canvas-subtle);
}

.geo-objectinfo__title {
	font-weight: var(--f-weight-mb);
}

.geo-objectinfo__source {
	border-block-start: 1px solid var(--c-canvas-subtle);
	color: var(--c-secondary);
	font-size: var(--f-size-2xs);
	line-height: 1.2;
	padding-block-start: var(--gap-xs);
}

.geo-objectinfo__source + .geo-leer {
	border-block-start: 1px solid var(--c-canvas-subtle);
	margin-block-start: var(--gap-s);
	padding-block-start: var(--gap-s);
}

.geo-panel__option {
	align-items: center;
	display: grid;
	grid-template-columns: auto 1fr;
}

.geo-panel__group + .geo-panel__group {
	margin-block-start: .25lh;
}

.geo-panel .input {
	align-self: stretch;
	border: 1px solid var(--c-secondary);
	border-radius: var(--radius);
	corner-shape: squircle;
}

.geo-panel .input__group--search {
	flex: 1;
	flex-wrap: nowrap;
}

.geo-panel .input__group--search .input.input--search {
	flex: 0 1 auto;
	inline-size: 26ch;
	min-inline-size: 14ch;
	padding-inline: var(--gap-s) var(--gap-xs);
}

.geo-panel .input:focus-visible {
	border: 1px solid transparent;
	outline: 2px solid var(--c-accent);
	outline-offset: -1px;
}

.geo-panel select {
	align-items: center;
	appearance: auto;
	border: 1px solid var(--c-secondary);
	border-radius: var(--radius);
	corner-shape: squircle;
	display: inline-flex;
	min-inline-size: 21ch;
	padding-inline-start: var(--gap-xs);
}

.geo-panel select:focus-visible {
	border: 1px solid transparent;
	outline-offset: 0;
}

.geo-panel option {
	background-color: Field;
	color: FieldText;
}

.geo-panel__option > input {
	appearance: auto;
	accent-color: var(--c-accent);
	block-size: .6lh;
	grid-column: 1;
	inline-size: 1em;
	margin-inline-end: var(--gap-xs);
}

.geo-panel__option > label {
	grid-column: 2;
	display: flex;
	align-items: center;
	cursor: pointer;
}

.geo-panel .geo-panel__deselect {
    block-size: fit-content;
    margin-block-start: var(--gap-s);
    padding: var(--gap-2xs) var(--gap-xs);
}

[data-ebene="standorte-jugend"] input,
[data-ebene="standorte-kultur"] input,
[data-ebene="standorte-sport"] input,
[data-ebene="standorte-verwaltung"] input,
[data-ebene="standorte-brandschutz"] input {
    accent-color: var(--geo-legende-farbe);
}

