/* =============================================================================
   hero_slider.css — Fullbleed Hero Slider (Splide 4)
   Mobile first, min-width Breakpoints.

   Markup: templates/engine/hero_slider.php + templates/engine/tiles/hero_slide.php

   Zustands-Klassen:
     .is-initialized  -> setzt Splide selbst beim mount()
     .is-booted       -> setzt hero_slider.js zwei Frames nach dem mount
     .is-paused       -> Autoplay pausiert
     .is-static       -> kein Autoplay (Einzelwerk oder prefers-reduced-motion)

   Ohne JS bleibt die erste Slide inklusive Text sichtbar, die Bedienleiste
   wird ausgeblendet.
   ========================================================================== */

.hero-slider {
	--hero-height: calc(100vh - var(--navHeight));
	--hero-height-min: 26rem;

	--hero-fade: 900ms;
	--hero-zoom-scale: 1.07;
	--hero-zoom-duration: 9s;

	--hero-stagger-step: 90ms;
	--hero-stagger-delay: 240ms;
	--hero-line-duration: 900ms;
	--hero-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

	--hero-ink: #fff;
	--hero-ink-dim: rgba(255, 255, 255, 0.72);
	--hero-line-color: rgba(255, 255, 255, 0.38);

	--hero-pad-inline: 1.25rem;
	--hero-pad-block: 1.5rem;

	/* Luft unter dem Textblock. Hochdrehen, wenn dort etwas fest
	   positioniert sitzt (Cookie-Hinweis, Chat-Button, Zurueck-nach-oben). */
	--hero-content-offset: 4.5rem;

	/* Bildausschnitt bei fullbleed. 'center' schneidet mittig, 'center top'
	   bzw. 'center bottom' verschieben den sichtbaren Streifen. */
	--hero-cover-position: center;

	/* Breite des Bildstreifens bei Hochformat (portrait_fit => 'band').
	   Wer das hier deutlich aendert, sollte portrait_sizes in der Conf
	   mitziehen, sonst holt der Browser die falsche Bildgroesse. */
	--hero-portrait-width: 34rem;

	/* Hintergrund des Heros. Muss mit dem Slide-Hintergrund uebereinstimmen,
	   siehe Kommentar bei der Ueberblendung. */
	--hero-bg: #101012;

	/* Fortschrittsleiste: ein Segment je Werk */
	--hero-progress-height: 2px;
	--hero-progress-gap: 3px;
	--hero-progress-track: rgba(255, 255, 255, 0.18);

	position: relative;
	overflow: hidden;
	background-color: var(--hero-bg);
	color: var(--hero-ink);
}

@supports (height: 1svh) {
	.hero-slider {
		--hero-height: calc(100svh - var(--navHeight));
	}
}

.hero-slider .splide__track {
	position: relative;
	overflow: hidden;
	height: max(var(--hero-height), var(--hero-height-min));
}

.hero-slider .splide__list {
	display: flex;
	height: 100%;
	margin: 0;
	padding: 0;
}

.hero-slider__slide {
	position: relative;
	flex-shrink: 0;
	height: 100%;
	list-style: none;
}

/* Ohne JS: erste Slide auf volle Breite, Rest und Bedienung weg.
   splide-core versteckt .splide komplett bis mount() gelaufen ist —
   das heben wir auf, damit der Hero auch ohne JS etwas zeigt. */
.hero-slider.splide {
	visibility: visible;
}

.hero-slider:not(.is-initialized) .hero-slider__slide {
	width: 100%;
}

.hero-slider:not(.is-initialized) .hero-slider__slide + .hero-slider__slide {
	display: none;
}

.hero-slider:not(.is-initialized) .hero-slider__ui,
.hero-slider:not(.is-initialized) .hero-slider__progress {
	display: none;
}

/* --- Crossfade ------------------------------------------------------------ */
/* Gleiche Regeln wie in splide-core.min.css, hier noch einmal explizit, damit
   die Datei auch ohne Splide-Stylesheet vollstaendig ist.
   WICHTIG: die Slides bleiben Flex-Kinder. Splide legt sie per inline
   translateX(-n*100%) uebereinander — auf position:absolute umstellen schiebt
   alles ab Slide 2 aus dem Bild. Die transition-Dauer setzt Splide inline
   aus options.speed. */

