/*
Theme Name:  Immobilien Child
Theme URI:   https://immo.hetz.pc-heini.de
Description: Child-Theme für Immobilienmakler auf Basis von Twenty Twenty-Five. Enthält Objektlisten, Eckdaten-Tabellen, Status-Badges und ein Objektanfrage-Formular – ohne zusätzliche Plugins.
Author:      pc-heini
Version:     1.0.0
Template:    twentytwentyfive
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.1
Text Domain: immobilien-child
License:     GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
*/

/* -------------------------------------------------------------------------
   Status-Badges
   Der Status eines Objekts wird über Schlagwörter gepflegt (neu, reserviert,
   top-objekt). Die Beitrags-Schlagwörter werden deshalb als Badge dargestellt.
   ---------------------------------------------------------------------- */

.immo-badges {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin-bottom: var(--wp--preset--spacing--20);
}

.immo-badge {
	display: inline-block;
	padding: 0.25em 0.75em;
	border: 1px solid currentColor;
	border-radius: 2px;
	font-size: var(--wp--preset--font-size--x-small);
	font-weight: 500;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	line-height: 1.4;
	text-decoration: none;
}

.immo-badge--neu         { background: var(--wp--preset--color--contrast); color: var(--wp--preset--color--base); border-color: var(--wp--preset--color--contrast); }
.immo-badge--top-objekt  { background: var(--wp--preset--color--accent); color: var(--wp--preset--color--contrast); border-color: var(--wp--preset--color--accent); }
.immo-badge--reserviert  { background: transparent; color: var(--wp--preset--color--contrast); }

/* Vermarktete Objekte bleiben als Nachweis online, sollen aber nicht mit den
   aktuellen Angeboten konkurrieren – deshalb bewusst zurückgenommen. */
.immo-badge--verkauft,
.immo-badge--vermietet,
.immo-badge--referenz    { background: var(--wp--preset--color--muted); color: var(--wp--preset--color--base); border-color: var(--wp--preset--color--muted); }

/* -------------------------------------------------------------------------
   Eckdaten-Tabelle
   Kommt aus dem Block-Pattern "Immobilie" und ist ein normaler Core-Tabellen-
   block. Hier nur die Darstellung: zweispaltig, Beschriftung links.
   ---------------------------------------------------------------------- */

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

.immo-eckdaten td {
	padding: 0.6em 0;
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--hairline);
	vertical-align: top;
}

.immo-eckdaten tr:last-child td {
	border-bottom: 0;
}

.immo-eckdaten td:first-child {
	width: 42%;
	color: var(--wp--preset--color--muted);
	padding-right: 1.5rem;
}

.immo-eckdaten td:last-child {
	font-weight: 500;
}

@media (max-width: 599px) {
	.immo-eckdaten td            { display: block; border-bottom: 0; padding: 0; }
	.immo-eckdaten td:first-child { width: auto; font-size: var(--wp--preset--font-size--small); }
	.immo-eckdaten td:last-child  { padding-bottom: 0.9em; border-bottom: 1px solid var(--wp--preset--color--hairline); }
}

/* -------------------------------------------------------------------------
   Objektliste (Query Loop im Kachel-Raster)
   Bilder verkaufen: die Kachel darf ruhig Platz nehmen. Bei drei Spalten auf
   1600 px sind das rund 500 px je Bild – und dazu muss auch die Schrift
   wachsen, sonst wirkt der Text unter dem großen Bild verloren.
   ---------------------------------------------------------------------- */

.immo-liste .wp-block-post-title {
	font-size: clamp(1.15rem, 0.95rem + 0.55vw, 1.45rem);
	line-height: 1.3;
}

.immo-liste .wp-block-post-title a {
	text-decoration: none;
}

.immo-liste .wp-block-post-title a:hover {
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.immo-liste .wp-block-post-featured-image img {
	aspect-ratio: 4 / 3;
	object-fit: cover;
	width: 100%;
}

/* -------------------------------------------------------------------------
   Objektfilter über den Listen
   Ersetzt die früheren Kategorie-Links unter jeder Kachel: eine Leiste statt
   zwölf gleicher Links, und sie zeigt, wo man gerade steht.
   ---------------------------------------------------------------------- */

.immo-filter {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.35rem 1.75rem;
	margin-block: 0 var(--wp--preset--spacing--40);
	padding-bottom: var(--wp--preset--spacing--20);
	border-bottom: 1px solid var(--wp--preset--color--hairline);
}

.immo-filter__eintrag {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--x-small);
	letter-spacing: 0.14em;
	text-transform: uppercase;
	text-decoration: none;
	padding-bottom: 0.35em;
	border-bottom: 1px solid transparent;
	transition: color 180ms ease, border-color 180ms ease;
	white-space: nowrap;
}

.immo-filter__eintrag:hover {
	color: var(--wp--preset--color--contrast);
}

.immo-filter__eintrag--aktiv {
	color: var(--wp--preset--color--contrast);
	border-bottom-color: var(--wp--preset--color--contrast);
}

/* Die Objektzahl steht klein hinter der Beschriftung, nicht als eigene Spalte:
   sie ist Beiwerk, kein Filterkriterium. */
.immo-filter__zahl {
	margin-left: 0.4em;
	font-size: 0.8em;
	letter-spacing: 0.04em;
	opacity: 0.55;
}

@media (max-width: 600px) {
	.immo-filter {
		flex-wrap: nowrap;
		overflow-x: auto;
		gap: 1.25rem;
		scrollbar-width: none;
	}

	.immo-filter::-webkit-scrollbar {
		display: none;
	}
}

/* -------------------------------------------------------------------------
   Kurzfassung der Eckdaten unter dem Kachelbild
   Lage, Zimmer, Fläche, Preis – die vier Angaben, die man beim Vergleichen
   tatsächlich nebeneinanderlegt.
   ---------------------------------------------------------------------- */

.immo-kacheldaten {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0 0.5rem;
	margin-block: 0.6rem 0;
	color: var(--wp--preset--color--muted);
	font-size: 1rem;
}

