/* ==========================================================================
   MaklerPress Core Styles – v2.0
   Version: 1.28.0-dev
   Design: Modern, clean, generous whitespace. BEM + CSS Custom Properties.
   ========================================================================== */

/* === LAYOUT =============================================================== */

.mp-detail {
	max-width: var(--mp-container-max, 1200px);
	margin: 0 auto;
	padding: var(--mp-space-8, 2rem) var(--mp-container-pad, 1.5rem);
}

.mp-detail--two-column {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--mp-space-8, 2rem);
}

@media (min-width: 960px) {
	.mp-detail--two-column {
		grid-template-columns: 1fr 360px;
	}
	.mp-detail--two-column .mp-gallery,
	.mp-detail--two-column .mp-detail__header {
		grid-column: 1 / -1;
	}
}

/* === DETAIL HEADER ======================================================= */

.mp-detail__header {
	margin-bottom: var(--mp-space-2, 0.5rem);
	padding-bottom: var(--mp-space-6, 1.5rem);
}

.mp-detail__objektnummer {
	font-size: var(--mp-text-xs, 0.75rem);
	color: var(--mp-text-muted, #64748b);
	letter-spacing: 0.05em;
	text-transform: uppercase;
	font-weight: 500;
	display: block;
	margin-bottom: var(--mp-space-2, 0.5rem);
}

.mp-detail__title {
	font-family: var(--mp-font-display, var(--mp-font, system-ui));
	font-size: clamp(1.5rem, 3vw, var(--mp-text-4xl, 2.25rem));
	font-weight: 700;
	line-height: var(--mp-leading-tight, 1.25);
	color: var(--mp-text, #1e293b);
	margin: 0 0 var(--mp-space-4, 1rem);
}

.mp-detail__badges {
	display: flex;
	flex-wrap: wrap;
	gap: var(--mp-space-2, 0.5rem);
	margin-bottom: var(--mp-space-4, 1rem);
}

.mp-detail__price-block {
	margin-top: var(--mp-space-2, 0.5rem);
}

.mp-detail__price {
	font-size: var(--mp-text-3xl, 1.875rem);
	font-weight: 700;
	color: var(--mp-primary, #1a56db);
	line-height: 1;
	margin: 0;
}

.mp-detail__price-label {
	font-size: var(--mp-text-sm, 0.875rem);
	font-weight: 400;
	color: var(--mp-text-muted, #64748b);
	margin-left: var(--mp-space-2, 0.5rem);
}

/* === BADGES ============================================================== */

.mp-badge {
	display: inline-flex;
	align-items: center;
	padding: var(--mp-space-1, 0.25rem) var(--mp-space-3, 0.75rem);
	font-size: var(--mp-text-xs, 0.75rem);
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	border-radius: var(--mp-radius-full, 9999px);
	background: var(--mp-bg-subtle, #f1f5f9);
	color: var(--mp-text, #1e293b);
	border: 1px solid var(--mp-border, #e2e8f0);
}

.mp-badge--kauf,
.mp-badge--kaufen,
.mp-badge--kaufpreis {
	background: var(--mp-primary-light, #e8effe);
	color: var(--mp-primary, #1a56db);
	border-color: transparent;
}

.mp-badge--miete,
.mp-badge--mieten,
.mp-badge--mietpreis {
	background: #ecfdf5;
	color: #15803d;
	border-color: transparent;
}

/* === SEKTIONEN – Gemeinsam ============================================== */

.mp-section {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-section + .mp-section {
	border-top: 1px solid var(--mp-border, #e2e8f0);
}

.mp-section__title {
	font-family: var(--mp-font-display, var(--mp-font, system-ui));
	font-size: var(--mp-text-xl, 1.25rem);
	font-weight: 700;
	color: var(--mp-text, #1e293b);
	margin: 0 0 var(--mp-space-6, 1.5rem);
	padding-bottom: var(--mp-space-3, 0.75rem);
	border-bottom: 2px solid var(--mp-primary, #1a56db);
	display: inline-block;
}

.mp-section__subtitle {
	font-size: var(--mp-text-lg, 1.125rem);
	font-weight: 600;
	color: var(--mp-text, #1e293b);
	margin: var(--mp-space-6, 1.5rem) 0 var(--mp-space-3, 0.75rem);
}

/* === KEY FACTS =========================================================== */

.mp-key-facts {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-key-facts__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
	gap: var(--mp-space-4, 1rem);
}

.mp-key-facts__item {
	background: var(--mp-bg-alt, #f8fafc);
	border: 1px solid var(--mp-border, #e2e8f0);
	border-radius: var(--mp-radius-lg, 12px);
	padding: var(--mp-space-4, 1rem) var(--mp-space-5, 1.25rem);
	text-align: center;
	transition: box-shadow var(--mp-transition-base, 250ms ease),
	            border-color var(--mp-transition-base, 250ms ease);
}

.mp-key-facts__item:hover {
	box-shadow: var(--mp-shadow-md, 0 4px 6px rgba(0,0,0,0.07));
	border-color: var(--mp-primary, #1a56db);
}

.mp-key-facts__value {
	font-size: var(--mp-text-2xl, 1.5rem);
	font-weight: 700;
	color: var(--mp-primary, #1a56db);
	display: block;
	line-height: 1.2;
}

.mp-key-facts__unit {
	font-size: var(--mp-text-sm, 0.875rem);
	font-weight: 400;
	color: var(--mp-text-muted, #64748b);
}

.mp-key-facts__label {
	font-size: var(--mp-text-xs, 0.75rem);
	color: var(--mp-text-muted, #64748b);
	margin-top: var(--mp-space-1, 0.25rem);
	font-weight: 500;
	letter-spacing: 0.03em;
	display: block;
}

@media (max-width: 480px) {
	.mp-key-facts__grid {
		grid-template-columns: repeat(2, 1fr);
	}
	.mp-key-facts__value {
		font-size: var(--mp-text-xl, 1.25rem);
	}
}

/* === DESCRIPTION ======================================================== */

.mp-description {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-description__content,
.mp-description__lage {
	line-height: var(--mp-leading-relaxed, 1.625);
	color: var(--mp-text, #1e293b);
	max-width: 72ch;
	font-size: var(--mp-text-base, 1rem);
}

.mp-description__lage {
	margin-top: var(--mp-space-4, 1rem);
	padding-left: var(--mp-space-4, 1rem);
	border-left: 3px solid var(--mp-primary, #1a56db);
	color: var(--mp-text-muted, #64748b);
}

/* === EQUIPMENT ========================================================== */

.mp-equipment {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-equipment__badge {
	display: inline-flex;
	align-items: center;
	padding: var(--mp-space-1, 0.25rem) var(--mp-space-3, 0.75rem);
	font-size: var(--mp-text-xs, 0.75rem);
	font-weight: 600;
	border-radius: var(--mp-radius-full, 9999px);
	background: var(--mp-bg-subtle, #f1f5f9);
	color: var(--mp-text-muted, #64748b);
	border: 1px solid var(--mp-border, #e2e8f0);
	margin-bottom: var(--mp-space-4, 1rem);
}

.mp-equipment__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: var(--mp-space-6, 1.5rem);
}

.mp-equipment__group-title {
	font-size: var(--mp-text-sm, 0.875rem);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	color: var(--mp-text-muted, #64748b);
	margin: 0 0 var(--mp-space-3, 0.75rem);
}

.mp-equipment__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: var(--mp-space-2, 0.5rem);
}

.mp-equipment__item {
	display: flex;
	align-items: flex-start;
	gap: var(--mp-space-2, 0.5rem);
	font-size: var(--mp-text-sm, 0.875rem);
	color: var(--mp-text, #1e293b);
}

.mp-equipment__item::before {
	content: '';
	display: inline-block;
	width: 16px;
	height: 16px;
	min-width: 16px;
	margin-top: 2px;
	background: var(--mp-success, #16a34a);
	border-radius: 50%;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M10 3L5 8 2 5' stroke='white' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
	background-size: 10px;
}

/* === ENERGY PASS ======================================================== */

.mp-energy-pass {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-energy-pass__list {
	display: grid;
	grid-template-columns: minmax(160px, auto) 1fr;
	gap: var(--mp-space-2, 0.5rem) var(--mp-space-6, 1.5rem);
	max-width: 480px;
}

.mp-energy-pass__list dt {
	color: var(--mp-text-muted, #64748b);
	font-size: var(--mp-text-sm, 0.875rem);
	font-weight: 500;
	padding: var(--mp-space-2, 0.5rem) 0;
	border-bottom: 1px solid var(--mp-border, #e2e8f0);
}

.mp-energy-pass__list dd {
	font-weight: 600;
	color: var(--mp-text, #1e293b);
	margin: 0;
	padding: var(--mp-space-2, 0.5rem) 0;
	border-bottom: 1px solid var(--mp-border, #e2e8f0);
}

.mp-energy-pass__klasse {
	font-size: var(--mp-text-xl, 1.25rem);
	font-weight: 800;
	color: var(--mp-primary, #1a56db);
}

/* Energie-Skala A+-H */
.mp-energy-scale {
	display: flex;
	gap: 3px;
	margin-bottom: var(--mp-space-4, 1rem);
	flex-wrap: wrap;
}

.mp-energy-scale__item {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: var(--mp-radius-sm, 4px);
	font-size: var(--mp-text-xs, 0.75rem);
	font-weight: 700;
	color: white;
	background: #94a3b8;
	transition: transform var(--mp-transition-base);
}

.mp-energy-scale__item--active {
	transform: scale(1.2);
	box-shadow: var(--mp-shadow-md);
}

.mp-energy-scale__item--ap { background: #00c928; }
.mp-energy-scale__item--a  { background: #42d43f; }
.mp-energy-scale__item--b  { background: #96d634; }
.mp-energy-scale__item--c  { background: #d4e228; }
.mp-energy-scale__item--d  { background: #f5d800; }
.mp-energy-scale__item--e  { background: #f59d00; }
.mp-energy-scale__item--f  { background: #f56100; }
.mp-energy-scale__item--g  { background: #f52600; }
.mp-energy-scale__item--h  { background: #c20000; }

/* === FLOOR PLANS ======================================================== */

.mp-floor-plans {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-floor-plans__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
	gap: var(--mp-space-4, 1rem);
}

.mp-floor-plans__item {
	border: 1px solid var(--mp-border, #e2e8f0);
	border-radius: var(--mp-radius, 8px);
	overflow: hidden;
	cursor: pointer;
	transition: box-shadow var(--mp-transition-base);
}

.mp-floor-plans__item:hover {
	box-shadow: var(--mp-shadow-lg);
}

.mp-floor-plans__img {
	width: 100%;
	height: auto;
	display: block;
}

/* === LOCATION MAP ======================================================== */

.mp-location-map {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-location-map__address {
	font-size: var(--mp-text-sm, 0.875rem);
	color: var(--mp-text-muted, #64748b);
	margin: 0 0 var(--mp-space-4, 1rem);
	display: flex;
	align-items: center;
	gap: var(--mp-space-2, 0.5rem);
}

.mp-location-map__address::before {
	content: '';
	display: inline-block;
	width: 14px;
	height: 14px;
	background: var(--mp-primary, #1a56db);
	border-radius: 50%;
	flex-shrink: 0;
}

.mp-map-wrapper {
	border-radius: var(--mp-radius-lg, 12px);
	overflow: hidden;
	border: 1px solid var(--mp-border, #e2e8f0);
	box-shadow: var(--mp-shadow-md);
}

/* === ALL DATA ============================================================ */

.mp-all-data {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-all-data__list {
	display: grid;
	grid-template-columns: minmax(160px, 40%) 1fr;
	gap: 0;
	border: 1px solid var(--mp-border, #e2e8f0);
	border-radius: var(--mp-radius, 8px);
	overflow: hidden;
}

.mp-all-data__label,
.mp-all-data__value {
	padding: var(--mp-space-3, 0.75rem) var(--mp-space-4, 1rem);
	font-size: var(--mp-text-sm, 0.875rem);
	border-bottom: 1px solid var(--mp-border, #e2e8f0);
}

.mp-all-data__list > dt:last-of-type,
.mp-all-data__list > dd:last-of-type {
	border-bottom: none;
}

.mp-all-data__label {
	color: var(--mp-text-muted, #64748b);
	font-weight: 500;
	background: var(--mp-bg-alt, #f8fafc);
}

.mp-all-data__value {
	font-weight: 400;
	color: var(--mp-text, #1e293b);
}

.mp-all-data__list dt:nth-child(4n+1),
.mp-all-data__list dt:nth-child(4n+1) + dd {
	background: var(--mp-bg, #ffffff);
}

/* === SIMILAR PROPERTIES ================================================= */

.mp-similar {
	padding: var(--mp-space-8, 2rem) 0;
}

.mp-similar__grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
	gap: var(--mp-space-4, 1rem);
}

/* === PROPERTY CARD (Archive) ============================================= */

.mp-archive__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--mp-space-6, 1.5rem);
}

@media (min-width: 600px) {
	.mp-archive__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1024px) {
	.mp-archive__grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

.mp-card {
	background: var(--mp-bg, #ffffff);
	border-radius: var(--mp-radius-lg, 12px);
	border: 1px solid var(--mp-border, #e2e8f0);
	box-shadow: var(--mp-shadow, 0 1px 3px rgba(0,0,0,0.1));
	overflow: hidden;
	/* Hover-Animationen kommen aus maklerpress-animations.css */
}

.mp-card__link {
	text-decoration: none;
	color: inherit;
	display: block;
}

.mp-card__image-wrapper {
	overflow: hidden;
	aspect-ratio: 3/2;
}

.mp-card__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.mp-card__image--placeholder {
	background: var(--mp-bg-subtle, #f1f5f9);
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--mp-border, #e2e8f0);
}

.mp-card__body {
	padding: var(--mp-space-5, 1.25rem);
}

.mp-card__title {
	font-size: var(--mp-text-lg, 1.125rem);
	font-weight: 600;
	margin: 0 0 var(--mp-space-2, 0.5rem);
	line-height: var(--mp-leading-snug, 1.375);
	color: var(--mp-text, #1e293b);
}

.mp-card__address {
	font-size: var(--mp-text-sm, 0.875rem);
	color: var(--mp-text-muted, #64748b);
	margin: 0 0 var(--mp-space-3, 0.75rem);
	display: flex;
	align-items: center;
	gap: var(--mp-space-1, 0.25rem);
}

.mp-card__price {
	font-size: var(--mp-text-xl, 1.25rem);
	font-weight: 700;
	color: var(--mp-primary, #1a56db);
	margin: 0;
	line-height: 1.2;
}

.mp-card__price-label {
	font-size: var(--mp-text-xs, 0.75rem);
	font-weight: 400;
	color: var(--mp-text-muted, #64748b);
	display: block;
	margin-top: 2px;
}

/* === SEARCH FORM ======================================================== */

/* DEV-020 Nacharbeit: Filter-Bar ist mockup-treu ein full-width BAND (nur
   Border-Bottom, leicht transparente Fläche + Blur), keine eingerückte Box-
   Karte mehr. Die Fläche/Border sitzt am inneren <form>.mp-filterbar. */
.mp-search-form {
	margin: 0;
	padding: 0;
	background: transparent;
	border: none;
	border-radius: 0;
}

.mp-search-form__form.mp-filterbar {
	position: relative;
	padding: var(--mp-space-l);
	background: transparent;
	backdrop-filter: none;
	/* DEV-033: kein border-bottom mehr — die Gesehen-Linie (mp-seen-progress
	   --in-widget) schließt das Widget als unterste Kante ab. */
	gap: var(--mp-filter-gap); /* DEV-033 E1: EIN Rasterabstand zwischen allen Zeilen */
}

/* Fläche + Blur liegen auf einem ::before OHNE Nachfahren: backdrop-filter
   direkt am Band würde es per CSS-Spec zum Containing Block für die
   position:fixed-Bottom-Sheets der Popover machen (Phase-5-Fallstrick 3).
   So bleibt der Blur-Effekt auf ALLEN Breakpoints aktiv (User-Vorgabe R3),
   ohne die mobile Popover-Verankerung am Viewport zu brechen. */
.mp-search-form__form.mp-filterbar::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: -1;
	background: color-mix(in srgb, var(--mp-bg-surface-color) 95%, transparent);
	backdrop-filter: blur(8px);
}

.mp-search-form__form {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--mp-space-4, 1rem);
}

.mp-search-form__row {
	display: flex;
	flex-wrap: wrap;
	gap: var(--mp-space-3, 0.75rem);
	align-items: flex-end;
	width: 100%;
}

.mp-search-form__row--dropdowns { flex: 1; min-width: 200px; }

.mp-search-form__row--ort {
	width: 100%;
	margin-top: var(--mp-space-3, 0.75rem);
}

.mp-search-form__field--ort-input { flex: 1; min-width: 200px; }
.mp-search-form__field--ort-input input { min-width: 100%; }
.mp-search-form__field--radius { flex: 0 0 auto; min-width: 100px; }

.mp-search-form__field {
	display: flex;
	flex-direction: column;
	gap: var(--mp-space-1, 0.25rem);
}

.mp-search-form__field label {
	font-size: var(--mp-text-xs, 0.75rem);
	font-weight: 600;
	color: var(--mp-text-muted, #64748b);
	text-transform: uppercase;
	letter-spacing: 0.05em;
}

.mp-search-form__field input[type="text"],
.mp-search-form__field input[type="number"],
.mp-search-form__field select {
	padding: var(--mp-space-2, 0.5rem) var(--mp-space-3, 0.75rem);
	min-width: 100px;
	border: 1px solid var(--mp-border, #e2e8f0);
	border-radius: var(--mp-radius, 8px);
	background: var(--mp-bg, #ffffff);
	font-size: var(--mp-text-sm, 0.875rem);
	color: var(--mp-text, #1e293b);
	transition: border-color var(--mp-transition-fast, 150ms ease),
	            box-shadow var(--mp-transition-fast, 150ms ease);
}

.mp-search-form__field input:focus,
.mp-search-form__field select:focus {
	outline: none;
	border-color: var(--mp-primary, #1a56db);
	box-shadow: 0 0 0 3px var(--mp-primary-light, #e8effe);
}

.mp-search-form__price { display: flex; flex-wrap: wrap; gap: var(--mp-space-3, 0.75rem); align-items: flex-end; flex: 1 1 180px; }
.mp-search-form__advanced { margin-top: var(--mp-space-3, 0.75rem); width: 100%; }
.mp-search-form__advanced summary { cursor: pointer; font-weight: 600; font-size: var(--mp-text-sm, 0.875rem); color: var(--mp-primary, #1a56db); }
.mp-search-form__row--ranges { margin-top: var(--mp-space-3, 0.75rem); width: 100%; }

.mp-search-form__actions {
	display: flex;
	gap: var(--mp-space-3, 0.75rem);
	align-items: center;
	flex-wrap: wrap;
}

.mp-search-form__submit {
	padding: var(--mp-space-2, 0.5rem) var(--mp-space-5, 1.25rem);
	background: var(--mp-primary, #1a56db);
	color: #fff;
	border: none;
	border-radius: var(--mp-radius, 8px);
	cursor: pointer;
	font-weight: 600;
	font-size: var(--mp-text-sm, 0.875rem);
	transition: background var(--mp-transition-fast, 150ms ease),
	            transform var(--mp-transition-fast, 150ms ease);
}

.mp-search-form__submit:hover {
	background: var(--mp-primary-dark, #1649c0);
	transform: translateY(-1px);
}

.mp-search-form__reset {
	font-size: var(--mp-text-sm, 0.875rem);
	color: var(--mp-text-muted, #64748b);
	text-decoration: none;
	padding: var(--mp-space-2, 0.5rem) var(--mp-space-3, 0.75rem);
	border-radius: var(--mp-radius, 8px);
	transition: color var(--mp-transition-fast), background var(--mp-transition-fast);
}

.mp-search-form__reset:hover {
	color: var(--mp-text, #1e293b);
	background: var(--mp-border, #e2e8f0);
}

/* === SLIDER (noUiSlider) ================================================= */

.mp-search-form__field--slider { min-width: 180px; flex: 1; }

.mp-slider__values {
	font-size: var(--mp-text-xs, 0.75rem);
	color: var(--mp-text-muted, #64748b);
	text-align: center;
	min-height: 1.25em;
	margin-bottom: var(--mp-space-2, 0.5rem);
}

.mp-slider__track {
	margin: var(--mp-space-2, 0.5rem) 6px var(--mp-space-1, 0.25rem);
}

.noUi-target {
	background: var(--mp-border, #e2e8f0);
	border: none;
	box-shadow: none;
	border-radius: var(--mp-radius-sm, 4px);
}

.noUi-connect { background: var(--mp-primary, #1a56db); }
.noUi-horizontal { height: 5px; }

.noUi-horizontal .noUi-handle {
	width: 20px;
	height: 20px;
	top: -8px;
	right: -10px;
	border-radius: 50%;
	background: var(--mp-bg, #fff);
	border: 2px solid var(--mp-primary, #1a56db);
	box-shadow: var(--mp-shadow-sm);
	cursor: pointer;
}

.noUi-handle::before,
.noUi-handle::after { display: none; }

.noUi-handle:focus {
	outline: 2px solid var(--mp-primary, #1a56db);
	outline-offset: 3px;
}

.mp-search-count {
	margin-bottom: var(--mp-space-4, 1rem);
	font-size: var(--mp-text-sm, 0.875rem);
	color: var(--mp-text-muted, #64748b);
	font-weight: 500;
}

/* === AJAX LOADING STATE ================================================= */

.mp-property-list {
	position: relative;
	transition: opacity 0.2s ease;
}

.mp-property-list.mp-results--loading {
	opacity: 0.5;
	pointer-events: none;
	cursor: wait;
}

.mp-property-list.mp-results--loading::after {
	content: '';
	position: absolute;
	inset: 0;
	background: transparent;
	z-index: 1;
}

/* === NO RESULTS / PAGINATION ============================================ */

.mp-no-results {
	text-align: center;
	padding: var(--mp-space-16, 4rem) var(--mp-space-4, 1rem);
	color: var(--mp-text-muted, #64748b);
}

.mp-pagination {
	margin-top: var(--mp-space-8, 2rem);
}

.mp-pagination ul {
	display: flex;
	flex-wrap: wrap;
	gap: var(--mp-space-2, 0.5rem);
	list-style: none;
	margin: 0;
	padding: 0;
}

/* === BUTTONS ============================================================= */

.mp-btn {
	display: inline-flex;
	align-items: center;
	gap: var(--mp-space-2, 0.5rem);
	padding: var(--mp-space-3, 0.75rem) var(--mp-space-6, 1.5rem);
	border-radius: var(--mp-radius, 8px);
	font-weight: 600;
	font-size: var(--mp-text-sm, 0.875rem);
	text-decoration: none;
	cursor: pointer;
	border: none;
	transition: background var(--mp-transition-fast),
	            transform var(--mp-transition-fast),
	            box-shadow var(--mp-transition-fast);
}

.mp-btn--primary {
	background: var(--mp-primary, #1a56db);
	color: #ffffff;
}

.mp-btn--primary:hover {
	background: var(--mp-primary-dark, #1649c0);
	transform: translateY(-1px);
	box-shadow: var(--mp-shadow-md);
}

/* === KONTEXTUELLE MODIFIER ============================================== */

.mp-property--miete_pacht .mp-card__price::after {
	content: ' /Mo.';
	font-size: 0.75em;
	font-weight: 400;
	color: var(--mp-text-muted, #64748b);
}

/* === PRINT ============================================================== */

@media print {
	.mp-similar,
	.mp-location-map,
	.mp-search-form,
	.mp-pagination {
		display: none !important;
	}

	.mp-detail {
		padding: 0;
		max-width: 100%;
	}

	.mp-detail__title {
		font-size: 1.5rem;
	}

	.mp-key-facts__grid {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* ==========================================================================
   DEV-020 Phase 3 – Karten-Klassen für AJAX-Fragment (property-list-fragment-bricks.php)

   Gleicher Grund wie beim Filter-Block unten: Bricks' TYPISIERTE Controls
   (background-color, padding, width/height, text-transform …) werden nur als
   kompakt-skopierte Regel ausgegeben (z. B. „.mp-badge--marketing.brxe-text-basic"),
   die nur auf echte Bricks-Elemente im Baum matcht — nicht auf das rohe HTML
   des AJAX-Fragments. Nur der freie _cssCustom-Block einer Global Class wird
   IMMER als Bare-Class-Regel ausgegeben. Titel/Preis/Feature-Icons sind im
   Fragment daher direkt inline gestylt; hier nur die restlichen, über die
   Klassen referenzierten typisierten Werte dupliziert (identisch zu Phase 1/2).
   ========================================================================== */

.mp-card {
	background-color: var(--mp-bg-body-color);
	border-radius: var(--mp-radius-l);
	box-shadow: 0 4px 20px rgba(26, 28, 30, 0.06); /* Stitch "ambient shadow" */
}

/* Titel-Link erbt die Kartenfarbe — seit der Theme-Style-Konsolidierung greift
   sonst die globale a-Linkfarbe (Blau) auf den Kartentiteln. */
.mp-card a {
	color: inherit;
}

.mp-card__image {
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9; /* Mockup aspect-video, statt fixer 250px */
	object-fit: cover;
}

.mp-card__content {
	padding: var(--mp-space-m);
}

.mp-card .mp-badge--marketing {
	background-color: var(--mp-bg-body-color);
	color: var(--mp-text-body-color);
	text-transform: none;
	font-size: var(--mp-text-2xs);
	backdrop-filter: blur(4px);
	/* DEV-032-Feinschliff (User): kein Oval — gleiche Eckenform wie 360°/Neu/
	   Status. Die Basis-.mp-badge (radius-full, PHP-Fallback-Optik) gilt sonst
	   für AJAX-Karten weiter, während Bricks-Karten radius-s rendern (sjqvn8). */
	border-radius: var(--mp-radius-s);
}

/* 360°/Neu-Badges (Kleinauftrag nach DEV-020): Duplikate der typisierten
   Bricks-Global-Class-Werte (te974i/qxbqp7 + Basis sjqvn8) fürs AJAX-Fragment
   — gleiche Scoping-Falle wie bei mp-badge--marketing. Werte identisch zu den
   Klassen-Controls, damit Initial-Render (Bricks) und AJAX-Fragment nicht
   auseinanderlaufen. */
.mp-card .mp-badge--360,
.mp-card .mp-badge--new {
	font-size: var(--mp-text-2xs);
	font-weight: 600;
	color: #ffffff;
	border-color: transparent;
	border-radius: var(--mp-radius-s);
	padding: 4px 10px;
}

.mp-card .mp-badge--360 {
	display: inline-flex;
	align-items: center;
	column-gap: var(--mp-space-2xs);
	background-color: var(--mp-primary-color);
	text-transform: uppercase;
}

.mp-card .mp-badge--new {
	background-color: var(--mp-secondary-color);
	text-transform: none;
}

/* 360°-Icon (Material Symbols: view_in_ar) als Mask vor dem Text — Farbe folgt
   der Badge-Textfarbe via currentColor (data-URIs können kein var()). */
.mp-card .mp-badge--360::before {
	content: '';
	flex: none;
	width: 12px;
	height: 12px;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M440-181 240-296q-19-11-29.5-29T200-365v-230q0-22 10.5-40t29.5-29l200-115q19-11 40-11t40 11l200 115q19 11 29.5 29t10.5 40v230q0 22-10.5 40T720-296L520-181q-19 11-40 11t-40-11Zm0-92v-184l-160-93v185l160 92Zm80 0 160-92v-185l-160 93v184ZM80-680v-120q0-33 23.5-56.5T160-880h120v80H160v120H80ZM280-80H160q-33 0-56.5-23.5T80-160v-120h80v120h120v80Zm400 0v-80h120v-120h80v120q0 33-23.5 56.5T800-80H680Zm120-600v-120H680v-80h120q33 0 56.5 23.5T880-800v120h-80ZM480-526l158-93-158-91-158 91 158 93Zm0 45Zm0-45Zm40 69Zm-80 0Z'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M440-181 240-296q-19-11-29.5-29T200-365v-230q0-22 10.5-40t29.5-29l200-115q19-11 40-11t40 11l200 115q19 11 29.5 29t10.5 40v230q0 22-10.5 40T720-296L520-181q-19 11-40 11t-40-11Zm0-92v-184l-160-93v185l160 92Zm80 0 160-92v-185l-160 93v184ZM80-680v-120q0-33 23.5-56.5T160-880h120v80H160v120H80ZM280-80H160q-33 0-56.5-23.5T80-160v-120h80v120h120v80Zm400 0v-80h120v-120h80v120q0 33-23.5 56.5T800-80H680Zm120-600v-120H680v-80h120q33 0 56.5 23.5T880-800v120h-80ZM480-526l158-93-158-91-158 91 158 93Zm0 45Zm0-45Zm40 69Zm-80 0Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Leere Badge-Elemente ausblenden: Die Dynamic-Data-Tags liefern bei Objekten
   ohne Tour/„neu" einen leeren String; Bricks rendert das text-basic-Element
   dann trotzdem (leer). Der .mp-card-Scope hebt die Spezifität über Bricks'
   kompakt-skopiertes display:inline-flex (te974i). Im AJAX-Fragment werden
   leere Badges gar nicht erst gerendert (PHP-Conditional). */
.mp-card .mp-badge--360:empty,
.mp-card .mp-badge--new:empty {
	display: none;
}

/* Verkauft-/Reserviert-Badge (DEV-032, Token maklerpress_badge_status):
   Duplikat der typisierten Global-Class-Werte (mp-badge--status) fürs
   AJAX-Fragment — gleiche Scoping-Falle wie oben. Dunkler Grund hebt den
   Vermarktungszustand deutlich von Kauf/Miete (weiß) und 360°/Neu
   (Primär/Sekundär) ab; EIN Stil für beide Zustände (Design-Harmonisierung),
   der Text unterscheidet. */
.mp-card .mp-badge--status {
	font-size: var(--mp-text-2xs);
	font-weight: 600;
	color: #ffffff;
	background-color: var(--mp-text-heading-color);
	border-color: transparent;
	border-radius: var(--mp-radius-s);
	padding: 4px 10px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

/* Leere Status-Badges überall ausblenden (Dynamic-Data liefert '' bei OFFEN) —
   bewusst OHNE .mp-card-Scope, weil das Badge auch auf der Detailseite
   (Template 11, Hervorhebung neben dem Titel) sitzt. */
.mp-badge--status:empty {
	display: none;
}

/* Detail-Hervorhebung (Template 11): größere Variante neben dem Titel. */
.mp-badge--status-detail {
	font-size: var(--mp-text-s);
	padding: 6px 14px;
	align-self: flex-start;
}

.mp-card__fav {
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/* Typisierte Controls der Bricks-Klassen mp-feature-row (u619fy) und
   mp-card__meta (ewys5b) greifen im AJAX-Fragment-HTML nicht (gleiche
   Scoping-Falle) — hier als Plain-CSS dupliziert. */
.mp-feature-row {
	display: flex;
	flex-direction: row;
	align-items: center;
	column-gap: var(--mp-space-m);
	font-size: var(--mp-text-s);
	color: var(--mp-secondary-color);
}

.mp-card__meta {
	display: flex;
	flex-direction: row;
	align-items: center;
	column-gap: var(--mp-space-2xs);
	font-size: var(--mp-text-s);
	color: var(--mp-secondary-color);
}

/* Gleicher Grund: mp-btn-primary rendert im Suchformular (rohes Custom-Element-HTML)
   ohne jegliches Bricks-Styling (kein Hintergrund/Padding/Radius). Bewusst ohne
   width:100% (Bricks-Detailseiten-Kontext) — hier soll der Button inhaltsbreit sitzen. */
.mp-search-form .mp-btn-primary {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background-color: var(--mp-primary-color);
	color: #ffffff;
	font-weight: 600;
	text-align: center;
	text-decoration: none;
	height: var(--mp-control-height); /* DEV-033 E1: gleiche Höhe wie Selects/Pills */
	padding: 0 var(--mp-space-xl);
	font-size: var(--mp-control-font-size);
	line-height: 1.4;
	border-radius: var(--mp-radius-m);
	border: 1px solid transparent;
	box-sizing: border-box;
	cursor: pointer;
	transition: background-color 0.3s ease;
}

.mp-search-form .mp-btn-primary:hover {
	background-color: var(--mp-secondary-color);
}

/* ==========================================================================
   DEV-020 Phase 3 – Filter-Bar (mp-filter-*)

   WICHTIG: Bricks generiert Global-Class-CSS nur für Klassen, die tatsächlich
   an einem echten Bricks-Element im Template-Baum hängen (_cssGlobalClasses).
   Diese Klassen (mp-filter-select/-input/-pill/-pill--active/-popover/
   -popover__actions) tauchen nur im rohen HTML-String des mp-search-filter
   Custom-Elements auf (templates/archive/search-form.php) — Bricks „sieht"
   diese Verwendung nicht und lässt ihr CSS auf der Seite weg. Deshalb hier
   als reines CSS dupliziert (identische Werte wie die Bricks-Klassen aus
   Phase 1), damit sie auch außerhalb des Bricks-Baums greifen. Ausschließlich
   var(--mp-*)-Tokens, kein Markenwert. mp-filterbar ist NICHT betroffen, da
   sie zusätzlich direkt am mp-search-filter-Element selbst hängt.
   ========================================================================== */

/* DEV-033 E1: EINE Kontrollhöhe (--mp-control-height) statt implizitem Padding-
   Maß; Vertikalzentrierung übernimmt die feste Höhe, Padding nur noch horizontal.
   line-height bleibt explizit, weil select/input sonst ein geerbtes
   line-height:40px übernehmen (Bricks-Theme-Reset). */
.mp-filter-select,
.mp-filter-input {
	width: 100%;
	height: var(--mp-control-height);
	background: var(--mp-bg-body-color);
	border: 1px solid var(--mp-border-primary-color);
	border-radius: var(--mp-radius-m);
	padding: 0 var(--mp-space-m);
	font-size: var(--mp-control-font-size);
	font-weight: 500;
	line-height: 1.4;
	color: var(--mp-text-body-color);
	box-sizing: border-box;
}

/* Chevron (Material Symbols expand_more) als Background — Mockup zeigt ihn an
   jedem Select; Markup-frei, damit auch der No-JS-Fallback ihn bekommt. */
.mp-filter-select {
	padding-left: var(--mp-space-s);
	padding-right: 36px; /* Platz für den 18px-Chevron; kompakt, damit „Kauf und Miete" bei 1440px nicht clippt */
	appearance: none;
	-webkit-appearance: none;
	cursor: pointer;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath fill='%2364748b' d='M480-345 240-585l56-56 184 184 184-184 56 56-240 240Z'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right var(--mp-space-xs) center;
	background-size: 18px 18px;
}

.mp-filter-input {
	padding-left: var(--mp-space-xl);
	cursor: text;
}

/* Input ohne Leading-Icon (Objekt-ID): normales Innenpolster links. */
.mp-filter-input--plain {
	padding-left: var(--mp-space-m);
}

.mp-filter-select:focus,
.mp-filter-input:focus {
	outline: none;
	border-color: var(--mp-text-body-color);
}

/* Pills sind im Stitch-Mockup KEINE Vollrund-Pills, sondern rounded-lg-Rechtecke
   (8px) in Select-Optik — Vollrundung gibt es nur bei den mobilen Chips. */
.mp-filter-pill {
	display: inline-flex;
	align-items: center;
	column-gap: var(--mp-space-2xs);
	background: var(--mp-bg-body-color);
	border: 1px solid var(--mp-border-primary-color);
	border-radius: var(--mp-radius-m);
	height: var(--mp-control-height);
	padding: 0 var(--mp-space-m);
	font-size: var(--mp-control-font-size);
	line-height: 1.4;
	font-weight: 500;
	color: var(--mp-text-body-color);
	cursor: pointer;
	transition: border-color .2s;
	box-sizing: border-box;
}

.mp-filter-pill:hover {
	border-color: var(--mp-secondary-color);
}

/* Aktiv-Zustand (Filter gesetzt bzw. Popover offen): sauberer 1px-Rand in
   der Primärfarbe — geometrisch identisch zum grauen Default-Rand. Der
   frühere zusätzliche box-shadow-Ring erzeugte eine doppelte, „ausbrechende"
   Linie (User-Feedback DEV-035 Runde 4). */
.mp-filter-pill--active,
.mp-filter-pill[aria-expanded="true"] {
	border-color: var(--mp-primary-color);
	color: var(--mp-primary-color);
}

.mp-filter-pill--active:hover,
.mp-filter-pill[aria-expanded="true"]:hover {
	border-color: var(--mp-primary-color);
}

/* Chevron dreht sich, während das zugehörige Popover geöffnet ist (Mockup-Verhalten). */
.mp-filter-pill[aria-expanded="true"] svg {
	transform: rotate(180deg);
}

.mp-filter-pill svg {
	transition: transform 0.15s ease;
	width: 18px;
	height: 18px;
	flex-shrink: 0;
}

.mp-filter-popover {
	background: var(--mp-bg-body-color);
	border: 1px solid var(--mp-border-primary-color);
	border-radius: var(--mp-radius-l);
	padding: var(--mp-space-m);
	position: absolute;
	top: 100%;
	left: 0;
	margin-top: var(--mp-space-xs);
	min-width: 256px; /* px statt rem: Bricks-Root ist 10px, 16rem wären nur 160px */
	box-shadow: var(--mp-shadow-hover);
	z-index: 50;
	flex-direction: column;
	gap: var(--mp-space-s);
}

.mp-filter-popover__actions {
	display: flex;
	justify-content: space-between;
	align-items: center;
	border-top: 1px solid var(--mp-border-primary-color);
	padding-top: var(--mp-space-s);
}

.mp-filter-row {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--mp-filter-gap);
	width: 100%;
}

/* Zeile 1 mockup-treu als 4-Spalten-Grid (Transaktion/Nutzungsart/Objektart/Zimmer). */
.mp-filter-row--selects {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: var(--mp-filter-gap);
}

/* Tablet-Split (960–1199px): Listen-Panel ist zu schmal für 4 Spalten,
   die Select-Labels würden clippen — 2×2-Grid stattdessen. */
@media (min-width: 960px) and (max-width: 1199px) {
	.mp-filter-row--selects {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.mp-filter-row--selects .mp-filter-field {
	min-width: 0;
}

/* Pills-Zeile: Chips links in einer Reihe, Reset-CTA rechts (Mockup-Anordnung).
   Desktop-Grundregel — der Scroll-Strip-Modus gilt nur in der Mobile-MQ unten.
   (Fix der Phase-5-Regression: .mp-filter-chip-scroll hatte außerhalb der
   Mobile-MQ kein display:flex, die Pills stapelten deshalb vertikal.) */
.mp-filter-row--pills {
	align-items: center;
}

.mp-filter-chip-scroll {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--mp-filter-gap);
	flex: 1 1 auto;
	min-width: 0;
}

.mp-filter-row--pills > .mp-btn-primary {
	margin-left: auto;
}

.mp-filter-field {
	display: flex;
	flex-direction: column;
	gap: var(--mp-space-2xs);
	flex: 1 1 160px;
	min-width: 140px;
}

.mp-filter-field--ort {
	flex: 2 1 280px;
	position: relative;
}

.mp-filter-field--ort .mp-filter-input {
	width: 100%;
}

.mp-filter-field--ort svg {
	position: absolute;
	left: var(--mp-space-s);
	top: 50%;
	transform: translateY(-50%);
	pointer-events: none;
}

.mp-filter-field--radius {
	flex: 0 0 auto;
	min-width: 90px;
}

/* Objekt-ID wohnt seit der Nacharbeit in der Ort-Zeile (Zeile 1 = reines
   4er-Grid); kompakt neben Radius statt volle Zeilenbreite. */
.mp-filter-field--objekt-id {
	flex: 0 1 200px;
	min-width: 140px;
}

/* Visuell versteckt (nur Screenreader) — Mockup zeigt keine Feld-Captions, nur den
   Feldnamen/Platzhalter direkt in der Box. Barrierefreiheit bleibt erhalten.
   left/top:0 ist Pflicht: ohne gesetzten Offset bleiben absolute Boxen an ihrer
   statischen Fluss-Position, ihr Containing Block ist aber das sticky Form-Band
   (nicht die overflow-x-Swipe-Zeile) — die 1px-Labels ragten dadurch bei 375px
   ~221px über den Viewport hinaus und machten die GANZE Seite horizontal
   scrollbar (Bestandsbefund 2026-07-03; clip macht unsichtbar, nimmt die Box
   aber nicht aus der Scroll-Overflow-Berechnung). */
.mp-filter-label {
	position: absolute;
	left: 0;
	top: 0;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.mp-filter-field--pill {
	position: relative;
	flex: 0 0 auto;
}

.mp-filter-pill svg {
	pointer-events: none;
}

.mp-filter-field--pill .mp-filter-popover {
	min-width: 320px; /* px statt rem (10px-Root) */
}

.mp-filter-popover__grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--mp-space-s);
}

.mp-filter-popover__field {
	display: flex;
	flex-direction: column;
	gap: var(--mp-space-2xs);
}

.mp-filter-popover__field label {
	font-size: var(--mp-text-xs);
	font-weight: 600;
	color: var(--mp-secondary-color);
}

.mp-filter-popover__field input[type="number"] {
	width: 100%;
	height: var(--mp-control-height); /* DEV-033 E1: gleiche Kontrollhöhe wie außen */
	border: 1px solid var(--mp-border-primary-color);
	border-radius: var(--mp-radius-s);
	padding: 0 var(--mp-space-m);
	font-size: var(--mp-control-font-size);
	line-height: 1.4;
	color: var(--mp-text-body-color);
	background: var(--mp-bg-body-color);
	box-sizing: border-box;
}

.mp-filter-popover__field input[type="number"]:focus {
	outline: none;
	border-color: var(--mp-text-body-color);
}

.mp-filter-popover__price-label {
	font-size: var(--mp-text-s);
	font-weight: 600;
	color: var(--mp-text-heading-color);
	margin: 0;
}

.mp-filter-checkbox-list {
	display: flex;
	flex-direction: column;
	gap: var(--mp-space-xs);
}

.mp-filter-checkbox-item {
	display: flex;
	align-items: center;
	gap: var(--mp-space-2xs);
	font-size: var(--mp-control-font-size);
	color: var(--mp-text-body-color);
	cursor: pointer;
}

.mp-filter-popover__actions button {
	background: none;
	border: none;
	padding: 0;
	font-size: var(--mp-control-font-size);
	cursor: pointer;
	color: var(--mp-secondary-color);
}

.mp-filter-popover__actions .mp-btn-primary {
	width: auto;
	padding: 0 var(--mp-space-l); /* Höhe kommt vom --mp-control-height der Basisregel */
}

.mp-search-form__actions {
	display: flex;
	align-items: center;
	gap: var(--mp-space-m);
}

/* ==========================================================================
   DEV-020 Phase 4 – Split-View (mp-archive) + Karten-Panel

   Split-Layout/Sticky-Verhalten selbst sitzt als _cssCustom direkt an den
   Global Classes mp-archive/__list/__map (Novamira). Hier nur, was diese
   Klassen NICHT abdecken können: das Sticky-Verhalten der Filter-Bar
   (mp-search-filter-element--sticky, gesetzt vom SearchFilterElement, aber
   bislang ohne CSS-Gegenstück) sowie die Karten-Popup-Card
   (maklerpress-maps.js baut das Markup client-seitig, Leaflet gibt keine
   Bricks-Klassen aus — reines CSS ist hier der einzig sinnvolle Weg).
   ========================================================================== */

/* Kein eigenes Polster/keine eigene Fläche mehr — das Filter-BAND
   (.mp-search-form__form.mp-filterbar) bringt Fläche, Blur und Border-Bottom
   selbst mit und läuft bündig über die volle Panel-Breite. */
.mp-search-filter-element--sticky {
	position: sticky;
	top: 0;
	z-index: 10;
}

/* PropertyMapElement rendert im Archiv-Panel mit fester Inline-Höhe (400px, Detail-Seiten-Default,
   dort NICHT anfassen) — im Split-Layout muss die Karte stattdessen die volle Panel-Höhe füllen. */
.mp-archive__map .mp-map-element,
.mp-archive__map .mp-map-container {
	height: 100% !important;
	width: 100%;
}

/* Popup-Card nach Designvorlage "object-card-on-map.jpg" (Nacharbeit R3):
   komplette Card = ein Link, weißes Panel mit Bild+Badge, Titel, Ort-Zeile,
   Preis, Feature-Zeile, "Details zeigen". Markup kommt aus
   maklerpress-maps.js (Leaflet) bzw. maklerpress-maps-google.js (InfoWindow)
   mit identischen Klassen. */
.mp-map-popup .leaflet-popup-content {
	margin: 0;
	width: auto !important;
}

.mp-map-popup .leaflet-popup-content-wrapper {
	padding: 0;
	border-radius: var(--mp-radius-l);
	overflow: hidden;
	box-shadow: 0 8px 25px rgba(26, 28, 30, 0.18);
}

.mp-map-popup .leaflet-popup-close-button {
	top: 8px;
	right: 8px;
	width: 26px;
	height: 26px;
	border-radius: var(--mp-radius-full);
	background: rgba(255, 255, 255, 0.9);
	color: var(--mp-text-heading-color);
	font-size: 16px;
	line-height: 26px;
	z-index: 2;
}

/* Marker-Redesign (Folgeauftrag 2026-07): Popup proportional auf Listen-
   Karten-Maß skaliert (Harmonisierung — Popup = skalierte mp-card, KEIN
   eigenes drittes Format). Breite 240px → 300px (~Listen-Karte), alle
   inneren Größen hängen an denselben Tokens wie die mp-card: Bild 16/9,
   Titel mp-text-m/600, Meta/Features mp-text-s, Badge mp-text-2xs,
   Preis zentral über --mp-card-price-size (EINE Stelle für Liste+Popup). */
.mp-map-popup__card {
	display: flex;
	flex-direction: column;
	width: 300px;
	background: var(--mp-bg-body-color);
	color: inherit;
	text-decoration: none;
	cursor: pointer;
}

.mp-map-popup__media {
	position: relative;
	display: block;
}

.mp-map-popup__image {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 16 / 9; /* wie .mp-card__image */
	object-fit: cover;
}

.mp-map-popup__badge {
	position: absolute;
	top: var(--mp-space-s);
	left: var(--mp-space-s);
	background: var(--mp-bg-body-color);
	color: var(--mp-text-body-color);
	font-size: var(--mp-text-2xs); /* wie .mp-badge--marketing auf der Karte */
	font-weight: 600;
	line-height: 1;
	padding: 6px 10px;
	border-radius: var(--mp-radius-s);
	box-shadow: 0 1px 3px rgba(26, 28, 30, 0.15);
}

.mp-map-popup__body {
	display: flex;
	flex-direction: column;
	padding: var(--mp-space-m); /* wie .mp-card__content */
}

.mp-map-popup__title {
	font-family: var(--mp-font-heading);
	font-size: var(--mp-text-m); /* wie Karten-Titel */
	font-weight: 600;
	line-height: 1.35;
	color: var(--mp-text-heading-color);
}

.mp-map-popup__meta {
	display: inline-flex;
	align-items: center;
	gap: var(--mp-space-2xs);
	margin-top: 2px;
	font-size: var(--mp-text-s); /* wie .mp-card__meta */
	color: var(--mp-secondary-color);
}

.mp-map-popup__price {
	font-family: var(--mp-font-heading);
	/* Zentrale Stelle: steuert Liste UND Popup gemeinsam (Token-Definition
	   in Bricks-Variable mp-card-price-size bzw. maklerpress-tokens.css). */
	font-size: var(--mp-card-price-size, var(--mp-head-m));
	font-weight: 700;
	color: var(--mp-text-heading-color);
	margin-top: var(--mp-space-xs);
}

.mp-map-popup__features {
	display: flex;
	align-items: center;
	gap: var(--mp-space-m);
	margin-top: var(--mp-space-s);
	padding-top: var(--mp-space-s);
	border-top: 1px solid var(--mp-border-primary-color);
	font-size: var(--mp-text-s); /* wie .mp-feature-row */
	color: var(--mp-secondary-color);
}

.mp-map-popup__feature {
	display: inline-flex;
	align-items: center;
	gap: var(--mp-space-2xs);
	white-space: nowrap;
}

.mp-map-popup__link {
	display: inline-block;
	margin-top: var(--mp-space-s);
	font-size: var(--mp-text-s);
	font-weight: 600;
	color: var(--mp-primary-color);
}

.mp-map-popup__card:hover .mp-map-popup__link {
	text-decoration: underline;
}

/* Höhen-Cap: Popup nie höher als ~70 % des Karten-Panels — der Body scrollt
   dann intern, das Bild bleibt stehen. */
.mp-archive__map .mp-map-popup__card {
	max-height: 70vh;
}

.mp-archive__map .mp-map-popup__body {
	overflow-y: auto;
}

/* Google-InfoWindow-Chrome an die Card angleichen (Standard bringt eigenes
   Padding/Radius mit). Klassen sind Google-intern, aber seit Jahren stabil.
   Maße an die 300px-Card angepasst (Marker-Redesign). */
.gm-style .gm-style-iw-c {
	padding: 0 !important;
	border-radius: var(--mp-radius-l) !important;
	box-shadow: 0 8px 25px rgba(26, 28, 30, 0.18) !important;
	max-width: 330px !important;
}

.gm-style .gm-style-iw-d {
	overflow: hidden !important;
	padding: 0 !important;
	max-width: 300px !important;
}

/* Googles InfoWindow reserviert oben eine eigene Kopfzeile (.gm-style-iw-chr)
   für den Schließen-Button — die erzeugt einen weißen Streifen ÜBER dem Bild.
   Fix: Kopfzeile als Overlay oben rechts ÜBER das Bild legen (Vorlage
   object-card-on-map.jpg: X liegt auf dem Bild), statt Platz zu beanspruchen. */
.gm-style .gm-style-iw-chr {
	position: absolute;
	top: 6px;
	right: 6px;
	height: auto;
	z-index: 3;
}

.gm-style .gm-ui-hover-effect {
	position: static !important;
	display: flex !important;
	align-items: center;
	justify-content: center;
	width: 28px !important;
	height: 28px !important;
	margin: 0 !important;
	border-radius: var(--mp-radius-full);
	background: rgba(255, 255, 255, 0.9) !important;
	opacity: 1;
}

/* Googles X-Icon (Span mit Mask) exakt mittig im Kreis zentrieren —
   der Google-Default (margin) sitzt im 28px-Kreis 2px zu weit unten/rechts. */
.gm-style .gm-ui-hover-effect > span {
	margin: 0 !important;
	width: 16px !important;
	height: 16px !important;
}

/* ==========================================================================
   Marker-Redesign (Folgeauftrag 2026-07) – Preis-Tag-Pins + Cluster-Kreis

   Mockup 01-00-Immobilienangebote-uebersicht.png: Preis-Tag-Pin ("450T €" /
   "1,2M €") mit kleiner Spitze unten + Cluster-Kreis mit Anzahl. EIN CSS für
   beide Provider: Google (AdvancedMarkerElement content, maklerpress-maps-
   google.js) und Leaflet (L.divIcon, maklerpress-maps.js). Die Farbe kommt
   IMMER aus dem Backend-Setting: JS setzt --mp-marker-color als Inline-
   Variable am .mp-map-container — hier NIE eine Farbe hardcoden.
   ========================================================================== */

.mp-map-pin {
	display: flex;
	flex-direction: column;
	align-items: center;
	cursor: pointer;
	filter: drop-shadow(0 2px 4px rgba(26, 28, 30, 0.35));
}

.mp-map-pin__label {
	padding: 6px 10px;
	background: var(--mp-marker-color, var(--mp-primary-color, #2271b1));
	border-radius: var(--mp-radius-m, 8px);
	font-family: var(--mp-font-heading, inherit);
	font-size: 13px;
	font-weight: 700;
	line-height: 1;
	color: #ffffff;
	white-space: nowrap;
}

/* Kleine Spitze unten — als Flex-Kind im Box-Fluss, damit die Gesamthöhe des
   Pins die Spitze einschließt (AdvancedMarkerElement ankert das Content-
   Element unten-mittig exakt auf der Koordinate). */
.mp-map-pin::after {
	content: '';
	width: 0;
	height: 0;
	border-left: 6px solid transparent;
	border-right: 6px solid transparent;
	border-top: 6px solid var(--mp-marker-color, var(--mp-primary-color, #2271b1));
}

/* Leaflet-Anker: der divIcon-Wrapper (iconSize null/0) sitzt exakt auf der
   Koordinate — der Pin wird per Transform unten-mittig darauf ausgerichtet. */
.mp-map-pin-anchor {
	background: none;
	border: none;
}

.mp-map-pin-anchor .mp-map-pin {
	position: absolute;
	left: 0;
	top: 0;
	transform: translate(-50%, -100%);
}

/* Cluster-Kreis mit Anzahl (beide Provider, gleiche Klasse). */
.mp-map-cluster {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	background: var(--mp-marker-color, var(--mp-primary-color, #2271b1));
	border: 3px solid rgba(255, 255, 255, 0.85);
	border-radius: var(--mp-radius-full, 9999px);
	box-shadow: 0 2px 8px rgba(26, 28, 30, 0.3);
	font-family: var(--mp-font-heading, inherit);
	font-size: 14px;
	font-weight: 700;
	color: #ffffff;
	cursor: pointer;
}

.mp-map-cluster-anchor {
	background: none;
	border: none;
}

/* ==========================================================================
   DEV-020 Phase 5 – Mobile-Politur (< 960px)

   Split-View-Kollaps (mp-archive/__list/__map) sitzt als @media-Zusatz direkt
   in den jeweiligen Global-Class-_cssCustom-Bloecken (Novamira), nicht hier.
   Hier nur, was reines Custom-Element-HTML betrifft (mp-search-filter,
   AJAX-Fragment) — gleiche Scoping-Falle wie in Phase 3/4: Bricks generiert
   fuer typisierte Controls kein CSS fuer Klassennamen im rohen HTML, deshalb
   mp-filter-chip hier als Plain-CSS-Duplikat der Global Class "onfix0".
   ========================================================================== */

@media (max-width: 959px) {
	/* mp-archive__list (Bricks-Container) hat align-items:flex-start (Bricks-
	   Default) statt stretch — ohne explizite Breite waechst mp-search-filter-
	   element sonst auf die Breite seines nicht schrumpfenden Chip-Scroll-
	   Inhalts statt an der Spaltenbreite zu clippen. */
	.mp-search-filter-element {
		width: 100%;
		min-width: 0;
	}

	/* Ort + Umkreis stehen mobil IMMER gemeinsam in einer Zeile ganz oben
	   und nutzen zusammen die volle Breite (User-Vorgabe R2). Reihenfolge
	   via order: Ort-Zeile vor die Selects-Swipe-Zeile (DOM: selects, ort,
	   pills — das Formular ist flex-wrap mit 100%-Zeilen). */
	.mp-filter-row--ort {
		order: -1;
		flex-wrap: nowrap;
	}

	.mp-filter-field--ort {
		flex: 1 1 auto;
		min-width: 0;
	}

	.mp-filter-field--radius {
		flex: 0 0 auto;
		min-width: 0;
	}

	/* Zeile 1 (Transaktion/Nutzungsart/Objektart + per JS eingehaengte
	   Objekt-ID) bleibt mobil SICHTBAR als horizontal swipebare Zeile
	   (User-Vorgabe R2 — kein "Mehr"-Popover mehr). Gleicher Scroll-Strip-
	   Mechanismus wie die Chip-Reihe darunter. */
	.mp-filter-row--selects {
		display: flex;
		flex-wrap: nowrap;
		overflow-x: auto;
		/* DEV-035 Runde 7: y-Achse FEST — overflow-x:auto impliziert sonst
		   overflow-y:auto, und iOS lässt solche Container auch OHNE Überlauf
		   vertikal gummibandartig ziehen (User-Fund am Realgerät). */
		overflow-y: hidden;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		gap: var(--mp-space-s);
		padding-bottom: var(--mp-space-2xs);
		min-width: 0;
	}

	.mp-filter-row--selects::-webkit-scrollbar {
		display: none;
	}

	.mp-filter-row--selects .mp-filter-field,
	.mp-filter-row--selects .mp-filter-field--pill {
		flex: 0 0 auto;
		scroll-snap-align: start;
	}

	/* DEV-035 Feedback-Runde 2: In der Kartenansicht stehen die Options-
	   Filter (Preis/Fläche/Zimmer/Ausstattung) MIT in Zeile 1 (hinter der
	   Objekt-ID, per JS umgehängt) — gleiche vollrunde Mobile-Chip-Optik
	   wie im Chip-Streifen der Listenansicht. */
	.mp-filter-row--selects .mp-filter-pill {
		border-radius: var(--mp-radius-full);
	}

	.mp-filter-row--selects .mp-filter-select,
	.mp-filter-row--selects .mp-filter-input {
		width: auto;
		max-width: 70vw;
	}

	/* Reset-CTA auf Mobile (DEV-033, Vorlage 01-07): voller CI-Button über die
	   gesamte Breite — sichtbar nur bei aktiven Filtern ([hidden]-Logik, E4). */
	.mp-filter-row--pills > .mp-btn-primary {
		margin-left: 0;
		width: 100%;
	}

	/* Chips (Preis/Flaeche/Zimmer/Ausstattung/Mehr) sind NUR mobil vollrund —
	   Desktop-Pills sind mockup-treu 8px-Rechtecke. */
	.mp-filter-chip-scroll .mp-filter-pill {
		border-radius: var(--mp-radius-full);
	}

	.mp-filter-row--pills {
		flex-direction: column;
		flex-wrap: nowrap;
		align-items: stretch;
		min-width: 0;
	}

	.mp-filter-chip-scroll {
		display: flex;
		flex-wrap: nowrap;
		overflow-x: auto;
		/* y-Achse fest — gleiche iOS-Gummiband-Falle wie in Zeile 1. */
		overflow-y: hidden;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		gap: var(--mp-filter-gap);
		padding-bottom: var(--mp-space-2xs);
		min-width: 0;
	}

	.mp-filter-chip-scroll::-webkit-scrollbar {
		display: none;
	}

	.mp-filter-chip-scroll .mp-filter-field--pill,
	.mp-filter-chip-scroll .mp-filter-pill {
		flex-shrink: 0;
		white-space: nowrap;
		scroll-snap-align: start;
	}

	/* Kein mobiler backdrop-filter-Override mehr noetig (R3): Blur+Flaeche
	   liegen jetzt auf ::before des Form-Bands (keine Nachfahren, kein
	   Containing Block) und gelten damit gefahrlos auf allen Breakpoints. */

	/* mp-filter-chip-scroll braucht overflow-x:auto fuers Scrollen — das erzwingt
	   per CSS-Spec implizit auch overflow-y:auto (kein "nur eine Achse"-Clipping
	   moeglich) und wuerde die absolut positionierten Popover darin abschneiden.
	   Fix: Popover auf Mobile als fixiertes Bottom-Sheet rendern, das dem
	   Scroll-Container-Clipping entgeht. */
	.mp-filter-popover {
		position: fixed;
		left: var(--mp-space-m);
		right: var(--mp-space-m);
		top: auto;
		bottom: var(--mp-space-m);
		margin-top: 0;
		width: auto;
		min-width: 0;
		max-height: 70vh;
		overflow-y: auto;
	}

	/* Zimmer-Select bekommt hier (und nur hier) die Chip-Optik der Bricks-
	   Global-Class "mp-filter-chip" (onfix0) — auf Desktop bleibt der Wrapper
	   ein unsichtbares <div>, das native Select-Styling unveraendert. */
	.mp-filter-chip {
		display: inline-flex;
		align-items: center;
		column-gap: var(--mp-space-2xs);
		background: var(--mp-bg-body-color); /* R3 02-02: gleiche helle Fläche wie die Nachbar-Chips */
		border: 1px solid var(--mp-border-primary-color);
		border-radius: var(--mp-radius-full);
		height: var(--mp-control-height); /* DEV-033 E1: bündig mit den Nachbar-Pills */
		padding: 0 var(--mp-space-m);
		box-sizing: border-box;
		font-size: var(--mp-control-font-size);
		font-weight: 500;
		color: var(--mp-text-body-color);
		white-space: nowrap;
		flex-shrink: 0;
		scroll-snap-align: start;
		cursor: pointer;
	}

	/* Kein all:revert mehr (stellte den nativen Select-Pfeil + volle Breite
	   wieder her → doppelter Chevron, Chip lief aus dem Viewport). Die Basis-
	   Regel .mp-filter-select liefert appearance:none + Chevron-Background;
	   hier nur die Chip-Einbettung: transparent, kompakt, eigener Pfeil rechts. */
	.mp-filter-chip .mp-filter-select {
		width: auto;
		height: auto; /* Chip bringt die Kontrollhöhe mit — 48px-Select würde die 46px-Innenhöhe sprengen */
		max-width: 144px; /* px statt rem (10px-Root) */
		border: none;
		background-color: transparent;
		border-radius: 0;
		padding: 0 calc(18px + var(--mp-space-2xs)) 0 0;
		background-position: right 0 center;
		font: inherit;
		color: inherit;
		cursor: pointer;
	}
}

/* ==========================================================================
   DEV-020 Nacharbeit R2 – Featured-Card (erste Karte im Grid)

   Design: _pm/05-designs/"Immobilienangebote Übersicht-featured-object.jpg" —
   gleiche Kartengröße, aber invertierter Body (dunkle Fläche, weiße Schrift)
   + Bookmark-Icon in Primärfarbe statt Favoriten-Herz. Bewusst als reine
   CSS-Variante des ersten Grid-Kindes gelöst (Definition "Featured = erster
   Treffer"): wirkt identisch auf den Bricks-Query-Loop UND das AJAX-Fragment,
   ohne bedingtes Rendering (über Novamira nicht verfügbar, s. Sprint-Doku).
   Die Invertierung läuft über lokale Custom-Property-Overrides — alle inneren
   Regeln (Titel/Preis/Meta/Feature-Row/Icons) referenzieren dieselben Tokens
   und kippen dadurch automatisch mit.
   ========================================================================== */

.mp-grid:not(.mp-similar__grid) > .mp-card:first-child {
	--mp-text-heading-color: #ffffff;
	--mp-text-body-color: rgba(255, 255, 255, 0.85);
	--mp-secondary-color: rgba(255, 255, 255, 0.7);
	--mp-border-primary-color: rgba(255, 255, 255, 0.18);
	background-color: var(--mp-bg-inverse-color, #1a1c1e);
}

/* Badge bleibt hell auf dem Bild (nutzt sonst die invertierten Tokens). */
.mp-grid:not(.mp-similar__grid) > .mp-card:first-child .mp-badge--marketing {
	background-color: #ffffff;
	color: #191c1e;
}

/* Statt Favoriten-Herz: gefülltes Bookmark (Material Symbols) in Primärfarbe
   oben rechts im Content-Bereich — als Mask, damit die Farbe aus dem Token
   var(--mp-primary-color) kommt (data-URIs können kein var()). */
.mp-grid:not(.mp-similar__grid) > .mp-card:first-child .mp-card__fav {
	display: none;
}

.mp-grid:not(.mp-similar__grid) > .mp-card:first-child .mp-card__content {
	position: relative;
	padding-right: calc(var(--mp-space-m) + 30px);
}

.mp-grid:not(.mp-similar__grid) > .mp-card:first-child .mp-card__content::after {
	content: '';
	position: absolute;
	top: var(--mp-space-m);
	right: var(--mp-space-m);
	width: 22px;
	height: 22px;
	background-color: var(--mp-primary-color);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M200-120v-640q0-33 23.5-56.5T280-840h400q33 0 56.5 23.5T760-760v640L480-240 200-120Z'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -960 960 960'%3E%3Cpath d='M200-120v-640q0-33 23.5-56.5T280-840h400q33 0 56.5 23.5T760-760v640L480-240 200-120Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ==========================================================================
   DEV-020 Nacharbeit R2 – QHD/4K-Layout (ab 2560px)

   Design: _pm/05-designs/4K-UHD-Screen-layout.jpg — der Listen-Content
   (Filter-Band, Sort-Row, Grid) deckelt auf die Breite von 4 Karten-Spalten
   und richtet sich RECHTS an der Karte aus; die verbleibende Fläche links
   füllt ein dunkelgrauer Streifen (Hard-Stop-Gradient statt Extra-Element).
   In 4K (3840px) bleibt es bei 4 Spalten, nur der Streifen wächst.
   ========================================================================== */

@media (min-width: 2560px) {
	.mp-archive__list {
		--mp-archive-content-max: 1480px; /* 4×~320px Karten + 3 Gutter + 2×~60px Innenrand */
		background-image: linear-gradient(
			to right,
			color-mix(in srgb, var(--mp-bg-inverse-color, #1a1c1e) 85%, #ffffff) 0,
			color-mix(in srgb, var(--mp-bg-inverse-color, #1a1c1e) 85%, #ffffff) calc(100% - var(--mp-archive-content-max)),
			transparent calc(100% - var(--mp-archive-content-max))
		);
	}

	.mp-archive__list > * {
		width: 100%;
		max-width: var(--mp-archive-content-max);
		margin-left: auto;
		margin-right: 0;
	}

	/* Deckel bei 4 Spalten — auto-fill würde im breiten Panel sonst 5+ bilden. */
	.mp-archive__list .mp-grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

/* === DEV-021 DETAILSEITE (Template 11) ==================================== */
/* Energieskala — Markup kommt server-seitig aus {maklerpress_energy_scale}
   (PropertyDetailFields::energyScaleHtml), daher Plain-CSS statt Bricks-Klasse. */
.mp-energy-band {
	position: relative;
	padding-top: 44px;
	padding-bottom: 4px;
}
.mp-energy-band__bar {
	display: flex;
	height: 16px;
	border-radius: var(--mp-radius-full);
	overflow: hidden;
}
.mp-energy-band__bar span { flex: 1 1 0; }
.mp-energy-band__bar span:nth-child(1) { background: #008f51; }
.mp-energy-band__bar span:nth-child(2) { background: #2ebd59; }
.mp-energy-band__bar span:nth-child(3) { background: #83c658; }
.mp-energy-band__bar span:nth-child(4) { background: #c5d54a; }
.mp-energy-band__bar span:nth-child(5) { background: #fbe031; }
.mp-energy-band__bar span:nth-child(6) { background: #f5b325; }
.mp-energy-band__bar span:nth-child(7) { background: #ee7f23; }
.mp-energy-band__bar span:nth-child(8) { background: #e74f26; }
.mp-energy-band__bar span:nth-child(9) { background: #cc2e2c; }
.mp-energy-band__labels {
	display: flex;
	justify-content: space-between;
	margin-top: var(--mp-space-2xs);
	padding: 0 var(--mp-space-xs);
	font-size: var(--mp-text-2xs);
	font-weight: 700;
	color: var(--mp-secondary-color);
}
.mp-energy-band__marker {
	position: absolute;
	top: 0;
	transform: translateX(-50%);
	display: flex;
	flex-direction: column;
	align-items: center;
}
.mp-energy-band__badge {
	background: var(--mp-text-heading-color);
	color: #fff;
	font-size: var(--mp-text-2xs);
	font-weight: 700;
	padding: 2px 8px;
	border-radius: var(--mp-radius-s);
	box-shadow: var(--mp-shadow);
}
/* Zeiger-Dreieck unter dem Badge */
.mp-energy-band__marker::after {
	content: '';
	width: 0;
	height: 0;
	border-left: 6px solid transparent;
	border-right: 6px solid transparent;
	border-top: 8px solid var(--mp-text-heading-color);
	margin-top: 2px;
}

/* Ähnliche Objekte: Element-HTML (mp-similar) im Card-Stil der Detailseite. */
.mp-detail__main .mp-similar {
	background: var(--mp-bg-body-color);
	border: 1px solid var(--mp-border-primary-color);
	border-radius: var(--mp-radius-l);
	box-shadow: var(--mp-shadow);
	padding: var(--mp-space-xl);
	margin: 0;
}
.mp-detail__main .mp-similar .mp-section__title {
	font-size: var(--mp-head-l);
	font-weight: 600;
	line-height: 1.25;
	color: var(--mp-text-heading-color);
	border-bottom: 1px solid var(--mp-border-primary-color);
	padding-bottom: var(--mp-space-m);
	margin: 0 0 var(--mp-space-l);
}
.mp-detail__main .mp-similar__grid { gap: var(--mp-space-l); }
@media (max-width: 639px) {
	.mp-detail__main .mp-similar { padding: var(--mp-space-l); }
}


/* =========================================================================
   DEV-031: Such-Widget-Ergänzungen
   ========================================================================= */

/* Trefferanzahl im Widget — seit DEV-033 SSR-befüllt in der Abschlusszeile. */
.mp-filter-count {
	align-self: center;
	font-size: var(--mp-control-font-size);
	color: var(--mp-text-muted-color, #6b7280);
	white-space: nowrap;
}

/* Sortier-Select in der Ergebnis-Kopfzeile (ersetzt den Platzhalter mp0006). */
.mp-sort {
	display: inline-flex;
	align-items: center;
	gap: var(--mp-space-xs, 0.5rem);
	white-space: nowrap;
}

.mp-sort select {
	border: none;
	background: transparent;
	font: inherit;
	font-weight: 600;
	color: inherit;
	cursor: pointer;
	padding: 0;
}

/* B-036: Safari hält den Fokus nach der Auswahl auf dem Select — ein
   Outline-Rahmen bliebe dauerhaft stehen. Dezente Unterstreichung statt Box. */
.mp-sort select:focus {
	outline: none;
}

.mp-sort select:focus-visible {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* B-036: Trefferanzahl steht im Such-Widget (data-mp-widget-count) — die große
   Kopfzeilen-Anzeige ist doppelt und entfällt visuell. Das Element bleibt im
   DOM: es ist die Datenquelle des Widget-Zählers (AJAX-JS pflegt .mp-result-count). */
.brxe-query-results-summary.mp-result-count {
	display: none;
}

/* =========================================================================
   DEV-033: Such-Widget-Abschlusszeile (Vorlage 01-06) — Trefferzahl links,
   "Sortieren nach" rechts, Gesehen-Linie als Widget-Unterkante.
   ========================================================================= */

.mp-filter-row--meta {
	align-items: center;
	justify-content: space-between;
}

.mp-filter-sort {
	display: inline-flex;
	align-items: center;
	gap: var(--mp-space-2xs);
	font-size: var(--mp-control-font-size);
	color: var(--mp-secondary-color);
	white-space: nowrap;
}

.mp-filter-sort__select {
	border: none;
	background: transparent;
	font: inherit;
	font-weight: 600;
	color: var(--mp-text-heading-color);
	cursor: pointer;
	padding: 0;
}

/* B-036-Erbe: Safari hält den Fokus nach der Auswahl auf dem Select — dezente
   Unterstreichung statt dauerhaftem Outline-Rahmen. */
.mp-filter-sort__select:focus {
	outline: none;
}

.mp-filter-sort__select:focus-visible {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* Gesehen-Linie im Widget (JS hängt sie als letztes Kind an .mp-search-form):
   erbt das Sticky-Verhalten des Widgets, braucht also keine eigene Position. */
.mp-seen-progress--in-widget {
	position: relative;
	top: auto;
	z-index: auto;
}

/* Luftiger vertikaler Rasterabstand zwischen Widget und Objektkarten. */
.mp-search-filter-element {
	margin-bottom: var(--mp-space-l);
}

/* ------------------------------------------------------------------------
   DEV-033 E4: Aktive-Filter-Chips (Einzel-Entfernen), Live-Zähler-Umfeld,
   Skeleton-Cards, A11y-Fokus.
   ------------------------------------------------------------------------ */

/* hidden-Attribut muss auch gegen display-setzende Regeln gewinnen
   (Reset-Link ist inline-flex, Chips-Zeile flex). */
.mp-search-form [hidden] {
	display: none !important;
}

.mp-filter-row--chips {
	gap: var(--mp-space-xs);
}

.mp-filter-chip-active {
	display: inline-flex;
	align-items: center;
	gap: var(--mp-space-2xs);
	background: color-mix(in srgb, var(--mp-primary-color) 8%, var(--mp-bg-body-color));
	border: 1px solid color-mix(in srgb, var(--mp-primary-color) 35%, transparent);
	border-radius: var(--mp-radius-full);
	padding: 0 var(--mp-space-s);
	height: 32px; /* bewusst kompakter als --mp-control-height: sekundäre Ebene */
	font-size: var(--mp-text-xs);
	font-weight: 500;
	color: var(--mp-primary-color);
	cursor: pointer;
	transition: border-color .2s, background-color .2s;
}

.mp-filter-chip-active:hover {
	border-color: var(--mp-primary-color);
}

.mp-filter-chip-active__x {
	font-size: 1.2em;
	line-height: 1;
}

/* Skeleton-Cards: neutraler Karten-Platzhalter mit Schimmer-Animation. */
.mp-skeleton-card {
	border: 1px solid var(--mp-border-primary-color);
	border-radius: var(--mp-radius-l);
	padding: var(--mp-space-m);
	display: flex;
	flex-direction: column;
	gap: var(--mp-space-s);
}

.mp-skeleton-card__media,
.mp-skeleton-card__line {
	border-radius: var(--mp-radius-s);
	background: linear-gradient(
		90deg,
		var(--mp-bg-surface-color) 25%,
		color-mix(in srgb, var(--mp-bg-surface-color) 40%, #ffffff) 37%,
		var(--mp-bg-surface-color) 63%
	);
	background-size: 400% 100%;
	animation: mp-skeleton-shimmer 1.4s ease infinite;
}

.mp-skeleton-card__media {
	aspect-ratio: 16 / 10;
	width: 100%;
}

.mp-skeleton-card__line {
	height: 14px;
	width: 100%;
}

.mp-skeleton-card__line--wide {
	width: 85%;
	height: 18px;
}

.mp-skeleton-card__line--short {
	width: 45%;
}

@keyframes mp-skeleton-shimmer {
	0%   { background-position: 100% 0; }
	100% { background-position: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
	.mp-skeleton-card__media,
	.mp-skeleton-card__line {
		animation: none;
	}
}

/* User-Feedback P3: native Select-Dropdowns rendern im OS-Dark-Mode dunkel,
   während die Seite hell ist — color-scheme pinnt das Widget auf hell. */
.mp-search-form {
	color-scheme: light;
}

/* User-Feedback P6 (Desktop-Raster): Zeile 2 nutzt DASSELBE Spaltenraster wie
   Zeile 1 — Ort über 2 Spalten, Umkreis + Objekt-ID je 1; damit schließen die
   Felder beider Zeilen im gleichen vertikalen Raster ab. */
@media (min-width: 960px) {
	.mp-filter-row--ort {
		display: grid;
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.mp-filter-field--ort {
		grid-column: span 2;
	}

	.mp-filter-field--radius,
	.mp-filter-field--objekt-id {
		min-width: 0;
	}
}

/* Tablet-Split (960–1199px): Zeile 1 ist dort 2×2 — Zeile 2 analog:
   Ort volle Zeile, darunter Umkreis + Objekt-ID nebeneinander. */
@media (min-width: 960px) and (max-width: 1199px) {
	.mp-filter-row--ort {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* User-Feedback P4 (Mobile, Vorlage 01-07): volle Bildschirmbreite, kompaktere
   Kontrollen, Ergebnisse + Sortierung in EINER Zeile. */
@media (max-width: 959px) {
	/* Full-bleed über das Container-Padding hinaus. WICHTIG: .mp-archive__list
	   ist ein Column-FLEX-Container — negative Margins VERSCHIEBEN ein
	   Flex-Item nur, verbreitern es aber nicht (Bug 13-Spalt-rechts, User-
	   Screenshot). Deshalb explizite 100vw-Breite + Linksverschiebung. */
	.mp-search-filter-element {
		width: 100vw;
		margin-left: calc(50% - 50vw);
		margin-right: 0;
	}

	/* Folge-Fix (User-Meldung "Karten nicht zentriert"): Das 100vw-Widget
	   verbreitert die Flex-LINIE — die auto-Margins des Bricks-Grid-Containers
	   verteilen den so entstandenen freien Raum asymmetrisch zur Content-Box
	   (links 24px, rechts 8px). Auto-Zentrierung hier neutralisieren; die
	   Breite regelt ohnehin max-width:100% + das Listen-Padding. */
	.mp-archive__list .mp-grid {
		margin-left: 0;
		margin-right: 0;
	}

	/* Kompaktere Kontrollen + engeres Raster (Token lokal überschrieben;
	   die 16px-iOS-Schrift für Inputs/Selects bleibt unberührt — B-034). */
	.mp-search-form__form {
		--mp-control-height: 42px;
		--mp-filter-gap: 12px;
		padding: var(--mp-space-m);
	}

	.mp-filter-chip-active {
		height: 28px;
	}

	/* Ergebnisse links + "Sortieren:" rechts in EINER Zeile. */
	.mp-filter-row--meta {
		flex-wrap: nowrap;
		min-width: 0;
	}

	.mp-filter-count {
		font-size: var(--mp-text-xs);
	}

	.mp-filter-sort {
		font-size: var(--mp-text-xs);
		min-width: 0;
	}
}

/* A11y (BFSG): sichtbarer Tastatur-Fokus auf allen Widget-Kontrollen —
   ersetzt das outline:none der Basisregeln NUR im :focus-visible-Fall. */
.mp-filter-select:focus-visible,
.mp-filter-input:focus-visible,
.mp-filter-pill:focus-visible,
.mp-filter-chip-active:focus-visible,
.mp-filter-popover__field input[type="number"]:focus-visible,
.mp-filter-popover__actions button:focus-visible,
.mp-search-form .mp-btn-primary:focus-visible,
.mp-filter-checkbox-item input:focus-visible {
	outline: 2px solid var(--mp-primary-color);
	outline-offset: 2px;
}

/* B-034: iOS Safari zoomt beim Fokus in Felder mit Schriftgröße < 16px in die
   Seite hinein (Layout "schwimmt" seitlich). Auf Touch-Viewports bekommen alle
   Controls des Such-Widgets deshalb mindestens 16px. Bewusst KEIN
   maximum-scale-Viewport-Hack (verbietet Nutzer-Zoom, BFSG/A11y). Die nativen
   Bricks-Formulare regelt dieselbe Regel im Bricks-Theme-Style (Seed). */
@media (max-width: 767px) {
	.mp-search-form__form select,
	.mp-search-form__form input:not([type="checkbox"]):not([type="radio"]),
	.mp-search-form__form textarea {
		font-size: 16px;
	}
}

/* ==========================================================================
   DEV-032 – Archiv-Politur: weiches Einblenden (B-041) + Gesehen-Indikator
   ========================================================================== */

/* B-041: Per Endlos-Scroll (B-038) angehängte Karten weich einblenden.
   Bewusst eine KEYFRAME-Animation statt Transition: .mp-card trägt seit B-030
   einen transform (Containing Block für den Stretched-Link) — eine from-only-
   Keyframe endet automatisch wieder auf dem computed transform der Karte,
   ohne den B-030-Wert zu überschreiben. Stagger via --mp-enter-i (JS, gedeckelt). */
@media (prefers-reduced-motion: no-preference) {
	.mp-card--enter {
		animation: mp-card-enter 0.4s ease both;
		animation-delay: calc(var(--mp-enter-i, 0) * 45ms);
	}

	@keyframes mp-card-enter {
		from {
			opacity: 0;
			transform: translateY(14px);
		}
	}
}

/* Gesehen-Indikator (ROADMAP Epic B): dünne Fortschritts-Linie über der
   Endlos-Liste (Lesemarker-Prinzip) — Füllstand = gesehene Karten / Treffer
   gesamt (.mp-result-count). JS (maklerpress-filter.js) hängt das Element an
   den Anfang des Grids und pflegt --mp-seen-ratio. sticky klebt im Desktop-
   Split-View am oberen Rand des internen Scrollers .mp-archive__list, mobil
   am Viewport (unter dem Header, s. Media Query). */
.mp-seen-progress {
	position: sticky;
	top: 0;
	z-index: 5;
	/* .mp-archive__list ist ein Column-Flex-Scroller mit align-items:flex-start
	   (Bricks-Default) — ohne explizite Breite schrumpft die Linie auf 0px
	   Breite, ohne flex:none drückt der überlaufende Inhalt sie auf 0px Höhe. */
	width: 100%;
	flex: none;
	grid-column: 1 / -1;
	height: 3px;
	margin: 0;
	background-color: color-mix(in srgb, var(--mp-primary-color) 15%, transparent);
	border-radius: 2px;
	overflow: hidden;
	pointer-events: none;
}

.mp-seen-progress > span {
	display: block;
	height: 100%;
	width: calc(var(--mp-seen-ratio, 0) * 100%);
	background-color: var(--mp-primary-color);
	border-radius: inherit;
	transition: width 0.25s ease;
}

@media (prefers-reduced-motion: reduce) {
	.mp-seen-progress > span {
		transition: none;
	}
}

@media (max-width: 959px) {
	/* Kollabiertes Layout: das Fenster scrollt — unter dem fixen Header kleben. */
	.mp-seen-progress {
		top: var(--mp-header-height, 0px);
	}
}

/* --------------------------------------------------------------------------
 * DEV-034 W2: POI-Sektion „Das ist in der Nähe" (OSM Overpass).
 * Genutzt von der Bricks-Sektion (Tokens maklerpress_poi_*) UND dem
 * PHP-Fallback (templates/single/parts/poi.php).
 * ------------------------------------------------------------------------ */

.mp-poi__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
	gap: 24px;
}

.mp-poi__category-title {
	margin: 0 0 8px;
	font-size: 15px;
	font-weight: 600;
}

.mp-poi-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.mp-poi-list__item {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 12px;
	padding: 4px 0;
	border-bottom: 1px solid color-mix(in srgb, currentColor 12%, transparent);
	font-size: 14px;
}

.mp-poi-list__item:last-child {
	border-bottom: 0;
}

.mp-poi-list__dist {
	white-space: nowrap;
	opacity: 0.65;
}

.mp-poi__attribution {
	margin-top: 12px;
	font-size: 12px;
	opacity: 0.6;
}

/* Karte „Das ist in der Nähe" komplett ausblenden, wenn keine Kategorie
 * eine Liste liefert; leere Kategorie-Blöcke via mp-cond-probe (Bricks). */
.mp-poi-card:not(:has(.mp-poi-list)) {
	display: none;
}

/* --------------------------------------------------------------------------
 * DEV-035 W2: Lage-Story — Gehminuten-Leiste, Kategorie-Chips, POI-Kopplung
 * an die Detailkarte (Fly-to). Markup aus PoiListRenderer (Tokens + Fallback),
 * Verhalten in maklerpress-lage-story.js.
 * ------------------------------------------------------------------------ */

.mp-poi-walk {
	display: flex;
	flex-wrap: wrap;
	gap: var(--mp-space-xs);
	margin: 0 0 var(--mp-space-s);
	padding: 0;
	list-style: none;
}

.mp-poi-walk__item {
	display: flex;
	align-items: baseline;
	gap: 6px;
	padding: 6px 12px;
	border: 1px solid var(--mp-border-primary-color, #e2e8f0);
	border-radius: var(--mp-radius-full);
	background: var(--mp-bg-surface-color, #f8fafc);
	font-size: var(--mp-text-s);
	line-height: 1.2;
}

.mp-poi-walk__label {
	font-weight: 600;
}

.mp-poi-walk__value {
	color: var(--mp-primary-color, #1a56db);
	font-weight: 600;
	white-space: nowrap;
}

.mp-poi-walk__name {
	opacity: 0.6;
	max-width: 16ch;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.mp-poi-walk__note {
	margin: 0 0 var(--mp-space-s);
	font-size: var(--mp-text-xs);
	opacity: 0.6;
}

/* Chip-Filter blendet ganze Kategorie-Spalten aus (Bricks + PHP-Pfad). */
.mp-poi__category[hidden] {
	display: none;
}

.mp-poi-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: var(--mp-space-m);
}

.mp-poi-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 36px;
	padding: 0 14px;
	border: 1px solid var(--mp-border-primary-color, #e2e8f0);
	border-radius: var(--mp-radius-full);
	background: transparent;
	color: inherit;
	font: inherit;
	font-size: var(--mp-text-s);
	cursor: pointer;
}

.mp-poi-chip:hover {
	border-color: var(--mp-primary-color, #1a56db);
}

.mp-poi-chip--active {
	border-color: var(--mp-primary-color, #1a56db);
	background: var(--mp-primary-color, #1a56db);
	color: #fff;
}

.mp-poi-chip__count {
	font-size: var(--mp-text-xs);
	opacity: 0.7;
}

/* Anklickbare POI-Zeile: der Button trägt jetzt das Zeilen-Layout.
   min-height 44px = Touch-Ziel-Mindestmaß (iOS-HIG) — die Zeile ist auf
   dem Smartphone die Haupt-Interaktion der Lage-Story. */
.mp-poi-list__btn {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 12px;
	width: 100%;
	min-height: 44px;
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	text-align: left;
	cursor: pointer;
}

.mp-poi-list__item:has(.mp-poi-list__btn) {
	display: block;
}

.mp-poi-list__btn:hover .mp-poi-list__name,
.mp-poi-list__btn:focus-visible .mp-poi-list__name {
	color: var(--mp-primary-color, #1a56db);
	text-decoration: underline;
}

.mp-poi-list__item--active .mp-poi-list__name {
	color: var(--mp-primary-color, #1a56db);
	font-weight: 600;
}

/* POI-Marker auf der Detailkarte (beide Provider, gleiche Optik). */
.mp-poi-pin {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border: 2px solid #fff;
	border-radius: var(--mp-radius-full);
	background: var(--mp-primary-color, #1a56db);
	box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	line-height: 1;
	transition: transform 0.15s ease-out;
}

/* Leaflet-Anker wie beim Preis-Pin: divIcon sitzt auf der Koordinate,
   der Punkt wird per Transform darauf zentriert. */
.mp-poi-pin-anchor {
	background: none;
	border: none;
}

.mp-poi-pin-anchor .mp-poi-pin {
	position: absolute;
	left: 0;
	top: 0;
	transform: translate(-50%, -50%);
}

.mp-poi-pin-anchor .mp-poi-pin--active {
	transform: translate(-50%, -50%) scale(1.3);
}

.mp-poi-pin--active {
	background: var(--mp-marker-color, #df5634);
	z-index: 2;
}

/* Google ankert AdvancedMarkerElement unten-mittig — Punkt dort zentrieren. */
.mp-map-container[data-provider="google"] .mp-poi-pin {
	transform: translateY(50%);
}

.mp-map-container[data-provider="google"] .mp-poi-pin--active {
	transform: translateY(50%) scale(1.3);
}

/* Routen-Overlay „Pendelzeit": Linie wird beim Zeichnen eingezogen. */
.mp-route-line {
	animation: mp-route-draw 1.2s ease-out forwards;
}

@keyframes mp-route-draw {
	from {
		stroke-dashoffset: 1200;
	}
	to {
		stroke-dashoffset: 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.mp-route-line {
		animation: none;
	}
}

.mp-route-label {
	padding: 4px 10px;
	border-radius: var(--mp-radius-full);
	background: var(--mp-bg-inverse-color, #1a1c1e);
	color: #fff;
	font-size: var(--mp-text-xs);
	font-weight: 600;
	white-space: nowrap;
	box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
	transform: translateY(-50%);
}

/* --------------------------------------------------------------------------
 * DEV-034 W3: Fahrzeit-Widget „Pendelzeit" (mp-commute-widget).
 * ------------------------------------------------------------------------ */

.mp-commute__label {
	display: block;
	margin-bottom: 8px;
	font-weight: 600;
}

.mp-commute__row {
	display: flex;
	gap: 8px;
}

.mp-commute__input {
	flex: 1 1 auto;
	min-width: 0;
	height: var(--mp-control-height, 48px);
	padding: 0 12px;
	font-size: var(--mp-control-font-size, 14px);
	border: 1px solid color-mix(in srgb, currentColor 25%, transparent);
	border-radius: 6px;
	color-scheme: light;
}

.mp-commute__btn {
	flex: 0 0 auto;
	height: var(--mp-control-height, 48px);
	padding: 0 18px;
	font-size: var(--mp-control-font-size, 14px);
	font-weight: 600;
	color: #fff;
	background-color: var(--mp-primary-color);
	border: 0;
	border-radius: 6px;
	cursor: pointer;
}

.mp-commute--busy .mp-commute__btn {
	opacity: 0.6;
	cursor: wait;
}

.mp-commute__hint {
	margin: 8px 0 0;
	font-size: 12px;
	opacity: 0.6;
}

.mp-commute__consent {
	margin-top: 12px;
	padding: 12px;
	border: 1px solid color-mix(in srgb, var(--mp-primary-color) 35%, transparent);
	border-radius: 6px;
	font-size: 14px;
}

.mp-commute__consent p {
	margin: 0 0 8px;
}

.mp-commute__results {
	display: flex;
	gap: 24px;
	margin: 12px 0 0;
}

.mp-commute__result dt {
	font-size: 12px;
	opacity: 0.65;
}

.mp-commute__result dd {
	margin: 0;
	font-weight: 600;
	color: var(--mp-text-heading-color);
}

/* --------------------------------------------------------------------------
 * DEV-035 W3: Street View (statische Straßenansicht, hinter Maps-Consent).
 * ------------------------------------------------------------------------ */

.mp-streetview__title {
	margin: 0 0 var(--mp-space-xs);
	font-size: var(--mp-text-l);
	font-weight: 600;
}

.mp-streetview__frame {
	position: relative;
	overflow: hidden;
	min-height: var(--mp-streetview-height, 360px);
	border-radius: var(--mp-radius-m);
	background: var(--mp-bg-surface-color, #f8fafc);
}

.mp-streetview__img {
	display: block;
	width: 100%;
	height: var(--mp-streetview-height, 360px);
	object-fit: cover;
}

.mp-streetview__consent {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: var(--mp-space-xs);
	padding: var(--mp-space-m);
	text-align: center;
	font-size: var(--mp-text-s);
}

.mp-streetview__consent p {
	margin: 0;
	max-width: 46ch;
	opacity: 0.8;
}

.mp-streetview__btn {
	height: var(--mp-control-height, 48px);
	padding: 0 18px;
	border: 0;
	border-radius: 6px;
	background-color: var(--mp-primary-color);
	color: #fff;
	font-size: var(--mp-control-font-size, 14px);
	font-weight: 600;
	cursor: pointer;
}

.mp-streetview__note {
	margin: var(--mp-space-2xs) 0 0;
	font-size: var(--mp-text-xs);
	opacity: 0.6;
}

/* DEV-035 W2: Route je Verkehrsmittel auf die Detailkarte legen. */
.mp-commute__route {
	display: block;
	margin-top: 2px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--mp-link-color, #1a56db);
	font-size: var(--mp-text-xs);
	font-weight: 500;
	text-decoration: underline;
	cursor: pointer;
}

.mp-commute__result--active dd {
	color: var(--mp-primary-color, #1a56db);
}

.mp-commute__result--active .mp-commute__route {
	text-decoration: none;
	opacity: 0.6;
	cursor: default;
}

.mp-commute__error {
	margin: 8px 0 0;
	font-size: 13px;
	color: #b32d2e;
}

@media (max-width: 639px) {
	.mp-commute__row {
		flex-direction: column;
	}
}

/* ==========================================================================
   DEV-035 W1 – Mobile Kartenansicht (User-Vorlagen 01-08/01-09)

   Liste bleibt Default; body.mp-view-map (maklerpress-mobile-map.js) schaltet
   < 960px auf die Vollbild-Karte um: Widget verschlankt (Zeile 1 + Ergebnis/
   Sortieren), Karten-Panel füllt den Rest-Viewport (Full-Bleed). Der runde
   Ansichts-Toggle sitzt als Body-Portal unten rechts (B-029-Muster,
   safe-area-inset). Ebenen-Regel §5.0.5: unten genau EINE aktive Ebene —
   Z-Reihenfolge Filter-Sheet (50) > Preview-Card (45) > Toggle (40) > Karte.
   ========================================================================== */

.mp-view-toggle {
	position: fixed;
	right: calc(var(--mp-space-m, 16px) + env(safe-area-inset-right, 0px));
	bottom: calc(var(--mp-space-l, 24px) + env(safe-area-inset-bottom, 0px));
	z-index: 40;
	display: none;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	padding: 0;
	border: none;
	border-radius: var(--mp-radius-full, 9999px);
	background: var(--mp-bg-inverse-color, #1a1c1e);
	color: #ffffff;
	box-shadow: 0 4px 16px rgba(26, 28, 30, 0.35);
	cursor: pointer;
	transition: opacity 0.2s ease, transform 0.2s ease;
}

@media (max-width: 959px) {
	.mp-view-toggle {
		display: flex;
	}
}

.mp-view-toggle:focus-visible {
	outline: 2px solid var(--mp-primary-color);
	outline-offset: 2px;
}

/* Ebenen-Regel §5.0.5: Toggle weicht aus, solange Filter-Sheet oder
   Preview-Card die untere Ebene belegen (gilt auch in der Listenansicht). */
body.mp-sheet-open .mp-view-toggle,
body.mp-card-open .mp-view-toggle {
	opacity: 0;
	pointer-events: none;
	transform: translateY(8px);
}

@media (max-width: 959px) {
	/* Karte füllt den Viewport unter Header + verschlanktem Widget —
	   das Fenster selbst scrollt nicht mehr (Footer bleibt unerreichbar,
	   Rückweg über den Listen-Toggle). Der Seiten-Scroller ist das
	   HTML-Element — die Klasse setzt maklerpress-mobile-map.js deshalb
	   auf <html> UND <body>. */
	html.mp-view-map,
	body.mp-view-map {
		overflow: hidden;
	}

	body.mp-view-map .mp-archive {
		height: calc(100dvh - var(--mp-header-height, 0px));
		min-height: 0;
		overflow: hidden;
	}

	body.mp-view-map .mp-archive__list {
		flex: 0 0 auto;
		height: auto;
		overflow: visible;
	}

	/* Nur das Such-Widget bleibt aus dem Listen-Panel sichtbar (Grid,
	   Pagination, Skeletons entfallen in der Kartenansicht). */
	body.mp-view-map .mp-archive__list > :not(.mp-search-filter-element) {
		display: none;
	}

	/* Widget-Verschlankung (Vorlage 01-09, Festlegung 2): Zeile 1 +
	   Ergebnis-Zeile; Ort/Chips/aktive Filter/Gesehen-Linie über „zurück
	   zur Liste" erreichbar. Feedback-Runde 1 (2026-07-27): auch das
	   Sortier-Select entfällt — auf der Karte ist eine Listen-Sortierung
	   sinnlos; die Trefferzahl (mp-filter-count) bleibt IMMER sichtbar. */
	body.mp-view-map .mp-filter-row--ort,
	body.mp-view-map .mp-filter-row--pills,
	body.mp-view-map .mp-filter-row--chips,
	body.mp-view-map .mp-filter-sort,
	body.mp-view-map .mp-search-form .mp-seen-progress {
		display: none;
	}

	/* Feedback-Runde 1 (2026-07-27): Karte schließt BÜNDIG ans Widget an —
	   der DEV-033-Rasterabstand (margin-bottom --mp-space-l, gedacht für den
	   Übergang Widget → Objektkarten) erzeugte in der Kartenansicht einen
	   weißen Streifen über der Karte. */
	body.mp-view-map .mp-search-filter-element {
		margin-bottom: 0;
	}

	/* Feedback-Runde 4: „Suche zurücksetzen" sitzt in der Kartenansicht als
	   kompakte Variante rechts neben der Trefferzahl (Meta-Zeile ist
	   space-between; der Zustandsautomat in maklerpress-filter.js hängt den
	   Listen-Reset-Link hierher um — Sichtbarkeits-Logik wandert mit). */
	body.mp-view-map .mp-filter-row--meta .mp-btn-primary {
		height: 32px;
		padding: 0 var(--mp-space-s);
		font-size: var(--mp-text-xs);
		white-space: nowrap;
		flex: 0 0 auto;
	}

	/* Karten-Panel einblenden — überstimmt das display:none der Global Class
	   mp-archive__map (Mobile-Kollaps DEV-020 Phase 5) per Spezifität. */
	body.mp-view-map .mp-archive__map {
		display: block;
		position: relative;
		top: auto;
		flex: 1 1 auto;
		min-height: 0;
		width: 100%;
		max-width: 100%;
		height: auto;
	}
}

/* --------------------------------------------------------------------------
 * Bottom-Preview-Card (Pin-Tap, wischbar): Foto/Preis/Meta + Exposé/Anfragen.
 * ------------------------------------------------------------------------ */

/* Feedback-Runde 5: Die Card ist ein SLIDER-Viewport (Swiper) — der
   Container selbst ist transparent, die weiße Karten-Fläche (Radius/
   Schatten) trägt jede einzelne Slide, damit beim Peek/Ziehen die
   Nachbar-Karte als eigene Karte sichtbar wird. Horizontale Gesten
   verwaltet Swiper (setzt selbst touch-action) — daher hier KEIN
   touch-action:none mehr (Runde-4-Regel wanderte zu Swiper). */
.mp-map-card {
	position: fixed;
	/* Feedback-Runden 6+7: Viewport läuft auf BEIDEN Seiten bis an den
	   Bildschirmrand — Peek-Karten (rechts: nächste; links: vorherige am
	   Stapel-Ende) werden erst vom Screen beschnitten und schweben als
	   echte Karten über der Map. Die 16px-Ränder der aktiven Karte kommen
	   aus den Swiper-Offsets (slidesOffsetBefore/After, mobile-map.js). */
	left: 0;
	right: 0;
	bottom: calc(var(--mp-space-m, 16px) + env(safe-area-inset-bottom, 0px));
	z-index: 45;
}

.mp-map-card__swiper {
	overflow: hidden;
	/* Luft für den Slide-Schatten (overflow clippt ihn sonst hart). */
	padding: 6px;
	margin: -6px;
}

.mp-map-card__swiper .swiper-wrapper {
	align-items: stretch;
}

.mp-map-card__swiper .swiper-slide {
	height: auto;
}

.mp-map-card__slide {
	position: relative;
	display: flex;
	flex-direction: column;
	box-sizing: border-box;
	background: var(--mp-bg-body-color, #ffffff);
	border-radius: var(--mp-radius-l, 12px);
	box-shadow: 0 8px 25px rgba(26, 28, 30, 0.25);
	overflow: hidden;
}

.mp-map-card[hidden] {
	display: none !important;
}

@media (min-width: 960px) {
	.mp-map-card {
		display: none;
	}
}

@media (prefers-reduced-motion: no-preference) {
	.mp-map-card:not([hidden]) {
		animation: mp-map-card-up 0.25s ease;
	}

	@keyframes mp-map-card-up {
		from {
			opacity: 0;
			transform: translateY(24px);
		}
	}
}

.mp-map-card__close {
	position: absolute;
	top: 8px;
	right: 8px;
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: none;
	border-radius: var(--mp-radius-full, 9999px);
	background: rgba(255, 255, 255, 0.9);
	color: var(--mp-text-heading-color);
	cursor: pointer;
	box-shadow: 0 1px 3px rgba(26, 28, 30, 0.15);
}

.mp-map-card__main {
	position: relative;
	display: flex;
	gap: var(--mp-space-m);
	padding: var(--mp-space-m);
}

.mp-map-card__media {
	position: relative;
	flex: 0 0 auto;
}

.mp-map-card__image {
	display: block;
	width: 112px;
	height: 96px;
	object-fit: cover;
	border-radius: var(--mp-radius-m, 8px);
	background: var(--mp-bg-surface-color, #f1f5f9);
}

.mp-map-card__badges {
	position: absolute;
	top: 6px;
	left: 6px;
	display: flex;
	gap: 4px;
}

.mp-map-card__badge {
	background: var(--mp-bg-body-color, #ffffff);
	color: var(--mp-text-body-color);
	font-size: var(--mp-text-2xs);
	font-weight: 600;
	line-height: 1;
	padding: 4px 7px;
	border-radius: var(--mp-radius-s, 4px);
	box-shadow: 0 1px 3px rgba(26, 28, 30, 0.15);
}

.mp-map-card__badge--status {
	background: var(--mp-bg-inverse-color, #1a1c1e);
	color: #ffffff;
}

.mp-map-card__body {
	display: flex;
	flex-direction: column;
	min-width: 0;
	padding-right: 24px;
}

.mp-map-card__title {
	font-family: var(--mp-font-heading);
	font-size: var(--mp-text-m);
	font-weight: 600;
	line-height: 1.3;
	color: var(--mp-text-heading-color);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.mp-map-card__meta {
	margin-top: 2px;
	font-size: var(--mp-text-s);
	color: var(--mp-secondary-color);
}

.mp-map-card__price {
	margin-top: var(--mp-space-2xs);
	font-family: var(--mp-font-heading);
	font-size: var(--mp-text-m);
	font-weight: 700;
	color: var(--mp-text-heading-color);
}

.mp-map-card__features {
	margin-top: 2px;
	font-size: var(--mp-text-xs);
	color: var(--mp-secondary-color);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.mp-map-card__pos {
	position: absolute;
	right: var(--mp-space-m);
	bottom: var(--mp-space-s);
	font-size: var(--mp-text-2xs);
	color: var(--mp-secondary-color);
	/* Liegt über der Eckdaten-Zeile — eigene Fläche statt Text-auf-Text. */
	background: var(--mp-bg-body-color, #ffffff);
	padding-left: 6px;
}

.mp-map-card__actions {
	display: flex;
	gap: var(--mp-space-s);
	padding: 0 var(--mp-space-m) var(--mp-space-m);
}

.mp-map-card__btn {
	flex: 1 1 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	height: 44px;
	border: 1px solid var(--mp-border-primary-color);
	border-radius: var(--mp-radius-m, 8px);
	font-size: var(--mp-control-font-size, 14px);
	font-weight: 600;
	text-decoration: none;
	color: var(--mp-text-heading-color);
	background: var(--mp-bg-body-color, #ffffff);
}

.mp-map-card__btn--primary {
	background: var(--mp-primary-color);
	border-color: var(--mp-primary-color);
	color: #ffffff;
}

/* --------------------------------------------------------------------------
 * Status-Pins VERKAUFT/RESERVIERT (EV-Ladekarten-Muster, Konzept §2) und
 * Aktiv-Zustand bei offener Preview-Card — beide Karten-Provider, Markup aus
 * buildPinIcon (Leaflet) bzw. buildPinElement (Google).
 * ------------------------------------------------------------------------ */

.mp-map-pin--verkauft .mp-map-pin__label {
	background: var(--mp-bg-inverse-color, #1a1c1e);
}

.mp-map-pin--verkauft::after {
	border-top-color: var(--mp-bg-inverse-color, #1a1c1e);
}

.mp-map-pin--reserviert .mp-map-pin__label {
	background: #ffffff;
	color: var(--mp-text-heading-color, #1a1c1e);
	box-shadow: inset 0 0 0 1px var(--mp-border-primary-color, #e2e8f0);
}

.mp-map-pin--reserviert::after {
	border-top-color: #ffffff;
}

.mp-map-pin--active .mp-map-pin__label {
	box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.9), 0 2px 8px rgba(26, 28, 30, 0.35);
}

/* DEV-035 W5: „Neu" (serverseitig, PropertyBadges) und „schon gesehen"
   (rein lokal, maklerpress-seen.js). Beides bewusst dezent — der Preis
   bleibt die Hauptinformation des Pins. */
.mp-map-pin--new .mp-map-pin__label::before {
	content: '';
	display: inline-block;
	width: 6px;
	height: 6px;
	margin-right: 5px;
	border-radius: var(--mp-radius-full, 9999px);
	background: #ffffff;
	vertical-align: middle;
}

.mp-map-pin--seen .mp-map-pin__label {
	opacity: 0.62;
}

.mp-map-pin--seen.mp-map-pin--active .mp-map-pin__label {
	opacity: 1;
}

/* DEV-035 W5 (User-Feedback 2026-07-28): Der Spillover-Hinweis der
   Umkreissuche ist KEINE Widget-Zeile mehr (überfrachtet das Widget, kostet
   auf Mobile Kartenfläche), sondern ein schwebender, nicht-blockierender
   Hinweis unter dem Widget: absolut positioniert → die Widget-Höhe bleibt
   unverändert; blendet sich nach wenigen Sekunden selbst aus.
   Markup baut maklerpress-filter.js (renderSpillover). */
.mp-spillover-toast {
	position: absolute;
	top: 100%;
	left: var(--mp-space-l);
	right: var(--mp-space-l);
	z-index: 20;
	display: flex;
	align-items: center;
	gap: var(--mp-space-xs);
	/* Kleiner Abstand zur Widget-Unterkante — die Gesehen-Linie sitzt dort
	   und darf nicht überdeckt werden. */
	margin-top: 4px;
	padding: 10px 12px 10px 14px;
	border-radius: var(--mp-radius-m);
	background: var(--mp-bg-inverse-color, #1a1c1e);
	box-shadow: 0 6px 16px rgba(26, 28, 30, 0.28);
	color: #ffffff;
	font-size: var(--mp-text-s);
	line-height: 1.35;
	opacity: 0;
	transform: translateY(-6px);
	transition: opacity 0.2s ease-out, transform 0.2s ease-out;
	pointer-events: none;
}

.mp-spillover-toast--in {
	opacity: 1;
	transform: translateY(0);
}

.mp-spillover-toast__text {
	flex: 1 1 auto;
}

.mp-spillover-toast__close {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	padding: 0;
	border: 0;
	border-radius: var(--mp-radius-full, 9999px);
	background: none;
	color: inherit;
	cursor: pointer;
	opacity: 0.75;
	/* Nur der Schließen-Button ist bedienbar — der Hinweis selbst darf keine
	   Klicks auf Liste/Karte darunter abfangen. */
	pointer-events: auto;
}

.mp-spillover-toast__close:hover,
.mp-spillover-toast__close:focus-visible {
	opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
	.mp-spillover-toast {
		transition: none;
		transform: none;
	}
}

/* --------------------------------------------------------------------------
 * Aktiv-Hervorhebung aller Filter-Kontrollen (Feedback-Runde 4): Kontrollen
 * MIT gesetztem Wert bekommen den 1px-Primärfarben-Rand — gleiche Formsprache
 * wie der Pill-Aktiv-Zustand (.mp-filter-pill--active), GENERELL in beiden
 * Ansichten (in der Karte der einzige Indikator, in der Liste ergänzend zu
 * den Entfernen-Chips). Klasse setzt updateControlHighlights()
 * (maklerpress-filter.js).
 * ------------------------------------------------------------------------ */

.mp-filter-select.mp-filter-control--active,
.mp-filter-input.mp-filter-control--active {
	border-color: var(--mp-primary-color);
	color: var(--mp-primary-color);
}

/* Zimmer-Chip (mobil): der Wrapper trägt den Rand, das Select darin ist
 * randlos — :has() ist im Projekt etabliert (POI-Card-Ausblendung). */
.mp-filter-chip:has(.mp-filter-control--active) {
	border-color: var(--mp-primary-color);
	color: var(--mp-primary-color);
}

/* --------------------------------------------------------------------------
 * Standort-Button (Feedback-Runde 1, vorgezogen aus W5): „Meinen Standort
 * anzeigen" auf Archiv-Karten — beide Provider, Mobile UND Desktop-Split
 * (mobile Nutzung auf Laptops/Tablets ≥960px). Geolocation-Prompt erst nach
 * Tap (DSGVO/Konzept §3). Markup bauen die Karten-Skripte (buildLocate…).
 * ------------------------------------------------------------------------ */

.mp-map-locate {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: none;
	border-radius: var(--mp-radius-full, 9999px);
	background: #ffffff;
	color: var(--mp-text-heading-color, #1a1c1e);
	box-shadow: 0 1px 4px rgba(26, 28, 30, 0.3);
	cursor: pointer;
}

/* Leaflet rendert den Button als Control unter dem Zoom (topright) und
   bringt eigene Control-Abstände mit; beim Google-Pfad sorgt die
   ControlPosition RIGHT_TOP für die Einordnung — hier nur der Abstand. */
.gm-style .mp-map-locate {
	margin: 10px;
}

.mp-map-locate--busy {
	opacity: 0.6;
	cursor: wait;
}

.mp-map-locate--error {
	color: #b32d2e;
}

/* „Mein Standort"-Punkt: konventionsblau (bewusst NICHT Marker-CI — der
   eigene Standort darf nicht wie ein Objekt-Pin aussehen). */
.mp-map-me {
	width: 16px;
	height: 16px;
	border-radius: var(--mp-radius-full, 9999px);
	background: #1a73e8;
	border: 3px solid #ffffff;
	box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.35), 0 1px 4px rgba(26, 28, 30, 0.3);
}

.mp-map-me-anchor {
	background: none;
	border: none;
}

.mp-map-me-anchor .mp-map-me {
	position: absolute;
	left: 0;
	top: 0;
	transform: translate(-50%, -50%);
}