.hero-slider .splide__track--fade > .splide__list > .hero-slider__slide {
	margin: 0;
	opacity: 0;
	z-index: 0;
}

.hero-slider .splide__track--fade > .splide__list > .hero-slider__slide.is-active {
	opacity: 1;
	z-index: 1;
}

/* Nur die einlaufende Slide blendet auf, die abgehende bleibt deckend liegen
   und wird erst nach der Blende abgeschaltet.
   Warum: bei einer klassischen Kreuzblende laufen beide gleichzeitig durch
   halbe Deckkraft. Alpha-Compositing addiert sich dabei nicht auf 1, in der
   Mitte bleiben nur rund 75% Bildanteil und der dunkle Hintergrund scheint
   durch — das Bild sackt bei jedem Wechsel sichtbar ab. Mit dem deckenden
   Slide-Hintergrund unten deckt die neue Slide die alte am Ende vollstaendig
   zu, das Abschalten faellt deshalb nicht auf. Nebeneffekt: es animiert nur
   noch eine Ebene statt zwei, was die Framezeiten etwa halbiert.
   !important, weil Splide die transition per inline style setzt. */

.hero-slider .hero-slider__slide {
	background-color: var(--hero-bg);
}

.hero-slider .splide__track--fade > .splide__list > .hero-slider__slide {
	transition: opacity 0s linear var(--hero-fade) !important;
}

.hero-slider .splide__track--fade > .splide__list > .hero-slider__slide.is-active {
	transition: opacity var(--hero-fade) linear !important;
	will-change: opacity;
}

/* --- Slide-Inhalt --------------------------------------------------------- */

.hero-slider__inner {
	position: relative;
	height: 100%;
}

.hero-slider__media {
	position: absolute;
	inset: 0;
	margin: 0;
	overflow: hidden;
}

.hero-slider__image {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: var(--hero-cover-position);
	transform: scale(1);
}

/* --- Hochformat ------------------------------------------------------------
   Drei Modi ueber portrait_fit in der Conf. Querformat ist davon nie
   betroffen und laeuft immer ueber die volle Breite.

   'band' (Default) — Bildstreifen fester Breite, volle Hoehe, oben und unten
       angeschnitten. Das Werk wird dadurch nie ueber seine eigene Aufloesung
       hochskaliert, was bei 100% Breite unvermeidlich waere und die Kanten
       matschig macht. Links und rechts bleibt der Hero-Hintergrund frei.
   'full'           — wie Querformat, volle Breite. Nur sinnvoll, wenn die
       Dateien gross genug sind.
   'contain'        — Werk komplett sichtbar, dahinter unscharf dieselbe
       Datei. drop-shadow statt box-shadow, damit der Schatten den echten
       Bildkanten folgt und nicht dem Elementkasten. */

.hero-slider__inner--fit-band .hero-slider__media {
	width: min(100%, var(--hero-portrait-width));
	/* inset:0 plus feste Breite plus auto-Margins zentriert den Streifen.
	   Rechtsbuendig: margin-left:auto; margin-right:0; */
	margin-inline: auto;
	box-shadow: 0 1.5rem 4rem rgba(6, 7, 9, 0.5);
}

.hero-slider__inner--fit-contain .hero-slider__image {
	object-fit: contain;
	object-position: center;
	filter: drop-shadow(0 1.5rem 3.5rem rgba(6, 7, 9, 0.55));
}

.hero-slider__backdrop {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transform: scale(1.2);
	filter: blur(48px) saturate(1.15);
}