.immo-kacheldaten__trenner {
	opacity: 0.4;
}

.immo-kacheldaten__wert--nummer {
	white-space: nowrap;
}

.immo-kacheldaten__wert--preis {
	color: var(--wp--preset--color--contrast);
}

/* -------------------------------------------------------------------------
   Objektanfrage-Formular
   Eigenes Formular im Theme statt eines Formular-Plugins.
   ---------------------------------------------------------------------- */

.immo-formular {
	display: grid;
	gap: var(--wp--preset--spacing--20) var(--wp--preset--spacing--30);
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.immo-formular__feld--breit,
.immo-formular__feld--voll {
	grid-column: 1 / -1;
}

/* Ab Tabletbreite stehen die vier kurzen Angaben links in einem 2×2-Block und
   das Nachrichtenfeld rechts daneben über die volle Höhe. Das nutzt die Breite
   der Seite, statt ein schmales Feld unter das nächste zu stapeln.
   Die Grenze liegt bewusst unter der Inhaltsbreite: das Formular steht meist
   in einer Box, die etwas schmaler ist als der Textbereich. */
@media (min-width: 740px) {
	.immo-formular {
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.15fr);
	}

	.immo-formular__feld--name     { grid-area: 1 / 1; }
	.immo-formular__feld--telefon  { grid-area: 1 / 2; }
	.immo-formular__feld--email    { grid-area: 2 / 1; }
	.immo-formular__feld--ort      { grid-area: 2 / 2; }

	.immo-formular__feld--nachricht {
		grid-area: 1 / 3 / 3 / 4;
		display: flex;
		flex-direction: column;
	}

	.immo-formular__feld--nachricht textarea {
		flex: 1;
	}
}

/* In der Anfragebox darf das Formular die ganze Kastenbreite nutzen. Ohne das
   endet es an der Textbreite und lässt rechts ein Drittel Sandfläche stehen. */
.immo-anfrage > * {
	max-width: none;
}

.immo-formular label {
	display: block;
	margin-bottom: 0.35em;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--muted);
}

.immo-formular input[type="text"],
.immo-formular input[type="email"],
.immo-formular input[type="tel"],
.immo-formular textarea {
	/* Ohne border-box zählt WordPress' Formular-CSS Polsterung und Rahmen zur
	   Breite hinzu – die Felder ragen dann rund 35 px in die Nachbarspalte und
	   der Spaltenabstand sieht aus, als fehle er. */
	box-sizing: border-box;
	width: 100%;
	padding: 0.85em 1em;
	border: 1px solid var(--wp--preset--color--hairline);
	border-radius: 2px;
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--medium);
	transition: border-color 180ms ease;
}

.immo-formular input:hover,
.immo-formular textarea:hover {
	border-color: var(--wp--preset--color--muted);
}

/* Auf dem Sandton der Anfragebox verschwindet die Haarlinie fast. Dort braucht
   der Rahmen etwas mehr Gewicht, damit die Felder als Felder lesbar bleiben. */
.immo-anfrage .immo-formular input[type="text"],
.immo-anfrage .immo-formular input[type="email"],
.immo-anfrage .immo-formular input[type="tel"],
.immo-anfrage .immo-formular textarea {
	border-color: #cbc7c1;
}

.immo-formular input:focus-visible,
.immo-formular textarea:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 1px;
}

.immo-formular textarea {
	min-height: 9em;
	resize: vertical;
}

.immo-formular__einwilligung {
	grid-column: 1 / -1;
	display: flex;
	gap: 0.75em;
	align-items: flex-start;
	font-size: var(--wp--preset--font-size--small);
}

.immo-formular__einwilligung input {
	margin-top: 0.25em;
	flex: 0 0 auto;
}

.immo-formular__einwilligung label {
	margin: 0;
	color: inherit;
}

/* Honeypot: für Menschen unsichtbar, für Bots ein Pflichtfeld zum Hineintappen.
   Bewusst nicht display:none – manche Bots ignorieren solche Felder. */
.immo-formular__hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.immo-formular button {
	grid-column: 1 / -1;
	justify-self: start;
	padding: 0.8em 2.2em;
	border: 0;
	border-radius: 2px;
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--medium);
	letter-spacing: 0.03em;
	cursor: pointer;
}

.immo-formular button:hover {
	background: var(--wp--preset--color--muted);
}

@media (max-width: 599px) {
	.immo-formular { grid-template-columns: 1fr; }
}

.immo-hinweis {
	padding: 1em 1.25em;
	border-left: 3px solid var(--wp--preset--color--contrast);
	background: var(--wp--preset--color--sand-light);
	margin-bottom: var(--wp--preset--spacing--30);
}

.immo-hinweis--fehler {
	border-left-color: #a3241c;
}

.immo-pflichtfeld {
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--small);
}

/* -------------------------------------------------------------------------
   Editorialer Grundton
   Weit gesperrte Versal-Labels als wiederkehrendes Ordnungselement, dazu
   Haarlinien statt Rahmen. Das trägt die Futura-Anmutung der alten Marke
   weiter, ohne sie nachzubauen.
   ---------------------------------------------------------------------- */

.immo-eyebrow {
	text-transform: uppercase;
	letter-spacing: 0.16em;
	font-weight: 500;
	line-height: 1.6;
	margin: 0;
}

.immo-eyebrow--gedimmt,
.immo-eyebrow--gedimmt a {
	color: var(--wp--preset--color--muted);
}

.immo-eyebrow a {
	text-decoration: none;
}

.immo-eyebrow a:hover {
	text-decoration: underline;
	text-underline-offset: 0.3em;
}

.immo-haarlinie {
	border: 0;
	border-top: 1px solid var(--wp--preset--color--hairline);
	opacity: 1;
	margin-block: 0;
}

