/* ---------------------------------------------------------------------------
 * pa-base.css - Seitengeruest: Kopfleiste, Inhaltsbereich, Fusszeile,
 * Grundtypografie, Formulare, Tabellen, Fokus.
 *
 * Gilt fuer ALLE Rollen. Was nur den Kundenpfad betrifft (Galerieraster,
 * Warenkorb, Codeeingabe), steht in pa-kundengalerie.css.
 *
 * Ersetzt das gekaufte Bootstrap-3-Shoptemplate "T-Shop" (style.css mit 4.342
 * Zeilen fuer Karussells, Parallax, Wunschlisten und Markenslider - nichts
 * davon wurde je gerendert). Von dessen Klassen brauchte die Anwendung
 * tatsaechlich rund 34; die sind hier neu gebaut statt weitergeschleppt.
 * --------------------------------------------------------------------------- */

/* ===========================================================================
 * 1. Grundlagen
 * ======================================================================== */

*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	/* Damit Sprungmarken nicht unter der klebenden Kopfleiste landen. */
	scroll-padding-top: calc(var(--pa-header-height) + var(--pa-space-4));
}

body {
	margin: 0;
	font-family: var(--pa-font);
	font-size: var(--pa-text-base);
	line-height: var(--pa-leading);
	color: var(--pa-ink);
	background-color: var(--pa-surface-sunken);
	-webkit-text-size-adjust: 100%;
	text-rendering: optimizeLegibility;

	/* Fusszeile unten halten, ohne sie aus dem Fluss zu nehmen. Vorher stand
	 * dort `position: fixed; bottom: 0` - die Zeile lag damit dauerhaft ueber
	 * dem Inhalt und verdeckte auf niedrigen Fenstern die letzte Zeile einer
	 * Tabelle oder den Bestellknopf. */
	/* 100dvh statt 100vh: auf dem Telefon zaehlt vh die Adressleiste mit,
	 * die beim Scrollen verschwindet - die Seite waere dann immer ein
	 * Stueck zu hoch. dvh misst, was wirklich sichtbar ist. vh bleibt als
	 * Rueckfall fuer Browser ohne dvh davor stehen. */
	min-height: 100vh;
	min-height: 100dvh;
	display: flex;
	flex-direction: column;
}

h1, h2, h3, h4, h5, h6 {
	margin: 0 0 var(--pa-space-3);
	font-weight: 600;
	line-height: var(--pa-leading-tight);
	color: var(--pa-navy);
	text-wrap: balance;
}

h1 { font-size: var(--pa-text-3xl); }
h2 { font-size: var(--pa-text-2xl); }
h3 { font-size: var(--pa-text-xl); }
h4 { font-size: var(--pa-text-lg); }
h5, h6 { font-size: var(--pa-text-base); }

p {
	margin: 0 0 var(--pa-space-4);
}

a {
	color: var(--pa-link);
	text-decoration: none;
	transition: color var(--pa-duration) var(--pa-ease);
}

a:hover {
	color: var(--pa-link-hover);
	text-decoration: underline;
}

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

/* Ein sichtbarer, einheitlicher Fokusring. Vorher stand im Template
 * `outline: none !important` auf allen Links - wer mit der Tastatur
 * unterwegs war, sah schlicht nicht, wo er stand. */
:focus-visible {
	outline: 3px solid var(--pa-accent);
	outline-offset: 2px;
	border-radius: var(--pa-radius-sm);
}

/* Wer die Maus benutzt, soll den Ring nicht sehen - :focus-visible regelt
 * das, aber Safari braucht die ausdruckliche Ruecknahme. */
:focus:not(:focus-visible) {
	outline: none;
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* ===========================================================================
 * 2. Seitengeruest
 * ======================================================================== */

.pa-shell {
	flex: 1 0 auto;
	width: 100%;
	max-width: var(--pa-container-max);
	margin-inline: auto;
	padding: var(--pa-space-6) var(--pa-space-4) var(--pa-space-8);
}

@media (max-width: 575.98px) {
	.pa-shell {
		padding: var(--pa-space-4) var(--pa-space-3) var(--pa-space-6);
	}
}

/* Seitenueberschrift. Ersetzt `.section-title.style2` aus dem Template
 * (zwei graue Linien ueber und unter Versalien). */
.pa-page-title {
	margin: 0 0 var(--pa-space-5);
	font-size: var(--pa-text-2xl);
	font-weight: 600;
	color: var(--pa-navy);
	letter-spacing: -0.01em;
}

.pa-page-title::after {
	content: "";
	display: block;
	width: 48px;
	height: 3px;
	margin-top: var(--pa-space-3);
	border-radius: var(--pa-radius-pill);
	background: var(--pa-accent);
}

/* ===========================================================================
 * 3. Kopfleiste
 *
 * Das Wichtigste an diesem Abschnitt: die Navigation ist auf dem Telefon
 * erreichbar. Vorher trug der Hamburger-Knopf `navbar-toggle hidden-xs` -
 * Bootstrap versteckt `.navbar-toggle` ab 768 px, `hidden-xs` darunter, der
 * Knopf war also in KEINER Fensterbreite sichtbar. Die Navigationsliste
 * selbst war ebenfalls `hidden-xs`. Auf dem Handy fehlten damit Galerie,
 * Fotografenprofil, Preisliste und Slideshow vollstaendig.
 * ======================================================================== */

.pa-header {
	position: sticky;
	top: 0;
	z-index: var(--pa-z-header);
	background: var(--pa-navy);
	box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06),
	            0 2px 12px rgba(0, 0, 0, 0.18);
}

.pa-header__bar {
	display: flex;
	align-items: center;
	gap: var(--pa-space-3);
	width: 100%;
	max-width: var(--pa-container-max);
	margin-inline: auto;
	min-height: var(--pa-header-height);
	padding-inline: var(--pa-space-4);
}

@media (max-width: 575.98px) {
	.pa-header__bar {
		padding-inline: var(--pa-space-3);
	}
}

/* --- Logo ----------------------------------------------------------------- */

.pa-header__brand {
	display: flex;
	align-items: center;
	flex: none;
	margin-right: auto;
	padding-block: var(--pa-space-2);
}

.pa-header__brand img {
	display: block;
	width: auto;
	height: 34px;
}

@media (max-width: 480px) {
	/* Auf dem Telefon muss die Leiste in 390 px passen, und sie enthaelt
	 * Logo, Benutzerbereich, Warenkorb und Hamburger. Nachgemessen brauchte
	 * sie 421 px - die Seite lief damit auf JEDER Seite mit geladener
	 * Galerie waagerecht ueber. Das Logo ist mit rund 6:1 sehr breit;
	 * begrenzt man die Breite statt der Hoehe, skaliert es passend mit. */
	.pa-header__brand img {
		height: auto;
		max-width: 130px;
	}

	.pa-header__bar {
		gap: var(--pa-space-2);
		padding-inline: var(--pa-space-2);
	}
}

/* --- Hamburger ----------------------------------------------------------- */

.pa-burger {
	display: none;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 42px;
	height: 42px;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, 0.22);
	border-radius: var(--pa-radius-sm);
	background: transparent;
	color: #fff;
	cursor: pointer;
	transition: background-color var(--pa-duration) var(--pa-ease);
}

.pa-burger:hover {
	background: rgba(255, 255, 255, 0.1);
}

.pa-burger__bars,
.pa-burger__bars::before,
.pa-burger__bars::after {
	display: block;
	width: 20px;
	height: 2px;
	border-radius: 2px;
	background: currentColor;
	transition: transform var(--pa-duration) var(--pa-ease),
	            opacity var(--pa-duration) var(--pa-ease);
}

.pa-burger__bars {
	position: relative;
}

.pa-burger__bars::before,
.pa-burger__bars::after {
	content: "";
	position: absolute;
	left: 0;
}

.pa-burger__bars::before { top: -6px; }
.pa-burger__bars::after  { top: 6px; }