/* Ken Burns auf EINER gemeinsamen Zeitachse fuer alle Bilder.
   Warum nicht pro aktiver Slide: dann steht das abgehende Bild waehrend der
   Blende auf einer anderen Skala als das einlaufende — gemessen 1.04 gegen
   1.00. Jedes Bild fuer sich steht still, aber die Ueberblendung mischt ein
   groesseres in ein kleineres, und das Auge liest das als Zurueckskalieren.
   Sichtbar wird es erst, wenn der Zoom ein paar Sekunden gelaufen ist.
   Alle Bilder starten die Animation im selben Moment (mit .is-booted) und
   laufen damit synchron: die Skalendifferenz ist zu jedem Zeitpunkt exakt
   null, egal wann gewechselt wird. 'alternate' laesst den Zoom endlos hin
   und her atmen, dadurch gibt es kein Ende und keinen Ruecksprung. */
.hero-slider.is-booted .hero-slider__image {
	animation: heroSliderKenBurns var(--hero-zoom-duration) ease-in-out infinite alternate;
}

@keyframes heroSliderKenBurns {
	from {
		transform: scale(1);
	}
	to {
		transform: scale(var(--hero-zoom-scale));
	}
}

.hero-slider__scrim {
	position: absolute;
	inset: 0;
	background-image: linear-gradient(
		to top,
		rgba(8, 9, 11, 0.82) 0%,
		rgba(8, 9, 11, 0.52) 26%,
		rgba(8, 9, 11, 0.06) 58%,
		rgba(8, 9, 11, 0.28) 100%
	);
}

/* --- Textblock ------------------------------------------------------------ */