/* -------------------------------------------------------------------------
   Kopf und Navigation
   Der Kopf läuft auf allen Seiten mit und ist flach gehalten: er nimmt vom
   Fenster dauerhaft Platz weg, jeder Millimeter zählt also doppelt.
   Was die Startseite darüber hinaus tut – durchsichtig im Bannerbild liegen
   und beim Scrollen umschlagen – steht weiter unten unter ".home".
   ---------------------------------------------------------------------- */

/* Das Klebenbleiben hängt am Wrapper des Template-Parts, nicht an .immo-kopf
   selbst: ein sticky-Element klebt nur innerhalb seines Elternelements, und
   das umschließt hier nichts als die Kopfzeile – es wäre sofort zu Ende. Der
   Wrapper dagegen ist ein direktes Kind des Seitenrumpfs und reicht über die
   ganze Seitenhöhe.
   Der Selektor greift den Wrapper über sein Kind, weil die Templates ihn ohne
   eigene Klasse einbinden und teils als div, teils als header ausgeben. */
.wp-block-template-part:has(> .immo-kopf) {
	position: sticky;
	top: 0;
	z-index: 40;
}

/* Die Adminleiste ist selbst fixiert und läge sonst über dem Kopf. Betrifft
   nur angemeldete Redakteure, aber genau die schauen sich die Seite an. */
.admin-bar .wp-block-template-part:has(> .immo-kopf) {
	top: var(--wp-admin--admin-bar--height, 32px);
}

/* Das Innenmaß kommt als Inline-Style aus dem Block-Markup; ohne !important
   ist dagegen nicht anzukommen. */
.immo-kopf__haupt {
	padding-top: 0.85rem !important;
	padding-bottom: 0.85rem !important;
}

/* Sprungmarken und der Skip-Link landen sonst hinter der Leiste. */
html {
	scroll-padding-top: 7rem;
}

/* Menü und Kontaktzeichen bilden zusammen die rechte Seite der Kopfzeile.
   Beide sollen auf einer Linie liegen, auch wenn das Menü höher baut. */
.immo-kopf__rechts {
	align-items: center;
	gap: var(--wp--preset--spacing--30);
}

/* Telefon und E-Mail als zwei Zeichen im Kopf. Der Abstand zum Menü ist etwas
   größer als der Abstand der beiden Zeichen zueinander: dadurch lesen sie sich
   als ein Paar und nicht als zwei angehängte Menüpunkte. */
.immo-kopf__kontakt {
	display: flex;
	align-items: center;
	gap: 0.85rem;
	margin: 0 0.6rem 0 0;
	line-height: 1;
}

.immo-kopf__kontakt a {
	display: flex;
	color: var(--wp--preset--color--muted);
	transition: color 180ms ease, transform 180ms ease;
}

.immo-kopf__kontakt a:hover {
	color: var(--wp--preset--color--contrast);
	transform: translateY(-1px);
}

/* Die Zeichen sitzen optisch auf der Schriftlinie des Menüs daneben. Etwas
   größer als die Versalhöhe der Menüschrift, weil eine Strichzeichnung bei
   gleicher Höhe leichter wirkt als Buchstaben. */
.immo-kopf__kontakt svg {
	display: block;
	width: 1.2rem;
	height: 1.2rem;
}

@media (prefers-reduced-motion: reduce) {
	.immo-kopf__kontakt a {
		transition: color 180ms ease;
	}

	.immo-kopf__kontakt a:hover {
		transform: none;
	}
}

/* Auf dem Telefon reicht die Breite nicht, damit Zeichen und Menüknopf
   nebeneinander stehen. Umbrechen dürfen sie nicht: der Knopf rutschte unter
   die Zeichen und der Kopf wüchse um 51 px, die er dauerhaft vom Fenster
   nimmt. Nebeneinander gezwungen und mit engerem Abstand passen sie in eine
   Zeile.
   Aus demselben Grund steht der Name kleiner und ohne den Zusatz darunter;
   „Wohnimmobilien in Stuttgart" ist auf der Startseite gleich noch einmal in
   der Augenbraue zu lesen. Der Schriftgrad braucht !important, weil er als
   Preset aus dem Block-Markup kommt. */
@media (max-width: 600px) {
	.immo-kopf__rechts {
		flex-wrap: nowrap;
		gap: 1rem;
	}

	.immo-kopf__kontakt {
		gap: 0.7rem;
		margin-right: 0.2rem;
	}

	.immo-kopf__haupt {
		flex-wrap: nowrap;
	}

	.immo-marke {
		min-width: 0;
	}

	.immo-kopf .wp-block-site-title {
		font-size: 1rem !important;
		line-height: 1.25;
	}

	.immo-wortmarke .immo-eyebrow {
		display: none;
	}
}

/* Zwischen 600 und 930 px klappt das Menü in den Menüknopf, obwohl WordPress
   dafür sonst 600 px ansetzt. Der Grund ist Arithmetik: Wortmarke und Menü
   brauchen zusammen 835 px, bei 800 px Fensterbreite stehen 705 zur Verfügung,
   und der Kopf bricht auf zwei Zeilen um.
   Umgesetzt durch Umkehren der beiden Regeln, mit denen der Kern ab 600 px das
   ausgeklappte Menü zeigt und den Knopf versteckt. */
@media (min-width: 600px) and (max-width: 929px) {
	.immo-nav .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	.immo-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
}

.immo-wortmarke .wp-block-site-title a {
	text-decoration: none;
	letter-spacing: 0.02em;
}

/* Bildmarke neben dem Schriftzug. Die Höhe steuert die Größe, nicht die
   Breite: das Logo ist deutlich breiter als hoch und würde sonst den Kopf
   auseinanderdrücken. */
.immo-marke {
	gap: var(--wp--preset--spacing--20);
}

.immo-marke__zeichen img {
	height: 2.9rem;
	width: auto;
	max-width: none;
}

/* Im Fußbereich darf die Bildmarke groß sein: dort kostet Höhe nichts. */
.immo-fuss .immo-marke__zeichen img {
	height: 7rem;
	opacity: 0.85;
}

@media (max-width: 600px) {
	.immo-marke__zeichen img {
		height: 2.5rem;
	}
}