/* Aufgeklappt wird aus den drei Strichen ein Kreuz - der Knopf sagt damit,
 * was er als naechstes tut. */
.pa-burger[aria-expanded="true"] .pa-burger__bars {
	background: transparent;
}

.pa-burger[aria-expanded="true"] .pa-burger__bars::before {
	top: 0;
	transform: rotate(45deg);
}

.pa-burger[aria-expanded="true"] .pa-burger__bars::after {
	top: 0;
	transform: rotate(-45deg);
}

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

.pa-header__nav {
	display: flex;
	align-items: center;
	gap: var(--pa-space-1);
}

/* Ab 992px steht die Navigation offen in der Leiste.
 *
 * Das `!important` ist hier nicht Bequemlichkeit: das Element traegt
 * Bootstraps Klasse `collapse`, und die setzt `display: none`, solange nicht
 * `show` dazukommt - in JEDER Fensterbreite. Ohne diese Regel waere die
 * Navigation auch auf dem Desktop unsichtbar. Bootstrap loest das bei seiner
 * eigenen navbar genauso. */
@media (min-width: 992px) {
	.pa-header__nav.collapse {
		display: flex !important;
	}
}

.pa-nav {
	display: flex;
	align-items: center;
	gap: var(--pa-space-1);
	margin: 0;
	padding: 0;
	list-style: none;
}

.pa-nav__link {
	display: flex;
	align-items: center;
	gap: var(--pa-space-2);
	padding: var(--pa-space-2) var(--pa-space-3);
	border-radius: var(--pa-radius-sm);
	color: rgba(255, 255, 255, 0.88);
	font-size: var(--pa-text-sm);
	font-weight: 600;
	white-space: nowrap;
	transition: background-color var(--pa-duration) var(--pa-ease),
	            color var(--pa-duration) var(--pa-ease);
}

.pa-nav__link:hover,
.pa-nav__link:focus-visible {
	background: rgba(255, 255, 255, 0.12);
	color: #fff;
	text-decoration: none;
}

/* Der aktive Punkt wird unten markiert statt flaechig gruen hinterlegt.
 * Weisse Schrift auf #62c40d kommt nur auf 2,23:1 - als Flaeche war das
 * nicht lesbar. Als Markierung unter dem Wort traegt die Farbe dagegen
 * ihre Bedeutung, ohne Text darauf zu setzen. */
.pa-nav__item.is-active .pa-nav__link {
	color: #fff;
	background: rgba(255, 255, 255, 0.1);
	box-shadow: inset 0 -3px 0 var(--pa-accent);
}

/* --- Benutzerbereich der Leiste ------------------------------------------ */

.pa-header__user {
	display: flex;
	align-items: center;
	gap: var(--pa-space-2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.pa-header__user > li {
	display: flex;
}

.pa-user-link {
	display: flex;
	align-items: center;
	gap: var(--pa-space-2);
	padding: var(--pa-space-2) var(--pa-space-3);
	border-radius: var(--pa-radius-sm);
	color: rgba(255, 255, 255, 0.78);
	font-size: var(--pa-text-sm);
	white-space: nowrap;
	cursor: pointer;
}

.pa-user-link:hover,
.pa-user-link:focus-visible {
	background: rgba(255, 255, 255, 0.1);
	color: #fff;
	text-decoration: none;
}

/* Anmelden ist ein Knopf, nicht ein Textlink zwischen Textlinks. Das
 * gedaempfte Gruen statt #62c40d, weil weisse Schrift darauf lesbar sein
 * muss - siehe pa-tokens.css. */
.pa-login-btn {
	background: var(--pa-primary);
	color: #fff;
	font-weight: 600;
}

.pa-login-btn:hover,
.pa-login-btn:focus-visible {
	background: var(--pa-primary-hover);
	color: #fff;
}

/* --- Warenkorb in der Leiste --------------------------------------------- */

.pa-cart {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--pa-space-2);
	flex: none;
	padding: var(--pa-space-2) var(--pa-space-3);
	border: 1px solid rgba(255, 255, 255, 0.22);
	border-radius: var(--pa-radius-sm);
	background: transparent;
	color: #fff;
	font-size: var(--pa-text-sm);
	font-weight: 600;
	cursor: pointer;
	white-space: nowrap;
}

.pa-cart:hover,
.pa-cart:focus-visible {
	background: rgba(255, 255, 255, 0.12);
	color: #fff;
	text-decoration: none;
}

.pa-cart .pa-icon {
	font-size: 1.1em;
}

/* Auf schmalen Fenstern bleibt nur das Symbol samt Zaehler - das Wort
 * "Warenkorb" kostet dort Platz, den die Kopfleiste nicht hat. */
@media (max-width: 480px) {
	.pa-cart__label {
		display: none;
	}
}

.pa-cart__count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 1.5em;
	height: 1.5em;
	padding-inline: 0.4em;
	border-radius: var(--pa-radius-pill);
	background: var(--pa-accent);
	/* Dunkle Schrift auf dem hellen Gruen - so traegt der Akzent den
	 * Zaehler lesbar (9,1:1), was er in Weiss nicht koennte. */
	color: #1b2b0a;
	font-size: var(--pa-text-xs);
	font-weight: 700;
	line-height: 1;
}

/* Der Warenkorbauszug haengt als Dropdown an der Leiste. Auf dem Telefon
 * nimmt er die volle Breite, damit die Zeilen nicht umbrechen. */
.pa-cart-panel {
	width: min(420px, calc(100vw - 2 * var(--pa-space-3)));
	max-height: min(70vh, 520px);
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 0;
	border: 0;
	border-radius: var(--pa-radius);
	box-shadow: var(--pa-shadow-lg);
}

/* ---------------------------------------------------------------------------
 * Umschaltpunkt der Kopfleiste
 *
 * Unterhalb von 992 px klappt die Navigation zusammen. Der Wert liegt hoeher
 * als Bootstraps ueblicher 768er, weil die Fotografen- und Adminmenues lange
 * Beschriftungen tragen ("Galerien verwalten", "Preislisten verwalten") und
 * auf dem Tablet quer sonst umbrechen.
 * ------------------------------------------------------------------------- */

@media (max-width: 991.98px) {
	.pa-burger {
		display: flex;
	}

	.pa-header__nav {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		display: block;
		max-height: calc(100vh - var(--pa-header-height));
		overflow-y: auto;
		padding: var(--pa-space-3);
		background: var(--pa-navy-dark);
		box-shadow: 0 12px 24px rgba(0, 0, 0, 0.28);
	}

	/* Solange Bootstrap die Klappe geschlossen haelt, bleibt sie unsichtbar -
	 * `collapse` erledigt das, hier nur die Darstellung im offenen Zustand.
	 *
	 * Nur .pa-nav wird hier zur Spalte. Der Benutzerbereich NICHT: der liegt
	 * bewusst in der Leiste und nicht in der Klappe (siehe Markup) - als
	 * Spalte machte er die Leiste dreizeilig und 473 px breit, womit die
	 * ganze Seite auf dem Telefon waagerecht ueberlief. */
	.pa-nav {
		flex-direction: column;
		align-items: stretch;
		gap: var(--pa-space-1);
	}

	.pa-nav__link {
		padding: var(--pa-space-3) var(--pa-space-3);
		font-size: var(--pa-text-base);
	}

	/* Fingergerechte Trefferflaeche: mindestens 44 px hoch. */
	.pa-nav__link,
	.pa-user-link,
	.pa-cart {
		min-height: 44px;
	}

	/* Der Benutzerbereich bleibt eine Zeile und schrumpft stattdessen auf
	 * seine Symbole.
	 *
	 * Ein Admin hat dort bis zu drei Rollenmenues ("Mein Konto",
	 * "Administration", "Tagesgeschaeft") - mit Beschriftung sind das allein
	 * 460 px. Die Symbole tragen die Bedeutung bereits; die Beschriftung
	 * bleibt fuer Screenreader im Dokument und wird nur unsichtbar gemacht,
	 * nicht entfernt. "Abmelden" behaelt seinen Text: dafuer gibt es im
	 * Symbolsatz kein eigenes Zeichen. */
	.pa-header__user {
		flex-wrap: nowrap;
		gap: 0;
	}

	.pa-header__user .dropdown-toggle .pa-user-link__label {
		position: absolute;
		width: 1px;
		height: 1px;
		padding: 0;
		margin: -1px;
		overflow: hidden;
		clip: rect(0, 0, 0, 0);
		white-space: nowrap;
		border: 0;
	}

	.pa-header__user .dropdown-toggle {
		gap: 0;
		padding-inline: var(--pa-space-2);
	}

	.pa-login-btn {
		justify-content: center;
	}
}