.hero-slider__content {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 2;
	box-sizing: border-box;
	max-width: 34rem;
	padding: var(--hero-pad-block) var(--hero-pad-inline);

	/* Senkrecht zentriert ueber Flexbox statt top:50% + translateY(-50%).
	   Ein transform auf dem Elternelement zwingt den Browser, den ganzen
	   Textblock waehrend der Zeilen-Animationen neu zu rastern, und bei
	   ungerader Hoehe landet der Text auf halben Pixeln. Beides kostet
	   genau dort Bildrate, wo es auffaellt. */
	top: 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.hero-slider__content > :nth-child(1) { --line-index: 0; }
.hero-slider__content > :nth-child(2) { --line-index: 1; }
.hero-slider__content > :nth-child(3) { --line-index: 2; }
.hero-slider__content > :nth-child(4) { --line-index: 3; }
.hero-slider__content > :nth-child(5) { --line-index: 4; }
.hero-slider__content > :nth-child(6) { --line-index: 5; }

.hero-slider__line,
.hero-slider__action {
	margin: 0;
}

/* Maske fuer die Textzeilen. Padding/Margin gleichen Unterlaengen aus. */
.hero-slider__line {
	display: block;
	overflow: hidden;
	padding-block: 0.12em;
	margin-block: -0.12em;
}

.hero-slider__reveal {
	display: block;
	--hero-reveal-shift: 118%;
}

/* Der CTA bekommt keine Maske, sonst wird der Fokus-Ring abgeschnitten. */
.hero-slider__action .hero-slider__reveal {
	--hero-reveal-shift: 1.25rem;
}

.hero-slider.is-initialized .hero-slider__reveal {
	opacity: 0;
	transform: translate3d(0, var(--hero-reveal-shift), 0);
	transition:
		transform var(--hero-line-duration) var(--hero-ease),
		opacity calc(var(--hero-line-duration) * 0.7) linear;
}

.hero-slider.is-booted .hero-slider__slide.is-active .hero-slider__reveal {
	opacity: 1;
	transform: translate3d(0, 0, 0);
	transition-delay: calc(var(--line-index, 0) * var(--hero-stagger-step) + var(--hero-stagger-delay));
}

.hero-slider__eyebrow {
	font-size: var(--text-base);
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.5em;
    color: var(--hero-ink-dim);
}

.hero-slider__title {
	margin-top: 0rem;
	font-size: clamp(2.25rem, 9vw, 4.75rem);
	line-height: 0.98;
	letter-spacing: -0.025em;
	font-weight: 400;
	text-wrap: balance;
}

.hero-slider__meta {
	margin-top: 0rem;
	font-size: clamp(0.9375rem, 2.4vw, 2.0625rem);
	line-height: 1.45;
	color: var(--hero-ink-dim);
}

.hero-slider__price {
	margin-top: 0.15rem;
	font-size: clamp(0.9375rem, 2.4vw, 1.0625rem);
	line-height: 1.45;
}

.hero-slider__price-note {
	margin-left: 0.5rem;
	font-size: 0.75rem;
	color: var(--hero-ink-dim);
}

.hero-slider__action {
	margin-top: 1.4rem;
}

/* Fuehrendes .hero-slider, damit globale a- oder Button-Styles der Seite
   nicht ueber die Ladereihenfolge gewinnen. */
.hero-slider .hero-slider__cta {
	display: inline-block;
	padding: 0.8rem 1.75rem;
	border: 1px solid var(--hero-ink);
	border-radius: 0;
	background-color: transparent;
	color: var(--hero-ink);
	font-size: 0.9375rem;
	line-height: 1.2;
	letter-spacing: 0.01em;
	text-align: center;
	text-decoration: none;
	transition:
		background-color 300ms var(--hero-ease),
		color 300ms var(--hero-ease);
}

.hero-slider .hero-slider__cta:hover,
.hero-slider .hero-slider__cta:focus-visible {
	background-color: var(--hero-ink);
	color: #101012;
}

.hero-slider__sold {
	position: absolute;
	top: var(--hero-pad-block);
	left: var(--hero-pad-inline);
	z-index: 2;
	padding: 0.35rem 0.7rem;
	background-color: rgba(8, 9, 11, 0.7);
	font-size: 0.75rem;
	letter-spacing: 0.06em;
}

/* --- Bedienleiste --------------------------------------------------------- */
/* Alle Selektoren hier tragen bewusst das fuehrende .hero-slider und setzen
   die Theme-Eigenschaften explizit zurueck. Grund: wer splide.min.css statt
   splide-core.min.css laedt, bekommt ein Arrow-Theme mit position:absolute,
   top:50%, eigenem Hintergrund und einem scaleX(-1) auf dem prev-SVG. Ohne
   das zusaetzliche .hero-slider haetten beide Regelsaetze dieselbe
   Spezifitaet und die Ladereihenfolge im Bundle wuerde entscheiden. */

.hero-slider .hero-slider__ui {
	position: absolute;
	z-index: 3;
	right: var(--hero-pad-inline);
	bottom: calc(var(--hero-pad-block) + 0.35rem);
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.hero-slider .hero-slider__counter {
	margin: 0 0.35rem 0 0;
	font-size: 0.8125rem;
	font-variant-numeric: tabular-nums;
	letter-spacing: 0.06em;
	color: var(--hero-ink-dim);
}

.hero-slider .hero-slider__counter-current {
	color: var(--hero-ink);
}

.hero-slider .hero-slider__counter-separator {
	margin: 0 0.3rem;
	opacity: 0.55;
}

.hero-slider .hero-slider__arrows {
	position: static;
	display: flex;
	gap: 0.5rem;
}

.hero-slider .hero-slider__arrow,
.hero-slider .hero-slider__toggle {
	position: static;
	top: auto;
	right: auto;
	bottom: auto;
	left: auto;
	transform: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	border: 1px solid var(--hero-line-color);
	border-radius: 50%;
	background: transparent;
	color: var(--hero-ink);
	opacity: 1;
	cursor: pointer;
	transition:
		background-color 300ms var(--hero-ease),
		border-color 300ms var(--hero-ease),
		color 300ms var(--hero-ease);
}

.hero-slider .hero-slider__arrow:hover:not([disabled]),
.hero-slider .hero-slider__toggle:hover {
	background-color: var(--hero-ink);
	border-color: var(--hero-ink);
	color: #101012;
	opacity: 1;
}

.hero-slider .hero-slider__arrow svg,
.hero-slider .hero-slider__toggle svg {
	width: 0.875rem;
	height: 0.875rem;
	fill: currentColor;
	transform: none; /* splide.min.css spiegelt sonst den prev-Pfeil */
}

.hero-slider .hero-slider__arrow[disabled] {
	opacity: 0.35;
	cursor: default;
}

.hero-slider .hero-slider__toggle-play {
	display: none;
}

.hero-slider.is-paused .hero-slider__toggle-play {
	display: block;
}

.hero-slider.is-paused .hero-slider__toggle-pause {
	display: none;
}

.hero-slider .hero-slider__arrow:focus-visible,
.hero-slider .hero-slider__toggle:focus-visible,
.hero-slider .hero-slider__cta:focus-visible {
	outline: 2px solid var(--hero-ink);
	outline-offset: 3px;
}

/* --- Fortschrittsbalken --------------------------------------------------- */

/* Ein Segment je Werk statt einer durchgehenden Leiste. Das laufende Werk
   fuellt sich, die bereits gezeigten bleiben voll, die kommenden sind leer.
   Die Fuellung wird pro Frame aus dem Autoplay-Fortschritt gesetzt, deshalb
   hier bewusst KEINE transition — die wuerde der Leiste hinterherhinken. */

.hero-slider .hero-slider__progress {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 3;
	display: flex;
	gap: var(--hero-progress-gap);
	height: var(--hero-progress-height);
	background-color: transparent;
}

.hero-slider .hero-slider__progress-segment {
	flex: 1 1 0;
	height: 100%;
	overflow: hidden;
	background-color: var(--hero-progress-track);
}

.hero-slider .hero-slider__progress-fill {
	display: block;
	width: 100%;
	height: 100%;
	background-color: var(--hero-ink);
	transform: scaleX(0);
	transform-origin: left center;
}

/* Kein Autoplay -> Fortschritt und Pause-Button sind sinnlos */
.hero-slider.is-static .hero-slider__progress,
.hero-slider.is-static .hero-slider__toggle {
	display: none;
}

/* --- Breakpoints ---------------------------------------------------------- */

@media (min-width: 48em) {
	.hero-slider {
		--hero-pad-inline: 2.5rem;
		--hero-pad-block: 2.25rem;
		--hero-height: calc(100vh - var(--navHeight));
	}

	@supports (height: 1svh) {
		.hero-slider {
			--hero-height: calc(100svh - var(--navHeight));
		}
	}

	.hero-slider__content {
		max-width: 40rem;
		/* Rechts bleibt die Bedienleiste frei, sonst laeuft langer Text darunter */
		padding-right: calc(var(--hero-pad-inline) + 12rem);
		/* padding-bottom: calc(var(--hero-pad-block) + var(--hero-content-offset)); */
	}

	/* Nur im contain-Modus: Werk nach rechts, damit der Text freie Flaeche hat */
	.hero-slider__inner--fit-contain .hero-slider__image {
		object-position: 78% center;
	}

	.hero-slider__ui {
		bottom: calc(var(--hero-pad-block) + 0.5rem);
	}
}

@media (min-width: 64em) {
	.hero-slider {
		--hero-pad-inline: 3.5rem;
		--hero-pad-block: 3rem;
		--hero-height: calc(100vh - var(--navHeight));;
	}

	@supports (height: 1svh) {
		.hero-slider {
			--hero-height: calc(100svh - var(--navHeight));;
		}
	}

	.hero-slider__content {
		max-width: 46rem;
	}
}

/* --- Bewegung reduzieren -------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.hero-slider.is-booted .hero-slider__image {
		animation: none;
		transform: none;
	}

	.hero-slider.is-initialized .hero-slider__reveal {
		transform: none;
		transition: opacity 200ms linear;
	}

	.hero-slider.is-booted .hero-slider__slide.is-active .hero-slider__reveal {
		transform: none;
		transition-delay: 0ms;
	}

	/* Kuerzere Blende, passend zu speed 200 aus hero_slider.js */
	.hero-slider .splide__track--fade > .splide__list > .hero-slider__slide {
		transition: opacity 0s linear 200ms !important;
	}

	.hero-slider .splide__track--fade > .splide__list > .hero-slider__slide.is-active {
		transition: opacity 200ms linear !important;
	}
}