.immo-nav a {
	text-decoration: none;
	padding-bottom: 0.2em;
	border-bottom: 1px solid transparent;
	transition: border-color 180ms ease;
}

.immo-nav a:hover,
.immo-nav .current-menu-item > a,
.immo-nav .current_page_item > a {
	border-bottom-color: var(--wp--preset--color--contrast);
}

/* -------------------------------------------------------------------------
   Kopf im Bannerbild – nur auf der Startseite

   Dort liegt der Kopf durchsichtig auf dem Panorama und schlägt beim Scrollen
   in die Sandleiste um, die auf allen anderen Seiten von Anfang an steht.
   Alles, was auch anderswo gilt – Klebenbleiben, Innenmaß, Logogröße,
   Menüknopf-Grenze –, steht oben im allgemeinen Teil.

   "position: fixed" statt des sticky-Wrappers: der Kopf muss hier ganz aus
   dem Fluss, damit der Auftakt am oberen Fensterrand beginnt und die volle
   Fensterhöhe füllt.

   Die Klasse "immo-kopf--fest" setzt assets/js/kopf.js. Beide Zustände
   unterscheiden sich nur in zwei Farbwerten; dafür stehen hier zwei eigene
   Eigenschaften, damit jede Farbe im Regelwerk genau einmal vorkommt.

   Der Selektor hängt an ".home", der Klasse, die WordPress dem Body der
   Startseite gibt. Deshalb steht das hier im Stylesheet und nicht als
   Style-Block im Seiteninhalt: dort käme das CSS erst nach dem Kopf beim
   Browser an, und der Kopf wäre für einen Moment als Sandleiste zu sehen,
   bevor er durchsichtig wird.
   ---------------------------------------------------------------------- */

.home .immo-kopf {
	--kopf-schrift: #fff;
	--kopf-schrift-leise: rgba(255, 255, 255, 0.75);

	position: fixed;
	inset: 0 0 auto 0;
	z-index: 40;
	color: var(--kopf-schrift);
	/* Über dem Banner muss der Kopf durchsichtig sein; die Preset-Klasse aus
	   dem Markup kommt mit !important, dagegen hilft nur dasselbe. */
	background-color: transparent !important;
	/* 250 ms und nicht mehr: zwischen der Schwelle bei rund 30 px und der
	   Stelle, an der die erste Textzeile den Kopf erreicht, liegen nur etwa
	   60 px. Ein längerer Übergang wäre bei zügigem Scrollen noch mitten im
	   Farbwechsel, während die Überschrift schon darunter durchläuft. */
	transition: background-color 250ms ease, color 250ms ease, box-shadow 250ms ease;
}

.admin-bar.home .immo-kopf {
	top: var(--wp-admin--admin-bar--height, 32px);
}

.home .immo-kopf--fest {
	--kopf-schrift: var(--wp--preset--color--contrast);
	--kopf-schrift-leise: var(--wp--preset--color--muted);

	/* Derselbe Sandton wie auf den übrigen Seiten: beim Verlassen der
	   Startseite wechselt der Kopf dadurch nicht die Farbe. Voll deckend und
	   nicht als Milchglas – ein Kopf, hinter dem man die durchlaufende
	   Überschrift ahnt, wirkt schmutzig, nicht leicht. */
	background-color: var(--wp--preset--color--sand-light) !important;
	box-shadow: 0 1px 0 var(--wp--preset--color--hairline);
}

/* Über dem Bild darf der Kopf etwas mehr Luft nehmen als sonst; er kostet dort
   keine Inhaltshöhe. Beim Umschlagen geht er auf das allgemeine Maß zurück. */
.home .immo-kopf__haupt {
	padding-top: 1.4rem !important;
	padding-bottom: 1.4rem !important;
	transition: padding 250ms ease;
}

.home .immo-kopf--fest .immo-kopf__haupt {
	padding-top: 0.85rem !important;
	padding-bottom: 0.85rem !important;
}

/* Das Logo besteht aus drei Grautönen: 66 % für Dach, Turm und Fensterläden,
   83 % für die Hauswand, 100 % für die Fenster. Auf dem Bild ist das zu matt,
   nur weiß färben würde es aber zur Silhouette machen – Fenster und Wand
   fielen mit einer weißen Fläche zusammen.
   Deshalb nur aufhellen: 1,15 verschiebt die drei Stufen auf 76 / 95 / 100,
   sie bleiben also unterscheidbar. Höhere Werte lassen zuerst Wand und
   Fenster zusammenlaufen; ab 1,25 ist die Zeichnung weg. Den Rest der
   Ablösung vom Bild leistet der Schattenwurf, der die Abstufungen im
   Inneren unangetastet lässt. */
.home .immo-kopf .immo-marke__zeichen img {
	height: 3.4rem;
	filter: brightness(1.15) drop-shadow(0 1px 4px rgba(0, 0, 0, 0.45));
	transition: height 250ms ease, filter 250ms ease;
}

.home .immo-kopf--fest .immo-marke__zeichen img {
	height: 2.9rem;
	filter: none;
}

@media (max-width: 600px) {
	.home .immo-kopf .immo-marke__zeichen img {
		height: 2.9rem;
	}

	.home .immo-kopf--fest .immo-marke__zeichen img {
		height: 2.5rem;
	}

	.home .immo-kopf__haupt {
		padding-top: 1rem !important;
		padding-bottom: 1rem !important;
	}
}

/* Alles im Kopf nimmt die Farbe des Kopfes an. Site-Titel, Augenbraue und
   die Kontaktzeichen bringen eigene Farben mit, die hier überschrieben
   werden. */
.home .immo-kopf .wp-block-site-title a,
.home .immo-kopf .immo-nav a,
.home .immo-kopf .wp-block-navigation__responsive-container-open {
	color: var(--kopf-schrift);
}