/* ===========================================================================
 * 4. Dropdowns in der Kopfleiste
 * ======================================================================== */

.pa-header .dropdown-menu {
	--bs-dropdown-border-color: transparent;
	--bs-dropdown-border-radius: var(--pa-radius);
	--bs-dropdown-link-active-bg: var(--pa-surface-sunken);
	--bs-dropdown-link-active-color: var(--pa-navy);
	--bs-dropdown-link-hover-bg: var(--pa-surface-sunken);
	--bs-dropdown-font-size: var(--pa-text-sm);
	box-shadow: var(--pa-shadow-lg);
}

/* Der Preislisten-Auszug zeigt Warenkategorien mit Vorschaubild. Fruehere
 * "megamenu-fullwidth"-Konstruktion aus dem Template, jetzt ein normales
 * Raster, das sich nach Platz richtet. */
.pa-catmenu {
	width: min(720px, calc(100vw - 2 * var(--pa-space-3)));
	padding: var(--pa-space-4);
}

.pa-catmenu__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
	gap: var(--pa-space-3);
	margin: 0;
	padding: 0;
	list-style: none;
}

.pa-catmenu__tile {
	display: block;
	padding: var(--pa-space-2);
	border: 1px solid var(--pa-border);
	border-radius: var(--pa-radius-sm);
	color: var(--pa-ink);
	text-align: center;
	transition: border-color var(--pa-duration) var(--pa-ease),
	            box-shadow var(--pa-duration) var(--pa-ease);
}

.pa-catmenu__tile:hover {
	border-color: var(--pa-accent);
	box-shadow: var(--pa-shadow-sm);
	color: var(--pa-ink);
	text-decoration: none;
}

.pa-catmenu__tile img {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: var(--pa-radius-sm);
	margin-bottom: var(--pa-space-2);
}

.pa-catmenu__plain {
	margin: 0;
	padding: 0;
	list-style: none;
}

.pa-catmenu__plain a {
	display: block;
	padding: var(--pa-space-2) var(--pa-space-3);
	border-radius: var(--pa-radius-sm);
	color: var(--pa-ink);
	font-size: var(--pa-text-sm);
}

.pa-catmenu__plain a:hover {
	background: var(--pa-surface-sunken);
	text-decoration: none;
}

/* ===========================================================================
 * 5. Fusszeile
 * ======================================================================== */

.pa-footer {
	flex: none;
	padding: var(--pa-space-5) var(--pa-space-4);
	background: var(--pa-navy-dark);
	color: rgba(255, 255, 255, 0.72);
	font-size: var(--pa-text-sm);
	text-align: center;
}

.pa-footer__links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--pa-space-2) var(--pa-space-4);
	max-width: var(--pa-container-max);
	margin-inline: auto;
}

.pa-footer a {
	color: rgba(255, 255, 255, 0.86);
}

.pa-footer a:hover {
	color: #fff;
	text-decoration: underline;
}

/* ===========================================================================
 * 6. Karten, Formulare, Tabellen
 * ======================================================================== */

.card {
	background: var(--pa-surface);
	box-shadow: var(--pa-shadow-sm);
	border-color: var(--pa-border);
}

.card-header {
	font-weight: 600;
	color: var(--pa-navy);
}

.card + .card {
	margin-top: var(--pa-space-5);
}

/* Aufklappbare Karten (Bestelldetails, Artikelauswahl). Der Pfeil zeigt,
 * in welchem Zustand die Karte ist. */
.pa-collapse-toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--pa-space-3);
	width: 100%;
	padding: 0;
	border: 0;
	background: none;
	color: var(--pa-navy);
	font-weight: 600;
	text-align: left;
	cursor: pointer;
}

.pa-collapse-toggle::after {
	content: "";
	flex: none;
	width: 1em;
	height: 1em;
	background-color: currentColor;
	opacity: 0.55;
	transition: transform var(--pa-duration) var(--pa-ease);
	-webkit-mask: var(--pa-icon-chevron) center / contain no-repeat;
	        mask: var(--pa-icon-chevron) center / contain no-repeat;
	--pa-icon-chevron: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>");
}

.pa-collapse-toggle[aria-expanded="false"]::after {
	transform: rotate(-90deg);
}

/* --- Formulare ----------------------------------------------------------- */

.form-label,
.col-form-label {
	font-weight: 600;
	color: var(--pa-navy);
	font-size: var(--pa-text-sm);
}

.form-control,
.form-select {
	border-color: var(--pa-border-strong);
	color: var(--pa-ink);
}

.form-control:focus,
.form-select:focus {
	border-color: var(--pa-primary);
	box-shadow: 0 0 0 3px rgba(98, 196, 13, 0.25);
}

.form-control::placeholder {
	color: var(--pa-ink-muted);
	opacity: 1;
}

/* Fehlerhafte Felder: Farbe allein genuegt nicht, deshalb zusaetzlich ein
 * kraeftigerer Rahmen. */
.pa-field-error .form-control,
.pa-field-error .form-select {
	border-color: var(--pa-danger);
	border-width: 2px;
}

.pa-field-error__msg {
	display: block;
	margin-top: var(--pa-space-1);
	color: var(--pa-danger);
	font-size: var(--pa-text-sm);
	font-weight: 600;
}

/* Knoepfe als Flexbox, damit Symbol und Beschriftung von selbst Abstand
 * halten - egal ob ein Icon dabei ist oder nicht. */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--pa-space-2);
	font-weight: 600;
}

/* Auf dem Telefon soll die Hauptaktion die Breite nehmen; sie zu treffen
 * ist dort wichtiger als sie klein zu halten. */
@media (max-width: 575.98px) {
	.pa-action-full {
		width: 100%;
	}
}

/* --- Tabellen ------------------------------------------------------------
 * Breite Tabellen scrollen in ihrem eigenen Rahmen, nicht die ganze Seite.
 * Bisher stand `table-responsive` teils am <table> selbst, wo es nach
 * Bootstrap keine Wirkung hat - der Rahmen muss aussen herum liegen. */

.pa-table-scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

/* Dasselbe fuer die Tabellen, die keinen eigenen Rahmen im Markup haben.
 *
 * Das sind die Listen im Fotografen- und Adminbereich - 58 Tabellen in
 * ebenso vielen Markupdateien, teils mit neun Spalten. Auf dem Tablet und
 * dem Telefon schoben sie die GANZE Seite in die Breite: die Galerieliste
 * des Admins ist 862 px breit, die Kopfleiste rutschte damit aus dem Bild
 * und waagerechtes Scrollen betraf das gesamte Dokument statt nur die
 * Tabelle. Die Regel greift den unmittelbaren Eltern der Tabelle, egal wie
 * er heisst.
 *
 * Nur unterhalb von 992 px, wo der Platz wirklich fehlt - auf dem Desktop
 * bleibt alles unveraendert.
 *
 * Ein Rollrahmen schneidet absolut positionierte Kinder ab. Deshalb wurde
 * vorher geprueft, was in diesen Tabellen liegt: Ausklappmenues in Zellen
 * gibt es keine, und die vier Tabellen mit Rueckfragedialog tragen
 * `position: fixed`-Modals - die haengen am Sichtfenster und nicht am
 * Rollrahmen, solange dieser keine Transformation traegt. Genau das ist hier
 * der Fall, und es ist nachgemessen.
 *
 * Ohne `:has()` (Safari vor 15.4) bleibt es beim bisherigen Verhalten. */