.home .immo-kopf .immo-eyebrow,
.home .immo-kopf .immo-eyebrow--gedimmt,
.home .immo-kopf .immo-kopf__kontakt a {
	color: var(--kopf-schrift-leise);
	transition: color 250ms ease, transform 180ms ease;
}

.home .immo-kopf .immo-kopf__kontakt a:hover {
	color: var(--kopf-schrift);
}

.home .immo-kopf .immo-nav a:hover,
.home .immo-kopf .immo-nav .current-menu-item > a,
.home .immo-kopf .immo-nav .current_page_item > a {
	border-bottom-color: var(--kopf-schrift);
}

/* Auf dem Bild sitzt keine Trennlinie – dort trennt das Bild selbst. Im
   festen Zustand übernimmt der Schlagschatten diese Aufgabe, die Linie
   bleibt deshalb durchgehend unsichtbar und hält nur ihren Platz. */
.home .immo-kopf .immo-haarlinie {
	border-top-color: transparent;
}

/* Aufgeklappte Menüs liegen auf weißem Grund, nicht auf dem Bild: die
   Untermenüs zu „Immobilien" und „Leistungen" am Rechner ebenso wie das
   Overlay auf dem Telefon. Beide würden die weiße Schrift des durchsichtigen
   Kopfes erben und wären dann nicht zu lesen.
   Umgesetzt über die beiden Eigenschaften und nicht über eigene color-Regeln:
   so ziehen Beschriftung, Trennlinien und der Unterstrich beim Überfahren
   von allein mit, ohne dass jede davon einzeln nachgeführt werden muss. */
.home .immo-kopf .wp-block-navigation__submenu-container,
.home .immo-nav .wp-block-navigation__responsive-container.is-menu-open {
	--kopf-schrift: var(--wp--preset--color--contrast);
	--kopf-schrift-leise: var(--wp--preset--color--muted);
}

.home .immo-nav .wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--wp--preset--color--base);
}

@media (prefers-reduced-motion: reduce) {
	.home .immo-kopf,
	.home .immo-kopf__haupt,
	.home .immo-kopf .immo-marke__zeichen img,
	.home .immo-kopf .immo-eyebrow,
	.home .immo-kopf .immo-kopf__kontakt a {
		transition: none;
	}
}

/* -------------------------------------------------------------------------
   Auftakt der Startseite
   Der Titel bekommt bewusst eine engere Zeilenhöhe und eine begrenzte Breite –
   dadurch entsteht die typografische Kante, die den Seitenanfang trägt.
   ---------------------------------------------------------------------- */

/* Zur Zeilenlänge von Überschriften:
   Im constrained-Layout zentriert WordPress jedes Kind mit
   "margin-inline: auto !important" innerhalb der Inhaltsbreite. Eine eigene
   max-width macht den Block schmaler – und weil er zentriert bleibt, rückt er
   von der Textkante weg. Überschrift und Absatz beginnen dann an verschiedenen
   Stellen, was auffällt, sobald man darauf achtet.
   Deshalb wird die Zeilenlänge hier über die Inhaltsbreite geregelt und nicht
   über max-width; nur text-wrap sorgt für einen ruhigen Umbruch. */
/* -------------------------------------------------------------------------
   Auftakt der Startseite
   Ein fester Blick vom Hang über den Stuttgarter Talkessel. Der Text steht
   oben im Himmel, nicht unten über den Dächern: das Blau trägt weiße Schrift
   von sich aus,
   während unten ein kräftiger Schleier nötig wäre – ausgerechnet über dem
   Teil des Bildes, der etwas erzählt.
   Das Bild liegt als Theme-Datei unter assets/img/ und nicht in der
   Mediathek. Es ist damit Teil der Gestaltung und übersteht jeden Wechsel
   der Seiteninhalte; zum Austauschen genügt es, die vier Dateien dort zu
   ersetzen (breit in zwei Größen und hoch, je als WebP und JPEG).
   ---------------------------------------------------------------------- */

/* Bewusst kein Flex-Layout: das constrained-Layout von WordPress gibt jedem
   Kind "margin-inline: auto !important" mit. In einem Flex-Container wird
   daraus eine waagerechte Zentrierung – Augenbraue und Knöpfe rücken dann
   zur Mitte, während die Überschrift links steht. Im normalen Blockfluss
   bleibt alles bündig, und der Bildnachweis wird absolut gesetzt. */
/* Der Kopf schwebt über dem Auftakt, statt ihn nach unten zu schieben. Zwei
   Maße hängen daran:
   - Das Innenmaß oben muss den Kopf mittragen. Er baut rund 7 rem hoch, der
     Rest ist der Abstand zur Augenbraue.
   - Die Höhengrenze steht bei 1000 px statt bei 880. Vorher stand der Kopf
     über dem Bild und kam zu dessen Höhe hinzu; jetzt liegt er darin. Ohne
     den Aufschlag wäre der Seitenanfang um die Kopfhöhe geschrumpft. */
.immo-auftakt {
	position: relative;
	min-height: min(100svh, 1000px);
	padding-top: clamp(9.5rem, 6.5rem + 6vh, 12rem);
	padding-bottom: clamp(3rem, 7vh, 5rem);
	overflow: hidden;
	color: #fff;
}

/* Der Text setzt an derselben Kante an wie die Wortmarke im Kopf. Der Kopf
   begrenzt seinen Inhalt auf die Wide-Breite und zentriert ihn; auf breiten
   Bildschirmen hielte der Auftakt sonst nur den Seitenrand ein und begänne
   weit links davon.
   Der Rand ist das größere von beidem: dem üblichen Seitenrand und dem, was
   übrig bleibt, wenn die Wide-Breite mittig steht. Beide Werte kommen aus
   theme.json, die Kopplung hält also auch, wenn dort etwas geändert wird.

   Warum der Seitenrand in der zweiten Zeile noch einmal auftaucht: Der Auftakt
   ist alignfull und bricht mit negativen Rändern aus dem Textbereich aus, ist
   also um zweimal den Seitenrand breiter als dieser. Prozentwerte im padding
   beziehen sich aber auf den Textbereich. Ohne den Zuschlag liegt die Kante
   um genau ein Randmaß zu weit links. */