@media (max-width: 991.98px) {
	.pa-shell *:has(> table.table) {
		overflow-x: auto;
		-webkit-overflow-scrolling: touch;
	}
}

.table {
	margin-bottom: 0;
	vertical-align: middle;
}

.table > thead {
	background: var(--pa-surface-sunken);
}

.table > thead th {
	padding-block: var(--pa-space-3);
	color: var(--pa-navy);
	font-size: var(--pa-text-sm);
	font-weight: 600;
	text-transform: none;
	white-space: nowrap;
	border-bottom-color: var(--pa-border);
}

.table > tbody td {
	padding-block: var(--pa-space-3);
}

/* --- Sortierbare Spaltenkoepfe -------------------------------------------
 *
 * Der Kopf einer sortierbaren Spalte ist ein Verweis, damit ein Klick die
 * Tabelle umsortiert. Aussehen soll er trotzdem wie ein Spaltenkopf und
 * nicht wie ein Link mitten in der Kopfzeile: er erbt Farbe und Gewicht der
 * Zelle, der Zeiger zeigt aber, dass hier etwas passiert.
 *
 * Der Pfeil steht nur an der Spalte, nach der gerade sortiert ist - ein
 * blasser Pfeil an jeder Spalte macht die Kopfzeile unruhig, ohne eine
 * Frage zu beantworten. */
.pa-sortierlink {
	display: inline-flex;
	align-items: center;
	color: inherit;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
}

.pa-sortierlink:hover,
.pa-sortierlink:focus-visible {
	color: var(--pa-navy-dark);
	text-decoration: underline;
}

.pa-sortierlink .pa-icon {
	margin-inline-start: var(--pa-space-1);
	font-size: 0.85em;
}

/* Die sortierte Spalte hebt sich leicht ab - sonst muss man den kleinen
 * Pfeil suchen, um die Tabelle zu verstehen. */
.table > thead th[aria-sort="ascending"],
.table > thead th[aria-sort="descending"] {
	color: var(--pa-navy-dark);
	box-shadow: inset 0 -2px 0 var(--pa-accent);
}

/* --- Hervorgehobene Zeilen ----------------------------------------------
 *
 * Gesperrte Labore, gesperrte oder geloeschte Benutzer, deaktivierte
 * Preislisten und Galerien werden rot unterlegt. Bootstrap 3 machte das mit
 * `class="danger"` an der Zeile; in Bootstrap 5 heisst die Klasse
 * `table-danger` - unter dem alten Namen war die Markierung wirkungslos und
 * eine gesperrte Zeile sah aus wie jede andere.
 *
 * Der Ton kommt aus unserer Palette statt aus Bootstraps Vorgabe, und die
 * Streifen der Tabelle bleiben innerhalb der Markierung. Zur Farbe kommt
 * eine linke Kante: Farbe allein unterscheidet fuer jemanden mit
 * Rotsehschwaeche nichts. */
.table > tbody > tr.table-danger {
	--bs-table-bg: var(--pa-danger-bg);
	--bs-table-striped-bg: var(--pa-danger-bg);
	--bs-table-hover-bg: var(--pa-danger-bg);
	--bs-table-color: var(--pa-text);
	--bs-table-striped-color: var(--pa-text);
	--bs-table-hover-color: var(--pa-text);
}

.table > tbody > tr.table-danger > *:first-child {
	box-shadow: inset 3px 0 0 var(--pa-danger);
}

/* Zahlen rechtsbuendig und tabellarisch - Betraege lassen sich dann
 * spaltenweise vergleichen, ohne dass die Ziffern wandern. */
.pa-num {
	text-align: right;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

.pa-price {
	font-weight: 600;
	color: var(--pa-navy);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* --- Reine Textseiten ----------------------------------------------------
 *
 * AGB, Datenschutz, Widerrufsbelehrung. Der Inhalt kommt als EIN Block aus
 * der Konfiguration - eine Huelle, darin Absaetze, Ueberschriften und
 * Listen.
 *
 * Begrenzt wird deshalb das BLATT und nicht der Text darin: die Karte ist
 * 820 px breit und steht mittig, der Text fuellt sie aus. Das ergibt rund
 * 85 Zeichen je Zeile.
 *
 * Zwei Zwischenstaende, die nicht funktioniert haben, als Warnung:
 *   * `max-width` an der Huelle des Inhalts - dann steht eine 636 px
 *     schmale Textspalte am linken Rand eines 1600 px breiten Fensters. Das
 *     sieht nach einem Umbruchfehler aus.
 *   * dasselbe in einer Karte ueber die volle Breite - dann klebt die
 *     schmale Spalte in einem breiten, halb leeren Kasten.
 * ---------------------------------------------------------------------- */

.pa-textblatt {
	max-width: 820px;
	margin-inline: auto;
}

/* Anschriften in den Textseiten: <address> kommt vom Browser kursiv und
 * ohne Abstand nach unten. Im Datenschutztext steht die Anschrift des
 * Verantwortlichen als ein Block - vorher war jede Zeile ein eigener
 * Absatz, was zwischen "Thomas Schiffler" und "Draiser Strasse 6" den
 * vollen Absatzabstand ergab. */
.pa-textblatt address {
	margin-bottom: var(--pa-space-4);
	font-style: normal;
	line-height: 1.7;
}

/* Anschrift im Impressum: mittig und ohne Kursivschrift, die <address>
 * mitbringt. Die Abstaende zwischen Anschrift, Kontakt und USt-Id kommen
 * hier her - vorher standen dafuer <br/><br/> im Markup. */
.pa-impressum {
	margin-bottom: var(--pa-space-6);
	font-style: normal;
	text-align: center;
	line-height: 1.7;
}

.pa-impressum__kontakt:first-of-type {
	margin-top: var(--pa-space-4);
}

.pa-impressum__ustid {
	margin-top: var(--pa-space-4);
}

/* --- Hinweiskasten mit Galeriecode und Direktverweis --------------------- */

.pa-codehint {
	margin-bottom: var(--pa-space-4);
	padding: var(--pa-space-3) var(--pa-space-4);
	border: 1px solid var(--pa-border);
	border-left: 3px solid var(--pa-accent);
	border-radius: var(--pa-radius-sm);
	background: var(--pa-surface-sunken);
	color: var(--pa-text);
	font-size: var(--pa-text-sm);
	line-height: 1.7;
	/* Die Galerieadresse ist ein langes Wort ohne Leerzeichen. */
	overflow-wrap: anywhere;
}

/* --- Knopfzeilen und Einleitungen ----------------------------------------
 *
 * Ersetzt das Bootstrap-3-Muster "ein Knopf je col-sm-12 mit padding-top im
 * style-Attribut". Die Knoepfe stehen nebeneinander und brechen um, wenn der
 * Platz nicht reicht.
 * ---------------------------------------------------------------------- */

.pa-actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--pa-space-2);
	margin-top: var(--pa-space-4);
}

/* Einleitungstext eines Kastens.
 *
 * BEWUSST ohne Begrenzung der Zeilenlaenge: der Kasten gibt die Breite vor.
 * Mit `max-width: 70ch` brach der Erklaertext der QR-Code-Erkennung nach
 * zwei Dritteln der Karte um, obwohl daneben Platz frei war - er sah
 * gedrueckt aus. Wo eine Lesebreite noetig ist, gibt es sie am Blatt
 * (.pa-textblatt), nicht am Absatz. */
.pa-intro {
	margin-bottom: var(--pa-space-4);
	color: var(--pa-text);
}

/* --- Beschreibungsraster (Bestelldetails, Zahlungsinformationen) ---------
 *
 * Bezeichnung und Wert als Paar, die Paare verteilt auf so viele Spalten,
 * wie die Breite hergibt. Ersetzt das alte Schwebelayout aus rechtsbuendigen
 * `col-md-6`-Bezeichnungen und `clearfix`-Zeilenumbruechen.
 * ---------------------------------------------------------------------- */

.pa-detailgrid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: var(--pa-space-3) var(--pa-space-6);
	margin: 0;
}

/* Eng: fuer Bankverbindungen und Kennungen, die untereinander gelesen
 * werden - dort ist eine Spalte richtig. */
.pa-detailgrid--eng {
	grid-template-columns: 1fr;
	gap: var(--pa-space-2);
}

.pa-detailgrid__paar {
	display: grid;
	grid-template-columns: minmax(120px, max-content) 1fr;
	gap: var(--pa-space-2) var(--pa-space-3);
	align-items: baseline;
}

/* Auf schmalen Fenstern untereinander - eine Bezeichnungsspalte von 120 px
 * neben einem Wert laesst bei 390 px keinen brauchbaren Platz. */
@media (max-width: 575.98px) {
	.pa-detailgrid__paar {
		grid-template-columns: 1fr;
		gap: 0;
	}
}

/* Eine Angabe, die eine eigene Zeile braucht - die Adressen.
 *
 * Im Raster landeten sie sonst neben Bestellnummer, Datum und Status, weil
 * dort so viel Platz ist; mehrzeilige Werte neben einzeiligen liest sich
 * schlecht. `1 / -1` spannt die Zeile ueber alle Spalten, der Wert selbst
 * behaelt eine Lesebreite. */
.pa-detailgrid__paar--zeile {
	grid-column: 1 / -1;
}

.pa-detailgrid__paar--zeile dd {
	max-width: 44ch;
}

.pa-detailgrid dt {
	color: var(--pa-text-muted);
	font-size: var(--pa-text-sm);
	font-weight: 400;
}

.pa-detailgrid dd {
	margin: 0;
	color: var(--pa-text);
}

/* Kennungen und Kontodaten: Ziffern tabellarisch, damit sie sich
 * vergleichen lassen, und nicht mitten in der Nummer umbrechen. */
.pa-nummer {
	font-variant-numeric: tabular-nums;
	overflow-wrap: anywhere;
}

.pa-payment-hint {
	margin-bottom: var(--pa-space-3);
	color: var(--pa-text);
}

/* --- Zaehlerlisten (Systemstatus der Todoliste) --------------------------
 *
 * Bezeichnung links, Zahl rechts, eine Trennlinie dazwischen. Die Zahlen
 * stehen tabellarisch, damit sie in der Spalte untereinander bleiben. */

.pa-statelist {
	margin: 0;
}

.pa-statelist__zeile {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--pa-space-3);
	padding-block: var(--pa-space-2);
	border-bottom: 1px solid var(--pa-border);
}

.pa-statelist__zeile:last-child {
	border-bottom: 0;
}

.pa-statelist dt {
	font-weight: 400;
	color: var(--pa-text-muted);
	font-size: var(--pa-text-sm);
}

.pa-statelist dd {
	margin: 0;
	font-weight: 600;
	color: var(--pa-navy);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}

/* --- Hinweise ------------------------------------------------------------ */

.alert {
	border: 1px solid transparent;
	box-shadow: var(--pa-shadow-sm);
}

.alert-success {
	--bs-alert-color: var(--pa-success);
	--bs-alert-bg: var(--pa-success-bg);
	--bs-alert-border-color: rgba(47, 122, 63, 0.24);
}

.alert-danger {
	--bs-alert-color: var(--pa-danger);
	--bs-alert-bg: var(--pa-danger-bg);
	--bs-alert-border-color: rgba(179, 38, 30, 0.24);
}

.alert-warning {
	--bs-alert-color: var(--pa-warning);
	--bs-alert-bg: var(--pa-warning-bg);
	--bs-alert-border-color: rgba(138, 90, 0, 0.24);
}

.alert-info {
	--bs-alert-color: var(--pa-info);
	--bs-alert-bg: var(--pa-info-bg);
	--bs-alert-border-color: rgba(31, 111, 159, 0.24);
}

/* ===========================================================================
 * 7. Kleine Helfer
 * ======================================================================== */

/* Nur fuer Hilfsmittel sichtbar - fuer Beschriftungen, die im Bild
 * offensichtlich sind, aber vorgelesen fehlen wuerden. */
.pa-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.pa-stack > * + * {
	margin-top: var(--pa-space-4);
}

.pa-muted {
	color: var(--pa-ink-soft);
}

.pa-small {
	font-size: var(--pa-text-sm);
}

/* ===========================================================================
 * 8. Uebernommen aus ownstyle.css
 *
 * Diese Klassen werden aus Java bzw. aus einzelnen Markup-Dateien heraus
 * gesetzt und bleiben deshalb unter ihrem alten Namen erhalten.
 * ======================================================================== */

/* Gesetzt ueber FotoCssAttributes.DETAILVIEW bzw. .THUMBVIEW. */
.detailImage {
	display: block;
	margin-inline: auto;
	max-width: 100%;
	height: auto;
}

.thumbImage {
	max-width: 120px;
	max-height: 120px;
}

/* Gesetzt ueber FotoCssAttributes.RESPONSIVE. Hiess in Bootstrap 3
 * img-responsive und in Bootstrap 5 img-fluid; die Klasse bleibt als
 * eigener Name bestehen, damit die Java-Seite unabhaengig von Bootstraps
 * Umbenennungen ist. */
.img-responsive {
	max-width: 100%;
	height: auto;
}

/* Stornierte Positionen und geloeschte Datensaetze. */
.deletedContent {
	text-decoration: line-through;
	font-style: italic;
	color: var(--pa-ink-muted);
}

/* Benutzermenue der Kopfleiste: lange Namen sollen die Klappe nicht
 * beliebig breit machen. */
.dropdown-menu_menue {
	max-width: 260px;
}

/* Registerkarten - Inhalt unter den Reitern.
 *
 * Der Rahmen ist ausdruecklich ein Block: das Markup der Seiten setzt am
 * aeusseren Tag "nav nav-tabs", und .nav ist in Bootstrap 5 ein
 * Flex-Behaelter - Reiterliste und Inhalt lagen dadurch nebeneinander.
 * PaTabbedPanel ersetzt die Klassen inzwischen, die Regel hier ist der
 * Gurt zum Hosentraeger. */
.pa-tabs-wrap {
	display: block;
	width: 100%;
}

.pa-tab-content {
	padding: var(--pa-space-5) 0 0;
}

.pa-tabs {
	margin-bottom: 0;
	border-bottom-color: var(--pa-border);
}

.pa-tabs .nav-link {
	color: var(--pa-ink-soft);
	font-weight: 600;
}

.pa-tabs .nav-link:hover {
	color: var(--pa-navy);
	border-color: var(--pa-border) var(--pa-border) var(--pa-border);
}

.pa-tabs .nav-link.active {
	color: var(--pa-navy);
	background: var(--pa-surface);
	border-color: var(--pa-border) var(--pa-border) var(--pa-surface);
}

/* ===========================================================================
 * 9. Formularklassen aus Bootstrap 3 - eigene Nachbildung
 *
 * WARUM DIESE KLASSEN NOCH EXISTIEREN
 *
 * Bootstrap 5 hat `form-group`, `control-label`, `form-horizontal` und
 * `form-inline` gestrichen. Der Umbau waere nicht wie bei panel->card eine
 * Umbenennung, sondern ein Umbau der Struktur: aus einer `form-group` mit
 * `col-sm-5 control-label` wird in Bootstrap 5 eine `row` mit
 * `col-sm-5 col-form-label`. Das betrifft 245 Stellen in 75 Dateien
 * (form-group) und 224 in 58 Dateien (control-label) - fast durchweg
 * Fotografen-, Labor- und Adminmasken.
 *
 * Diese Masken kann ich nicht alle nachpruefen. Eine verrutschte
 * Preislistenmaske oder eine Laborstammdatenmaske faellt erst dem Fotografen
 * auf, der sie braucht. Deshalb sind die vier Klassen hier nachgebaut - mit
 * denselben Mitteln, die Bootstrap 5 selbst benutzt (`--bs-gutter-x`), damit
 * die `col-sm-*`-Kinder darin genauso liegen wie in einer echten `row`.
 *
 * Es sind ab hier UNSERE Klassen, nicht Bootstraps. Neuer Code soll
 * `row mb-3` und `col-form-label` verwenden. Wer eine dieser Masken
 * ueberarbeitet, kann sie dabei mitziehen - dann schrumpft dieser Abschnitt
 * von selbst.
 * ======================================================================== */