.immo-auftakt.has-global-padding {
	--immo-rand: var(--wp--style--root--padding-left, clamp(1.25rem, 5vw, 5rem));

	padding-inline: max(
		var(--immo-rand),
		calc(var(--immo-rand) + (100% - var(--wp--style--global--wide-size, 1600px)) / 2)
	);
}

.immo-auftakt::before,
.immo-auftakt::after {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.immo-auftakt::before {
	background-position: center center;
	background-size: cover;
	/* WebP spart rund ein Drittel; ältere Browser nehmen das JPEG. */
	background-image:
		image-set(
			url("assets/img/auftakt-stuttgart-kessel.webp") type("image/webp"),
			url("assets/img/auftakt-stuttgart-kessel.jpg") type("image/jpeg")
		);
}

/* Bildschirme mit mehr als 2560 physischen Pixeln in der Breite – 4K-Monitore
   und Retina-Notebooks – würden die 2560er Datei wieder hochrechnen, und das
   sieht man als Weichheit. Sie bekommen das Bild in Originalbreite (3950 px);
   alle anderen laden weiterhin die kleinere Datei. */
@media (min-resolution: 1.5x), (min-width: 2000px) {
	.immo-auftakt::before {
		background-image:
			image-set(
				url("assets/img/auftakt-stuttgart-kessel-gross.webp") type("image/webp"),
				url("assets/img/auftakt-stuttgart-kessel-gross.jpg") type("image/jpeg")
			);
	}
}

/* So viel Schleier, dass Kopfleiste und Knopf sitzen, und keinen Hauch mehr.
   Der Horizont liegt bei rund 46 % der Höhe, Titel und Knöpfe stehen also
   ganz im Himmel, und der trägt weiße Schrift fast von allein. Der erste
   Verlauf hält deshalb nur bis zur Knopfzeile bei 46 % und läuft bis 66 %
   aus. Tiefer darf er nicht reichen: eine gleichmäßig dunklere Kurve würde
   die Stadt grau machen und dem Bild nehmen, wofür es ausgesucht wurde. */
.immo-auftakt::after {
	background:
		linear-gradient(to bottom, rgba(8, 18, 32, 0.50) 0%, rgba(8, 18, 32, 0.42) 30%, rgba(8, 18, 32, 0.28) 46%, rgba(8, 18, 32, 0.08) 56%, rgba(8, 18, 32, 0) 66%),
		linear-gradient(to right, rgba(8, 18, 32, 0.38) 0%, rgba(8, 18, 32, 0.10) 45%, rgba(8, 18, 32, 0) 70%),
		linear-gradient(to top, rgba(8, 18, 32, 0.42) 0%, rgba(8, 18, 32, 0) 22%);
}

/* Die Blöcke selbst müssen über beide Ebenen – und linksbündig stehen.
   Das constrained-Layout gibt jedem Kind "margin-inline: auto !important"
   mit; bei einem Block, der schmaler ist als die Inhaltsbreite, rückt er
   damit in die Mitte. Sichtbar wurde das an der Augenbraue, die als
   einzige kurz genug war, um wegzurutschen. */
.immo-auftakt > *:not(.immo-auftakt__nachweis) {
	position: relative;
	z-index: 2;
	margin-inline: 0 auto !important;
}

/* Der Auftakt ist knapper gesetzt als die übrigen Seiten: kleinerer Titel,
   kürzere Zeilen, engere Abstände. Der Horizont liegt bei rund 46 % der
   Bildhöhe, der Text endet knapp darüber und steht ganz im Himmel.
   Die Größen stehen im CSS und nicht als Preset im Block, weil WordPress
   Preset-Schriftgrößen mit !important ausgibt und sie sich sonst nicht
   überschreiben ließen. */
.immo-auftakt__titel {
	font-size: clamp(1.8rem, 1.1rem + 1.5vw, 2.6rem);
	line-height: 1.1;
	max-width: 26ch;
	text-wrap: balance;
	text-shadow: 0 1px 40px rgba(0, 0, 0, 0.25);
}

.immo-auftakt .immo-eyebrow,
.immo-auftakt .immo-eyebrow--gedimmt {
	color: rgba(255, 255, 255, 0.85);
}

.immo-auftakt .wp-block-buttons {
	gap: var(--wp--preset--spacing--20);
}

/* Der Auftakt trägt nur Einordnung, Titel und zwei Wege weiter; alles endet
   damit bei rund 47 % der Bildhöhe, knapp über dem Horizont. Ein Fließsatz
   zwischen Titel und Knöpfen reichte bis in die Dächer, wo der Schleier nicht
   mehr trägt; er steht deshalb im Leistungsabschnitt weiter unten. */

.immo-auftakt .wp-block-button__link {
	background-color: #fff;
	color: var(--wp--preset--color--contrast);
	border-color: #fff;
}

.immo-auftakt .is-style-outline .wp-block-button__link {
	background-color: rgba(8, 18, 32, 0.28);
	backdrop-filter: blur(3px);
	color: #fff;
	border-color: rgba(255, 255, 255, 0.6);
}

/* Namensnennung fürs Bannerbild: klein und unaufdringlich, aber am Bild
   und nicht in einer Fußnote. */
.immo-auftakt__nachweis {
	position: absolute;
	right: var(--wp--preset--spacing--30);
	bottom: var(--wp--preset--spacing--20);
	left: auto;
	z-index: 2;
	margin: 0;
	max-width: none;
	text-align: right;
	letter-spacing: 0.04em;
}

.immo-auftakt__nachweis a {
	color: rgba(255, 255, 255, 0.6);
	text-decoration: none;
}

.immo-auftakt__nachweis a:hover {
	color: rgba(255, 255, 255, 0.9);
}

/* Auf dem Telefon steht das Fenster hochkant. Das 2:1-Bild würde dort links
   und rechts so stark beschnitten, dass nur ein Streifen Stadt bliebe. Darum
   ein hochformatiger Zuschnitt aus der engeren Aufnahme desselben Motivs. */
@media (max-width: 781px) {
	.immo-auftakt::before {
		background-image:
			image-set(
				url("assets/img/auftakt-stuttgart-kessel-hoch.webp") type("image/webp"),
				url("assets/img/auftakt-stuttgart-kessel-hoch.jpg") type("image/jpeg")
			);
	}

	.immo-auftakt {
		min-height: 88svh;
		/* Hochkant ist der Kopf flacher (2,9 rem Logo), der Text darf also
		   höher ansetzen – die Bildhöhe ist hier das knappe Gut. */
		padding-top: clamp(7rem, 5rem + 4vh, 8.5rem);
	}

	/* Hochkant ist der Text im Verhältnis zur Bildhöhe viel länger – die
	   beiden Knöpfe stehen untereinander statt nebeneinander. Der Block
	   reicht damit bis weit unter den Horizont, und der knappe Schleier
	   der Desktopansicht trägt dort nicht mehr. Auf dem kleinen Bild
	   kostet ein durchgehender Verlauf wenig und die Schrift bleibt
	   sicher lesbar. */
	.immo-auftakt::after {
		background:
			linear-gradient(to bottom, rgba(8, 18, 32, 0.62) 0%, rgba(8, 18, 32, 0.48) 30%, rgba(8, 18, 32, 0.34) 58%, rgba(8, 18, 32, 0.16) 82%, rgba(8, 18, 32, 0.05) 100%);
	}

	.immo-auftakt__titel {
		font-size: 1.65rem;
	}

	.immo-auftakt__nachweis {
		right: auto;
		left: var(--wp--preset--spacing--30);
		text-align: left;
	}
}

.immo-zitat p {
	max-width: 24ch;
	margin-inline: auto;
	font-weight: 300;
	text-wrap: balance;
}

.immo-seitenkopf h1 {
	text-wrap: balance;
}

/* -------------------------------------------------------------------------
   Objektkacheln
   Das Bild zoomt beim Überfahren minimal – gerade genug, dass die Kachel
   anfassbar wirkt, ohne unruhig zu werden.
   ---------------------------------------------------------------------- */

.immo-kachel .wp-block-post-featured-image {
	overflow: hidden;
	background: var(--wp--preset--color--sand-light);
}

.immo-kachel .wp-block-post-featured-image img {
	transition: transform 600ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

.immo-kachel:hover .wp-block-post-featured-image img {
	transform: scale(1.035);
}

.immo-kachel .wp-block-post-excerpt__more-text {
	display: none;
}

.immo-kachel .wp-block-post-excerpt {
	font-size: 0.98rem;
	line-height: 1.6;
}

/* Der Vermarktungsstand gehört aufs Bild, nicht in eine eigene Zeile darunter:
   dort schiebt er den Titel bei jeder zweiten Kachel um eine Zeile nach unten
   und zerlegt die Ruhe des Rasters. */
.immo-kachel {
	position: relative;
}

.immo-kachel > .immo-badges {
	position: absolute;
	top: var(--wp--preset--spacing--20);
	left: var(--wp--preset--spacing--20);
	z-index: 3;
	margin: 0;
	pointer-events: none;
}

.immo-kachel > .immo-badges .immo-badge {
	pointer-events: auto;
	backdrop-filter: blur(4px);
}

.immo-kachel > .immo-badges .immo-badge--neu {
	background: rgba(33, 33, 33, 0.85);
}

.immo-kachel > .immo-badges .immo-badge--verkauft,
.immo-kachel > .immo-badges .immo-badge--vermietet {
	background: rgba(110, 106, 101, 0.85);
}

/* -------------------------------------------------------------------------
   Bildspur in der Objektkachel
   Der Query Loop kennt nur ein Beitragsbild pro Kachel. Diese Spur zeigt
   stattdessen mehrere Objektbilder und lässt den Browser das Blättern
   übernehmen: scroll-snap statt Slider-Bibliothek.
   ---------------------------------------------------------------------- */

.immo-kachelgalerie {
	position: relative;
	margin-bottom: var(--wp--preset--spacing--20);
	background: var(--wp--preset--color--sand-light);
}

.immo-kachelgalerie__spur {
	display: flex;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}

.immo-kachelgalerie__spur::-webkit-scrollbar {
	display: none;
}

/* Das Seitenverhältnis sitzt am Rahmen, nicht am Bild: WordPress schreibt in
   jedes img ein height-Attribut, und solange das gilt, bleibt aspect-ratio am
   Bild wirkungslos – die Kacheln wären so hoch wie ihr jeweiliges Original. */
.immo-kachelgalerie__rahmen {
	flex: 0 0 100%;
	scroll-snap-align: start;
	scroll-snap-stop: always;
	display: block;
	aspect-ratio: 4 / 3;
	line-height: 0;
}

.immo-kachelgalerie__bild {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Pfeile bleiben unsichtbar, bis die Kachel angefasst wird – auf Zeigegeräten
   stören sie sonst die Bildwirkung. Auf Touchgeräten wischt man ohnehin. */
.immo-kachelgalerie__pfeil {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	z-index: 2;
	width: 2.25rem;
	height: 2.25rem;
	display: grid;
	place-items: center;
	padding: 0 0 0.15em;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.9);
	color: var(--wp--preset--color--contrast);
	font-size: 1.5rem;
	line-height: 1;
	cursor: pointer;
	opacity: 0;
	transition: opacity 180ms ease, background-color 180ms ease;
}

.immo-kachelgalerie__pfeil--zurueck { left: 0.6rem; }
.immo-kachelgalerie__pfeil--vor     { right: 0.6rem; }

.immo-kachel:hover .immo-kachelgalerie__pfeil,
.immo-kachelgalerie__pfeil:focus-visible {
	opacity: 1;
}

.immo-kachelgalerie__pfeil:hover {
	background: #fff;
}

.immo-kachelgalerie__pfeil[disabled] {
	opacity: 0 !important;
	pointer-events: none;
}

.immo-kachelgalerie__punkte {
	position: absolute;
	bottom: 0.7rem;
	left: 50%;
	transform: translateX(-50%);
	z-index: 2;
	display: flex;
	gap: 0.35rem;
	padding: 0.3rem 0.55rem;
	border-radius: 999px;
	background: rgba(33, 33, 33, 0.35);
	backdrop-filter: blur(3px);
}

.immo-kachelgalerie__punkt {
	width: 0.3rem;
	height: 0.3rem;
	border-radius: 50%;
	background: rgba(255, 255, 255, 0.55);
	transition: background-color 180ms ease;
}

.immo-kachelgalerie__punkt.ist-aktiv {
	background: #fff;
}

/* Bei sehr vielen Bildern würde die Punktreihe die Kachel überziehen. */
.immo-kachelgalerie__punkt:nth-child(n + 9) {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.immo-kachelgalerie__spur {
		scroll-behavior: auto;
	}
}

/* -------------------------------------------------------------------------
   Objekt-Detailseite
   ---------------------------------------------------------------------- */

/* Das Objektbild dockt direkt an die Kopfzeile an. Ohne diese Regel schiebt
   der Block-Abstand des Seitenrumpfs (jedes Direktkind bekommt von WordPress
   margin-block-start) einen weißen Streifen dazwischen. */
.immo-objekt {
	margin-block-start: 0;
}

.immo-objekt__bild img {
	width: 100%;
	max-height: 68vh;
	object-fit: cover;
}

.immo-objekt__kopf h1 {
	text-wrap: balance;
}

/* -------------------------------------------------------------------------
   Objektgalerie
   Die Objekte haben zwischen einem und knapp vierzig Bildern. Ein starres
   Raster wirkt bei wenigen Bildern leer und bei vielen erschlagend, deshalb
   füllt das Raster sich selbst auf und alle Bilder bekommen dasselbe
   Seitenverhältnis – so entsteht eine ruhige Fläche statt einer Treppe.
   ---------------------------------------------------------------------- */

.immo-objekt .wp-block-gallery {
	--wp--style--gallery-gap-default: var(--wp--preset--spacing--10);
}

.immo-galerie.wp-block-gallery.has-nested-images {
	display: grid;
	/* Das min() muss sein: ein festes Minimum von 22rem ist breiter als ein
	   Telefonbildschirm, und die Spalte läuft dann über den rechten Rand
	   hinaus – die ganze Seite lässt sich seitlich schieben. */
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr));
	gap: var(--wp--preset--spacing--10);
}