.form-group {
	margin-bottom: var(--pa-space-4);
}

.control-label {
	font-weight: 600;
	color: var(--pa-navy);
	font-size: var(--pa-text-sm);
	margin-bottom: var(--pa-space-1);
	/* Enge Beschriftungsspalten (teils col-sm-3 innerhalb einer col-sm-6)
	 * brachen sonst mitten im Wort: "Ansprechpartn / er". */
	overflow-wrap: break-word;
	hyphens: auto;
}

/* Waagerechtes Formular: die Gruppe verhaelt sich wie eine Bootstrap-Zeile.
 * Die Werte sind aus .row uebernommen, damit die Spaltenkinder ihre
 * gewohnten Innenabstaende behalten.
 *
 * Der zweite Selektor faengt die Faelle ohne `form-horizontal` am Formular:
 * in Bootstrap 3 waren `col-*` schwebende Elemente (float), eine Gruppe mit
 * Spaltenkindern lag deshalb auch ohne Zeile nebeneinander - siehe
 * AuszahlungDurchfuehrenPage, die genau darauf und auf ein nachgestelltes
 * `clearfix` gebaut war. In Bootstrap 5 gibt es kein float mehr, ohne diese
 * Regel wuerde die Beschriftung unter das Feld rutschen.
 *
 * `:has()` kennen alle aktuellen Browser. Wo es fehlt, stapeln die Felder -
 * unschoen, aber vollstaendig bedienbar. */
.form-horizontal .form-group,
.form-group:has(> [class*="col-"]) {
	--bs-gutter-x: 1.5rem;
	--bs-gutter-y: 0;
	display: flex;
	flex-wrap: wrap;
	margin-top: calc(-1 * var(--bs-gutter-y));
	margin-right: calc(-0.5 * var(--bs-gutter-x));
	margin-left: calc(-0.5 * var(--bs-gutter-x));
}

/* DER SPALTENABSTAND MUSS HIER MITKOMMEN.
 *
 * Das war der Grund, warum in allen waagerechten Formularen die
 * Beschriftungen an den Feldern klebten: Bootstrap 5 vergibt den
 * Innenabstand einer Spalte NICHT ueber die Klasse `col-sm-3`, sondern ueber
 * den Selektor `.row > *`. Die Klasse selbst setzt nur Breite und
 * Flex-Verhalten. Wer die Zeile nachbaut, muss also auch diesen Abstand
 * nachbauen - sonst stossen Beschriftung und Eingabefeld ohne jede Luecke
 * aneinander.
 *
 * Bewusst nur an Spaltenkinder und ohne `width`: Bootstrap setzt in
 * `.row > *` zusaetzlich `width: 100%`, was dort funktioniert, weil die
 * Regel VOR den col-Klassen steht. Diese Datei laedt nach Bootstrap - ein
 * `width` hier wuerde `col-sm-3` ueberschreiben und jede Spalte auf die
 * volle Breite ziehen. */
.form-horizontal .form-group > [class*="col-"],
.form-group:has(> [class*="col-"]) > [class*="col-"] {
	flex-shrink: 0;
	padding-right: calc(var(--bs-gutter-x, 1.5rem) * 0.5);
	padding-left: calc(var(--bs-gutter-x, 1.5rem) * 0.5);
}

@media (min-width: 576px) {
	/* Beschriftung rechtsbuendig an das Feld heranruecken - so gehoert sie
	 * sichtbar zum Feld rechts daneben und nicht zum Feld darunter. Der
	 * Innenabstand oben ist derselbe, den Bootstrap 5 fuer
	 * col-form-label ansetzt, damit Text und Feld auf einer Linie sitzen. */
	.form-horizontal .control-label,
	.form-group:has(> [class*="col-"]) > .control-label {
		text-align: right;
		padding-top: calc(0.375rem + 1px);
		padding-bottom: calc(0.375rem + 1px);
		margin-bottom: 0;
	}
}

@media (max-width: 575.98px) {
	/* Auf dem Telefon stapeln: eine Beschriftung in einer 5-Spalten-Kolumne
	 * neben einem Feld in 7 Spalten ist bei 360 px Breite unlesbar. */
	.form-horizontal .form-group > [class*="col-"],
	.form-group:has(> [class*="col-"]) > [class*="col-"] {
		flex: 0 0 100%;
		max-width: 100%;
	}
}

/* --- Spalten ohne Zeile ------------------------------------------------
 *
 * Ein durchgehendes Muster aus der Bootstrap-3-Zeit: `col-*`-Kaesten liegen
 * DIREKT in einem Kasten, ohne `row` darum, dahinter ein `clearfix`. In
 * Bootstrap 3 ging das auf, weil `col-*` schwebende Elemente (float) waren -
 * sie reihten sich von selbst nebeneinander, und der `clearfix` beendete die
 * Reihe.
 *
 * In Bootstrap 5 gibt es kein float mehr: `col-*` setzt nur noch Breite und
 * Flex-Verhalten. Ohne flex-Eltern sind es damit Blockelemente mit
 * Teilbreite, die UNTEREINANDER stehen - drei Drittel-Spalten wurden zu
 * einer schmalen Liste. Sichtbar war das u.a. im Systemstatus der Todoliste
 * (drei Spalten wurden eine), auf der Preislistenseite und bei den
 * Zahlungseingaengen.
 *
 * Die Regel macht den Eltern zu genau dem, was er in Bootstrap 3 faktisch
 * war: eine Zeile. Ausgenommen sind die Faelle, die schon eine eigene
 * Behandlung haben - echte `row`, Formulargruppen (siehe
 * Kompatibilitaetsebene oben), Zeilenmasken und unsere eigenen
 * `pa-`Layouts.
 *
 * Erst danach kommt der Innenabstand der Spalten, denn Bootstrap vergibt ihn
 * ueber `.row > *` und nicht ueber die Spaltenklasse selbst.
 *
 * WICHTIG - nur REINE Spaltencontainer:
 * `:not(:has(> *:not([class*="col-"])))` verlangt, dass der Kasten kein
 * Kind hat, das keine Spalte ist. Ohne diese Bedingung traf die Regel auch
 * Kaesten, die neben einer Spalte noch anderes enthalten - etwa den
 * Kartenrumpf der QR-Code-Erkennung mit Einleitungstext, Formular UND einem
 * `col-sm-12` fuer die Knopfzeile. Der wurde dadurch zur Zeile, und
 * Einleitungstext, Formular und Knopfzeile standen NEBENEINANDER, jeder in
 * einer schmalen Spalte. Ebenso verloren Tabellen ihre volle Breite: als
 * Flex-Element richtet sich eine Tabelle nach ihrem Inhalt, nicht nach dem
 * Kasten.
 *
 * Ohne `:has()` bleibt es beim gestapelten Zustand - unschoen, aber
 * vollstaendig lesbar.
 * ---------------------------------------------------------------------- */

:has(> [class*="col-xs-"], > [class*="col-sm-"], > [class*="col-md-"], > [class*="col-lg-"]):not(.row):not(.form-group):not(.form-inline):not([class*="pa-"]):not(html):not(body):not(tr):not(thead):not(tbody):not(:has(> *:not([class*="col-"]))) {
	display: flex;
	flex-wrap: wrap;
	--bs-gutter-x: 1.5rem;
	/* KEINE negativen Aussenabstaende wie in einer echten `row`.
	 *
	 * Eine `row` zieht sich um den halben Spaltenabstand nach aussen, weil
	 * sie in einer `container`-Spalte sitzt, die genau diesen Abstand als
	 * Innenabstand hat - beides hebt sich auf. Hier ist der Eltern aber ein
	 * beliebiger Kasten, meist ein `card-body`: dort ragte der Inhalt dann
	 * 12 px links und rechts aus der Karte heraus. Ohne die negativen
	 * Abstaende sitzt der Inhalt um denselben Betrag ein - das ist in einer
	 * Karte richtig und ragt nirgends heraus. */
}

:has(> [class*="col-xs-"], > [class*="col-sm-"], > [class*="col-md-"], > [class*="col-lg-"]):not(.row):not(.form-group):not(.form-inline):not([class*="pa-"]):not(html):not(body):not(tr):not(thead):not(tbody):not(:has(> *:not([class*="col-"]))) > [class*="col-"] {
	flex-shrink: 0;
	padding-right: calc(var(--bs-gutter-x, 1.5rem) * 0.5);
	padding-left: calc(var(--bs-gutter-x, 1.5rem) * 0.5);
}

/* UNTERHALB ihres Umbruchpunkts haben die Spaltenklassen keine Breite.
 *
 * `col-sm-12` setzt seine Breite erst ab 576 px; darunter ist sie
 * unbestimmt. In einer echten `row` ist das kein Problem, weil Bootstrap in
 * `.row > *` zusaetzlich `width: 100%` vergibt - genau daran liegt es, dass
 * Spalten unter ihrem Umbruchpunkt die ganze Breite nehmen und stapeln.
 *
 * Fehlt dieses `width` und steht gleichzeitig `flex-shrink: 0`, richtet sich
 * die Spalte nach ihrem INHALT und kann nicht schrumpfen: auf dem Telefon
 * wurde die Preislistenverwaltung dadurch 1157 px breit. Also dieselbe
 * Breite nachziehen, und zwar je Klasse in dem Fensterbereich, in dem
 * Bootstrap sie noch nicht setzt.
 *
 * `min-width: 0` dazu, damit breite Inhalte (Tabellen) die Spalte nicht von
 * innen aufdehnen - die Tabellen rollen in ihrem eigenen Rahmen, siehe
 * Abschnitt Tabellen. */
@media (max-width: 575.98px) {
	:has(> [class*="col-xs-"], > [class*="col-sm-"], > [class*="col-md-"], > [class*="col-lg-"]):not(.row):not(.form-group):not(.form-inline):not([class*="pa-"]):not(html):not(body):not(tr):not(thead):not(tbody):not(:has(> *:not([class*="col-"]))) > [class*="col-"] {
		flex: 0 0 100%;
		width: 100%;
		max-width: 100%;
		min-width: 0;
	}
}

@media (max-width: 767.98px) {
	:has(> [class*="col-xs-"], > [class*="col-sm-"], > [class*="col-md-"], > [class*="col-lg-"]):not(.row):not(.form-group):not(.form-inline):not([class*="pa-"]):not(html):not(body):not(tr):not(thead):not(tbody):not(:has(> *:not([class*="col-"]))) > [class*="col-md-"],
	:has(> [class*="col-xs-"], > [class*="col-sm-"], > [class*="col-md-"], > [class*="col-lg-"]):not(.row):not(.form-group):not(.form-inline):not([class*="pa-"]):not(html):not(body):not(tr):not(thead):not(tbody):not(:has(> *:not([class*="col-"]))) > [class*="col-lg-"] {
		flex: 0 0 100%;
		width: 100%;
		max-width: 100%;
		min-width: 0;
	}
}

@media (max-width: 991.98px) {
	:has(> [class*="col-xs-"], > [class*="col-sm-"], > [class*="col-md-"], > [class*="col-lg-"]):not(.row):not(.form-group):not(.form-inline):not([class*="pa-"]):not(html):not(body):not(tr):not(thead):not(tbody):not(:has(> *:not([class*="col-"]))) > [class*="col-lg-"] {
		flex: 0 0 100%;
		width: 100%;
		max-width: 100%;
		min-width: 0;
	}
}

/* Der `clearfix` gehoerte zu den schwebenden Spalten. In einer Flex-Zeile
 * ist er ein leeres Kind, das eine neue Zeile erzwingt - also weg damit,
 * wo er in einer solchen Zeile steht. */
.row > .clearfix:empty,
:has(> [class*="col-sm-"], > [class*="col-md-"]) > .clearfix:empty {
	display: none;
}

/* Formular in einer Zeile - Bootstrap 5 macht das ueber d-flex und gap. */
.form-inline {
	display: flex;
	flex-flow: row wrap;
	align-items: center;
	gap: var(--pa-space-2);
}

.form-inline .form-control,
.form-inline .form-select {
	width: auto;
	display: inline-block;
}

/* Senkrechtes Formular: nur Abstand, keine Zeilenlogik. */
.form-vertical .form-group > [class*="col-"] {
	flex: 0 0 100%;
	max-width: 100%;
	padding-inline: 0;
}

/* --- Meldungen an einzelnen Feldern -------------------------------------
 *
 * `FeedbackContainer` ist ein Border: er rendert seine Meldungen VOR dem
 * Rumpf, und dieser Rumpf ist bei einer Feldgruppe die Beschriftung samt
 * Eingabefeld. Jede Feldmeldung erschien deshalb als eigener, schliessbarer
 * Meldungskasten OBERHALB der Beschriftung - bei einer leeren Adresse waren
 * das sieben rote Kaesten, die das Formular auseinanderschoben, mit einem
 * Schliesskreuz quer ueber dem Text.
 *
 * Hier bleibt vom Kasten nur die Aussage: eine rote Zeile. Sie steht
 * ausserdem UNTER dem Feld statt darueber - moeglich, weil die Feldgruppe
 * eine Flex-Zeile ist und `order` die Reihenfolge unabhaengig vom Markup
 * bestimmt.
 *
 * Der Schliessknopf entfaellt: eine Feldmeldung wegzuklicken, ohne das Feld
 * zu berichtigen, hilft niemandem - beim naechsten Absenden ist sie wieder
 * da. Bei den Meldungen ganzer Abschnitte (Zahlungsart, AGB) bleibt der
 * Kasten samt Knopf.
 * ---------------------------------------------------------------------- */

.form-group > .alert-danger,
.form-group > .alert-success {
	order: 99;
	flex: 0 0 100%;
	max-width: 100%;
	margin: var(--pa-space-1) 0 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	box-shadow: none;
	font-size: var(--pa-text-sm);
}

.form-group > .alert-danger {
	color: var(--pa-danger);
}

.form-group > .alert-success {
	color: var(--pa-success);
}

.form-group > .alert-danger .btn-close,
.form-group > .alert-success .btn-close {
	display: none;
}

/* Mehrere Meldungen einer Gruppe (Strasse UND Hausnummer) untereinander,
 * nicht als zwei Marken nebeneinander. */
.form-group > .alert-danger + .alert-danger {
	margin-top: 0;
}

/* --- Fehlerhafte Felder -------------------------------------------------
 *
 * FieldValidationBehaviour setzt bei einem ungueltigen Feld die Klasse
 * `has-error` auf den umgebenden FeedbackContainer. Das war Bootstrap 3;
 * Bootstrap 5 markiert stattdessen das Eingabefeld selbst mit `is-invalid`.
 *
 * Den Mechanismus umzubauen hiesse, die Fehlerdarstellung SAEMTLICHER
 * Formulare der Anwendung anzufassen - vom Bestellabschluss bis zur
 * Laborstammdatenmaske. Deshalb ist `has-error` hier nachgebaut. Der
 * Unterschied zu Bootstrap 3: nicht nur die Rahmenfarbe wechselt, sondern
 * auch die Rahmenstaerke. Farbe allein unterscheidet fuer jemanden mit
 * Rotsehschwaeche ein fehlerhaftes Feld nicht von einem richtigen.
 * ---------------------------------------------------------------------- */