/* Das :not(#individual-image) ist kein Tippfehler, sondern muss sein: der
   Core-Galerieblock erhöht mit demselben Kniff die Spezifität seiner
   Breitenregel (width: calc(50% - gap)). Ohne Gegengewicht sitzen die Bilder
   auf einem Drittel ihrer Rasterzelle und der Rest bleibt weiß. */
.immo-galerie.wp-block-gallery.has-nested-images figure.immo-galerie__bild:not(#individual-image) {
	width: 100%;
	max-width: none;
	margin: 0;
	overflow: hidden;
	background: var(--wp--preset--color--sand-light);
}

.immo-galerie.wp-block-gallery.has-nested-images figure.immo-galerie__bild img {
	width: 100%;
	height: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	transition: transform 600ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

.immo-galerie.wp-block-gallery.has-nested-images figure.immo-galerie__bild:hover img {
	transform: scale(1.04);
}

/* Das erste Bild führt die Galerie an und darf doppelt so breit stehen –
   nur, wenn überhaupt genug Bilder für zwei Reihen da sind. */
@media (min-width: 782px) {
	.immo-galerie.wp-block-gallery.has-nested-images figure.immo-galerie__bild:first-child:nth-last-child(n + 5):not(#individual-image) {
		grid-column: span 2;
		grid-row: span 2;
	}

	.immo-galerie.wp-block-gallery.has-nested-images figure.immo-galerie__bild:first-child:nth-last-child(n + 5) img {
		aspect-ratio: auto;
	}
}

/* -------------------------------------------------------------------------
   Fußbereich
   ---------------------------------------------------------------------- */

.immo-fuss__liste,
.immo-fuss ul {
	list-style: none;
	padding: 0;
	margin: var(--wp--preset--spacing--20) 0 0;
	font-size: var(--wp--preset--font-size--small);
	line-height: 2;
}

.immo-fuss__liste a,
.immo-fuss ul a {
	text-decoration: none;
}

.immo-fuss__liste a:hover,
.immo-fuss ul a:hover {
	text-decoration: underline;
	text-underline-offset: 0.25em;
}

/* -------------------------------------------------------------------------
   Einblendung beim Laden
   Ein einziger, gestaffelter Auftritt der obersten Abschnitte. Bewusst nur
   beim Seitenaufbau und nicht beim Scrollen – sonst wirkt die Seite nervös.
   ---------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
	.immo-auftakt > *,
	.immo-seitenkopf > *,
	.immo-objekt__kopf > * {
		animation: immo-auftritt 700ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
	}

	.immo-auftakt > *:nth-child(1),
	.immo-seitenkopf > *:nth-child(1),
	.immo-objekt__kopf > *:nth-child(1) { animation-delay: 60ms; }

	.immo-auftakt > *:nth-child(2),
	.immo-seitenkopf > *:nth-child(2),
	.immo-objekt__kopf > *:nth-child(2) { animation-delay: 150ms; }

	.immo-auftakt > *:nth-child(3),
	.immo-seitenkopf > *:nth-child(3),
	.immo-objekt__kopf > *:nth-child(3) { animation-delay: 240ms; }

	.immo-auftakt > *:nth-child(4),
	.immo-objekt__kopf > *:nth-child(4) { animation-delay: 330ms; }
}

@keyframes immo-auftritt {
	from { opacity: 0; transform: translateY(0.6rem); }
	to   { opacity: 1; transform: none; }
}