.has-error .form-control,
.has-error .form-select,
.has-error .form-check-input {
	border-color: var(--pa-danger);
	border-width: 2px;
}

.has-error .form-control:focus,
.has-error .form-select:focus {
	border-color: var(--pa-danger);
	box-shadow: 0 0 0 3px rgba(179, 38, 30, 0.2);
}

.has-error label,
.has-error .control-label,
.has-error .form-label,
.has-error .col-form-label {
	color: var(--pa-danger);
}

/* Die Fehlermeldung selbst - FeedbackErrorContainerMessagePanel rendert
 * dafuer ein alert-danger, das braucht in einem Formular weniger Gewicht
 * als ein Seitenhinweis. */
.has-error .alert-danger,
.form-group > .alert-danger {
	margin-top: var(--pa-space-2);
	margin-bottom: 0;
	padding: var(--pa-space-2) var(--pa-space-3);
	font-size: var(--pa-text-sm);
	box-shadow: none;
}

/* ===========================================================================
 * 10. Blaettern
 *
 * CustomPagingNavigator wird an acht Stellen benutzt - Galerie, Einzelbild,
 * Bestelluebersicht, Galerielisten, Benutzerliste, Uploadwarteschlange -
 * also in allen Rollen. Deshalb steht das hier und nicht in
 * pa-kundengalerie.css.
 * ======================================================================== */

.pa-pager {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: var(--pa-space-2);
	margin: var(--pa-space-5) 0;
	padding: 0;
	list-style: none;
}

/* Nur die unmittelbaren Kinder sind Bedienflaechen. Ohne das ">" wuerden
 * auch die Symbol- und Vorlese-Spans INNERHALB der Links wie Knoepfe
 * aussehen - das ergaebe einen Knopf im Knopf. */
.pa-pager > a,
.pa-pager > .pa-pager__state {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	min-height: 40px;
	padding-inline: var(--pa-space-2);
	border: 1px solid var(--pa-border);
	border-radius: var(--pa-radius-sm);
	background: var(--pa-surface);
	color: var(--pa-navy);
	font-size: var(--pa-text-sm);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.pa-pager > a:hover {
	border-color: var(--pa-accent);
	background: var(--pa-accent-soft);
	text-decoration: none;
}

.pa-pager > .current {
	border-color: var(--pa-primary);
	background: var(--pa-primary);
	color: #fff;
}

.pa-pager > .disabled {
	color: var(--pa-ink-muted);
	background: var(--pa-surface-sunken);
}


/* Seitenanzeige zwischen den Pfeilen. */
.pa-pager__state {
	color: var(--pa-ink-soft);
	font-size: var(--pa-text-sm);
	font-variant-numeric: tabular-nums;
	background: transparent;
	border: 0;
	min-width: 0;
	padding-inline: var(--pa-space-2);
}

/* "Zur Uebersicht" - traegt Text, ist also breiter als die Pfeile. */
.pa-pager__back {
	gap: var(--pa-space-2);
	padding-inline: var(--pa-space-3);
}

/* --- Kontrollkaestchen und Radiozeilen aus Bootstrap 3 -----------------
 *
 * Bootstrap 3 kannte `<div class="checkbox"><input> Text</div>` und
 * entsprechend `radio`. Bootstrap 5 hat dafuer form-check mit eigener
 * Struktur. Die 35 bzw. 4 Stellen im Markup bleiben, hier bekommen sie
 * ihren Abstand zurueck - vorher klebte der Text am Kaestchen.
 * ---------------------------------------------------------------------- */

.checkbox,
.radio {
	display: flex;
	align-items: baseline;
	gap: var(--pa-space-2);
	min-height: 1.6em;
}

.checkbox > input,
.radio > input {
	flex: none;
	width: 1.05em;
	height: 1.05em;
	margin: 0;
	/* Auf die Grundlinie des Textes heben. */
	transform: translateY(0.15em);
}

.checkbox label,
.radio label {
	margin: 0;
	font-weight: normal;
}

/* --- Enge Formularspalten stapeln --------------------------------------
 *
 * Manche Masken setzen ein waagerechtes Formular INNERHALB einer halben
 * Spalte (col-sm-3 Beschriftung in einer col-sm-6). Die Beschriftungsspalte
 * ist dann rund 90 px breit, und Woerter wie "Ansprechpartner" brachen
 * mitten im Wort um: "Ansprechpartn / er".
 *
 * Eine Behaelterabfrage loest das an der richtigen Stelle: entscheidend ist
 * nicht die Fensterbreite, sondern wie breit die Formularzeile selbst ist.
 * Wo Behaelterabfragen fehlen, bleibt es beim bisherigen Umbruch - unschoen,
 * aber bedienbar.
 * ---------------------------------------------------------------------- */

.form-horizontal .form-group,
.form-group:has(> [class*="col-"]) {
	container-type: inline-size;
}

@container (max-width: 460px) {
	/* Dieselben Selektoren wie in der @media-Regel oben, und das mit
	 * Absicht: eine Behaelterabfrage erhoeht die Spezifitaet NICHT. Stand
	 * hier nur `.control-label`, gewann die spezifischere Regel
	 * `.form-group:has(> [class*="col-"]) > .control-label` mit ihrem
	 * `text-align: right` - und genau so sah es im Bestellprozess aus: die
	 * Beschriftung stand gestapelt UEBER dem Feld, aber rechtsbuendig, also
	 * scheinbar rechts vom Feld statt links davor. Mit gleicher Spezifitaet
	 * entscheidet die Reihenfolge, und diese Regel steht weiter unten. */
	.form-horizontal .control-label,
	.form-group:has(> [class*="col-"]) > .control-label,
	.control-label {
		text-align: left;
		padding-top: 0;
		padding-bottom: var(--pa-space-1);
	}

	.form-group > [class*="col-"] {
		flex: 0 0 100%;
		max-width: 100%;
	}
}

/* --- Suchmasken: form-inline mit Spalten IN der Gruppe -----------------
 *
 * Ein Muster aus mehreren Such- und Filtermasken (Benutzerliste,
 * Galerieverwaltung, Preislisten):
 *
 *   <form class="form form-inline">
 *     <div class="form-group col-md-5">
 *       <label class="col-sm-5 control-label">…</label>
 *       <div class="col-sm-7"><input class="form-control"></div>
 *
 * Die Gruppe ist also SELBST eine Spalte und enthaelt zugleich Spalten. In
 * Bootstrap 3 ging das auf, weil `col-*` schwebende Elemente waren.
 *
 * Die Zeilenlogik der Kompatibilitaetsebene darf hier nicht greifen: mit
 * negativen Aussenabstaenden und rechtsbuendigen Beschriftungen rutschten
 * die Beschriftungen ueber die falschen Felder - in der Benutzerliste stand
 * "Kundennummer" ueber dem Suchfeld und das erste Feld ganz ohne
 * Beschriftung.
 *
 * Innerhalb einer Zeilenmaske stehen Beschriftung und Feld schlicht
 * nebeneinander.
 * ---------------------------------------------------------------------- */

.form-inline .form-group {
	/* Keine Behaelterabfrage: sonst stapelt die Regel weiter unten die
	 * Spalten, sobald die Gruppe schmal ist. */
	container-type: normal;
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: var(--pa-space-2);
	margin: 0;
}

.form-inline .form-group > [class*="col-"] {
	flex: 0 1 auto;
	width: auto;
	max-width: none;
	padding: 0;
}

.form-inline .control-label {
	margin: 0;
	padding: 0;
	text-align: left;
	white-space: nowrap;
}

/* Auf schmalen Fenstern untereinander - drei Suchfelder nebeneinander
 * passen auf einem Telefon nicht. */
@media (max-width: 767.98px) {
	.form-inline {
		align-items: stretch;
		flex-direction: column;
	}

	.form-inline .form-group {
		flex-wrap: wrap;
	}

	.form-inline .form-group > [class*="col-"] {
		flex: 1 1 auto;
	}

	.form-inline .form-control,
	.form-inline .form-select {
		width: 100%;
	}
}
