/**
 * BS360 Energy Calculator - wizard styles.
 *
 * Alle Farbwerte kommen aus der offiziellen Betterspace-Farbpalette in
 * Confluence (Marketing > Webseite > Plugins > Farbpalette), nicht aus
 * frei gewählten Werten:
 * - "Sustainable Green" (Primärfarbe, Stufen 050-900)
 * - "Digital Gray" (Neutral/Text/Border, Stufen 050-900)
 * - "Innovative Bordeaux" (Akzentfarbe, Stufen 050-900)
 * - "Funktionsfarben" (Error/Warnung/Erfolg/Info, feste Einzelwerte)
 *
 * --bs360-color-primary (Green 500, #679D2E): Rahmen, Slider-Thumb,
 *   Fortschritts-Punkte - Nicht-Text-UI, braucht nur 3:1 (WCAG 1.4.11),
 *   erreicht 3,26:1 gegen Weiss.
 * --bs360-color-primary-contrast (Green 600, #527E25): Text auf grünem
 *   Grund (Buttons, Check-Icon, aktive Fortschritts-Labels, Slider-Wert).
 *   Text braucht 4,5:1 (WCAG 1.4.3); Stufe 500 kommt dort nur auf 3,26:1,
 *   Stufe 600 erreicht 4,81:1.
 * --bs360-color-primary-light (Green 300, #A4D571): heller Startpunkt für
 *   den Gradient im Slider-Fuell-Balken (300 -> 500, wie bei Preline's
 *   "Gradient track"-Variante, siehe advanced-range-slider.html).
 * --bs360-color-heading (Digital Gray 600, #323E44) / --bs360-color-text
 *   (Digital Gray 400, #5E737F): Überschriften vs. Fließtext, wie in der
 *   Digital-Gray-Beschreibung vorgegeben.
 * --bs360-color-muted (Digital Gray 300, #8297A3): sekundäre/kleinere
 *   Textelemente (Captions, Min/Max-Labels), heller als der Fließtext.
 * --bs360-color-border (Digital Gray 100, #D5DCE0): Rahmen und der helle
 *   Slider-Track-Hintergrund.
 * --bs360-color-surface (#FAFAFB): Hintergrund der linken Spalten-Box
 *   (5.0.9). @since 5.0.10 Rechnerischer Mittelwert zwischen Weiß
 *   (#FFFFFF) und dem ursprünglichen anthracite-050-Ton (#F5F6F7) je
 *   Farbkanal: (255+245)/2=250, (255+246)/2=250,5→251, (255+247)/2=251,
 *   ergibt #FAFAFB - der reine anthracite-050-Ton wirkte zu grau.
 *   Kein offizieller Palette-Wert mehr, sondern ein abgeleiteter
 *   Zwischenton auf explizite Anweisung.
 * --bs360-color-error (#D93025): offizielle Funktionsfarbe "Fehler".
 * --bs360-color-accent (Bordeaux 500, #AE1253): "Live"-Badge auf den
 *   Energieform-Buttons (Strom/Gas/Heizöl, 4.0.9). Weisser Text darauf
 *   erreicht 6,97:1 (WCAG AA bestanden, > 4,5:1). Bordeaux ist laut
 *   Confluence als Akzentfarbe "gezielt, nie flächig" gedacht - passt zu
 *   einem kleinen Badge, nicht zur Buttonfläche selbst.
 */

.bs360-ecp-v5 {
	--bs360-color-primary: #679D2E;
	--bs360-color-primary-light: #A4D571;
	--bs360-color-primary-contrast: #527E25;
	--bs360-color-result-bg: #F7FCF3;
	--bs360-color-surface: #FAFAFB;
	--bs360-color-border: #D5DCE0;
	--bs360-color-heading: #323E44;
	--bs360-color-text: #5E737F;
	--bs360-color-muted: #8297A3;
	--bs360-color-future: #D5DCE0;
	--bs360-color-error: #D93025;
	--bs360-color-accent: #AE1253;

	--bs360-ec-a: #00A651;
	--bs360-ec-b: #50B848;
	--bs360-ec-c: #BFD730;
	--bs360-ec-d: #FFF200;
	--bs360-ec-e: #FDB913;
	--bs360-ec-f: #F37021;
	--bs360-ec-g: #ED1C24;

	--bs360-footer-height: 96px; /* overwritten by calculator.js after first render */

	max-width: 1280px;
	margin: 0 auto;
	color: var(--bs360-color-text);
	font-size: 16px;
	line-height: 1.5;
	box-sizing: border-box;
	scroll-margin-top: 24px;
}

.bs360-ecp-v5 *,
.bs360-ecp-v5 *::before,
.bs360-ecp-v5 *::after {
	box-sizing: inherit;
}

.bs360-ecp-v5 .is-hidden {
	display: none !important;
}

/* ---------- Progress bar (concept 15.5a) ---------- */

.bs360-ecp-v5__progress {
	margin-bottom: 2rem;
}

.bs360-ecp-v5__progress-labels {
	display: flex;
	justify-content: space-between;
	margin-bottom: 0.5rem;
}

.bs360-ecp-v5__progress-label {
	flex: 1;
	text-align: center;
	font-size: 0.8rem;
	font-weight: 600;
	color: #ACBAC1; /* Digital Gray 200 - naeher am Grau des Tracks als --color-muted (300) */
}

.bs360-ecp-v5__progress-label.is-active,
.bs360-ecp-v5__progress-label.is-done {
	color: var(--bs360-color-primary-contrast);
}

/**
 * Track und Punkte teilen sich diese eine, relativ positionierte Zeile.
 * Die Hoehe der Zeile ergibt sich allein aus .progress-dots (normaler
 * Fluss); der Track ist absolut positioniert und vertikal zentriert -
 * dadurch liegen beide immer exakt auf einer Hoehe (Punkt 2), unabhaengig
 * von Label-Zeilenumbrüchen o.ä.
 */
.bs360-ecp-v5__progress-track-row {
	position: relative;
}

.bs360-ecp-v5__progress-dots {
	display: flex;
	position: relative;
	z-index: 1;
}

.bs360-ecp-v5__progress-dot-col {
	flex: 1;
	display: flex;
	justify-content: center;
	align-items: center;
}

.bs360-ecp-v5__progress-dot {
	width: 14px;
	height: 14px;
	flex: none;
	border-radius: 50%;
	background: #fff;
	border: 3px solid var(--bs360-color-future);
	display: block;
	transition: width 0.2s ease, height 0.2s ease, border-color 0.2s ease;
}

.bs360-ecp-v5__progress-dot.is-done {
	border-color: var(--bs360-color-primary);
}

.bs360-ecp-v5__progress-dot.is-active {
	border-color: var(--bs360-color-primary);
	width: 18px;
	height: 18px;
}

.bs360-ecp-v5__progress-track {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	height: 8px;
	background: var(--bs360-color-future);
	border-radius: 999px;
	overflow: hidden;
	/* 4 progress-step columns of equal width -> each dot's center sits at
	   half a column-width from the nearest edge (100% / (2*4) = 12.5%).
	   Insetting the track by that amount aligns its 0%/100% ends exactly
	   under the first/last dot, so the fill stops (0/33.33/66.67/100%)
	   land under every dot in between too. */
	left: 12.5%;
	right: 12.5%;
}

.bs360-ecp-v5__progress-fill {
	height: 100%;
	background: var(--bs360-color-primary);
	border-radius: 999px;
	position: relative;
	overflow: hidden;
	transition: width 0.3s ease;
	width: 0%;
}

.bs360-ecp-v5__progress-fill--step-1 { width: 0%; }
.bs360-ecp-v5__progress-fill--step-2 { width: 33.33%; }
.bs360-ecp-v5__progress-fill--step-3 { width: 66.67%; }
.bs360-ecp-v5__progress-fill--step-4 { width: 100%; }

/* ---------- Layout grid (identisch für jeden Step, Named Areas) ---------- */

/* Since 5.0.1: Grundgrid liegt jetzt direkt auf .bs360-ecp-v5__step statt
   auf einem äußeren, alle Steps umschließenden .bs360-ecp-v5__grid-
   Container. Grund: die alte Struktur (eine gemeinsame linke Spalte mit
   allen vier <section>-Steps darin, eine einzelne Vorschaubox rechts
   daneben) sperrte step-eigene Elemente wie die <h2>-Überschrift oder die
   Nav-Buttonzeile technisch in die linke Spalte ein - sie konnten nie
   architektonisch die volle Breite einnehmen, unabhängig vom CSS, das man
   ihnen gab (Konsistenz-Fund: Step-Überschrift stand nicht auf gleicher
   Höhe wie die Vorschaubox, Buttonzeile ließ sich nicht sauber auf volle
   Breite mit space-between ziehen).
   Jetzt ist jeder einzelne Step ein vollständiges, in sich geschlossenes
   Grid mit denselben vier benannten Bereichen:
     - headline: Step-Überschrift, volle Breite
     - content:  Kontextbox + Eingabemaske, linke Spalte
     - result:   die für diesen Step eigene Vorschaubox-Kopie, rechte Spalte
     - nav:      Zurück-/Weiter-Buttonzeile, volle Breite
   Alle vier Steps teilen sich denselben Selektor (.bs360-ecp-v5__step),
   also dieselbe grid-template-columns/areas-Definition - das ist
   entscheidend, damit beim Wechsel zwischen Steps keine Spalte springt:
   es gibt keine step-spezifische Breiten-Regel, die diese Basis
   überschreibt, .bs360-ecp-v5__step--1/2/3/4 dienen nur noch als reine
   Marker-Klassen für JS-Selektoren, nicht für Layout. */
/* Since 5.0.8: headline liegt jetzt in der linken Spalte (content) statt
   in einem eigenen, volle-Breite-Bereich - Ziel: Step-Überschrift und
   Vorschaubox beginnen auf derselben Höhe/Flucht (vorher stand die
   Headline über beiden Spalten, die Vorschaubox begann dadurch sichtbar
   tiefer als die linke Spalte). Auf Mobile (< 768px, ein Bereich pro
   Zeile) ändert sich am Ablauf nichts, die Headline steht dort ohnehin
   ganz oben. */
/* @since 5.0.23 Spaltenreihenfolge getauscht (explizite Anweisung):
   Vorschaubox (result) jetzt links, Eingabemaske (content) rechts -
   reine Positions-Vertauschung, das Breitenverhaeltnis bleibt
   unveraendert (result weiterhin die schmalere 35fr-Spalte, jetzt nur
   links statt rechts). grid-area: content/result an den Elementen
   selbst (siehe .bs360-ecp-v5__step-content/.bs360-ecp-v5__result
   weiter unten) muss dafuer NICHT geaendert werden - nur die Areas
   selbst wandern hier auf eine andere Grid-Position. */
.bs360-ecp-v5__step {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-areas:
		"result"
		"content"
		"nav";
	gap: 2rem;
	align-items: start;
}

/* @since 5.0.24 align-items: stretch NUR ab diesem Breakpoint (explizite
   Anweisung: Höhenangleichung nur Desktop, nicht Mobile) - beide Boxen
   (result links, content rechts) nehmen dadurch automatisch die Höhe
   der jeweils höheren Box an, ohne dass eine feste Pixelhöhe berechnet
   werden müsste. Mobile bleibt bei align-items: start von oben (jede
   Box behält ihre natürliche Inhaltshöhe) - dort stehen beide Boxen
   ohnehin untereinander, eine erzwungene Mindesthöhe wäre dort nur
   unnötiger Leerraum. */
@media (min-width: 768px) {
	.bs360-ecp-v5__step {
		grid-template-columns: 35fr 65fr;
		grid-template-areas:
			"result  content"
			"nav     nav";
		align-items: stretch;
	}
}

/* Since 5.0.9: linke Spalte jetzt als eigene Box, optisch analog zur
   Vorschaubox rechts (.bs360-ecp-v5__result).
   @since 5.0.10 Hintergrund anthracite-100-Rahmen kombiniert mit
   --bs360-color-surface als Hintergrund (Wert siehe Definition/
   Dokumentation oben - inzwischen ein abgeleiteter, aufgehellter
   Zwischenton statt des reinen anthracite-050-Werts, reiner
   anthracite-050-Hintergrund wirkte zu grau). */
.bs360-ecp-v5__step-content {
	grid-area: content;
	min-width: 0;
	background: var(--bs360-color-surface);
	border: 1px solid var(--bs360-color-border);
	border-radius: 10px;
	padding: 1.5rem 1.5rem 2.5rem;
}

/* ---------- Generic step / field styles ---------- */


/* Step-Übergänge (4.0.22, angepasst 5.0.1): animieren die jeweilige
   Step-Section selbst (.bs360-ecp-v5__step), nicht mehr ein
   gemeinsames äußeres .bs360-ecp-v5__grid - das gab es bis 5.0.1, ist
   mit der neuen Struktur (jeder Step ist sein eigenes vollständiges
   Grid, siehe render_wizard()) aber entfallen. JS steuert
   is-exiting/is-entering weiterhin aktiv per Klassenwechsel (siehe
   goTo() in calculator.js), inklusive erzwungenem Reflow vor dem
   erneuten Hinzufügen von is-entering, damit die Animation bei
   aufeinanderfolgenden Übergängen zuverlässig neu startet. */
.bs360-ecp-v5__step.is-exiting {
	animation: bs360-grid-exit-left 0.2s ease forwards;
}

.bs360-ecp-v5__step.is-exiting.bs360-ecp-v5__step--reverse {
	animation: bs360-grid-exit-right 0.2s ease forwards;
}

.bs360-ecp-v5__step.is-entering {
	animation: bs360-grid-enter-right 0.3s ease;
}

.bs360-ecp-v5__step.is-entering.bs360-ecp-v5__step--reverse {
	animation: bs360-grid-enter-left 0.3s ease;
}

@keyframes bs360-grid-enter-right {
	from { opacity: 0; transform: translateX(40px); }
	to { opacity: 1; transform: translateX(0); }
}

@keyframes bs360-grid-enter-left {
	from { opacity: 0; transform: translateX(-40px); }
	to { opacity: 1; transform: translateX(0); }
}

@keyframes bs360-grid-exit-left {
	from { opacity: 1; transform: translateX(0); }
	to { opacity: 0; transform: translateX(-40px); }
}

@keyframes bs360-grid-exit-right {
	from { opacity: 1; transform: translateX(0); }
	to { opacity: 0; transform: translateX(40px); }
}

@media (prefers-reduced-motion: reduce) {
	.bs360-ecp-v5__step.is-exiting,
	.bs360-ecp-v5__step.is-exiting.bs360-ecp-v5__step--reverse,
	.bs360-ecp-v5__step.is-entering,
	.bs360-ecp-v5__step.is-entering.bs360-ecp-v5__step--reverse {
		animation: none;
	}
}

/* @since 5.0.10 Auf 1.3rem angeglichen (Mittelwert zwischen den bisher
   auseinanderlaufenden 1.5rem hier und 1.1rem bei
   .bs360-ecp-v5__result-heading) - Step-Headline und Vorschaubox-Titel
   sollen einheitlich wirken. */
.bs360-ecp-v5__heading {
	font-size: 1.3rem;
	margin: 0 0 1rem;
	color: var(--bs360-color-heading);
	font-weight: 600;
}

.bs360-ecp-v5__field {
	margin-bottom: 1.75rem;
}

/* Since 5.0.6: Belegungszeit/Sanierungsjahr sind gesperrt, bis der
   Besucher die Zimmeranzahl aktiv verändert hat (roomsFine >= 2, siehe
   isStepValid('2') in calculator.js) - macht die Bearbeitungsreihenfolge
   von Step 2 optisch eindeutig, statt drei gleichwertig wirkende Regler
   gleichzeitig zu zeigen. disabled auf dem <input type="range"> allein
   reicht nicht als visuelles Signal (Browser-Default ist zu subtil),
   daher zusätzlich die ganze Feldgruppe gedimmt. */
.bs360-ecp-v5__field.is-locked {
	opacity: 0.45;
}

.bs360-ecp-v5__field.is-locked .bs360-ecp-v5__slider {
	cursor: not-allowed;
}

/* Since 5.0.0: data-awaits-house-count-Regeln entfernt - gehörten zu
   Step 3B (Anzahl Gebäude), das komplett entfällt (Konzept Abschnitt 1).
   Das Attribut kommt im Markup nicht mehr vor. */

.bs360-ecp-v5__label {
	display: block;
	font-weight: 600;
	margin-bottom: 0.5rem;
	color: var(--bs360-color-heading);
}

.bs360-ecp-v5__label-optional {
	font-weight: 400;
	color: var(--bs360-color-muted);
}

/**
 * Custom range slider (Punkte 1, 4, 7). Native appearance komplett
 * entfernt, damit Track und Thumb vollständig selbst gestaltet werden
 * können - das behebt nebenbei auch die Reichweite: mit nativer
 * Browser-Darstellung reservieren manche Browser/Betriebssysteme ein
 * paar Pixel Rand für die Kugel-Form am Anfang/Ende, mit appearance:none
 * zeichnen wir Track und Thumb selbst über die volle Breite des Inputs.
 *
 * @since 4.0.3
 */
.bs360-ecp-v5__slider {
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	width: 100%;
	height: 20px; /* reserviert Platz für den 18px-Thumb, ohne Hover-Layout-Sprung */
	margin: 0;
	padding: 0;
	background: transparent;
	cursor: pointer;
}

/**
 * Track: heller Rest-Balken, davor ein gruener Fuell-Balken (Gradient
 * 300->500) bis zum aktuellen Wert. Der Fuellstand kommt ueber die
 * CSS-Variable --bs360-fill-pct, die calculator.js bei jeder
 * Wertaenderung setzt (auf dem Input selbst, sie vererbt sich in die
 * Pseudo-Elemente). WebKit hat kein natives "Fill"-Pseudo-Element,
 * deshalb der Gradient-Trick mit hartem Farbwechsel bei fill-pct;
 * Firefox hat mit ::-moz-range-progress ein echtes Pendant, dessen
 * Breite der Browser selbst passend zum Wert setzt.
 *
 * Masse und Thumb-Optik (weiss, 4px farbiger Rahmen, 18px) an
 * https://preline.co/docs/components/advanced-range-slider.html angelehnt.
 */
.bs360-ecp-v5__slider {
	--bs360-fill-pct: 0%;
}

.bs360-ecp-v5__slider::-webkit-slider-runnable-track {
	width: 100%;
	height: 8px;
	border-radius: 999px;
	background: linear-gradient(
		to right,
		var(--bs360-color-primary-light) 0%,
		var(--bs360-color-primary) var(--bs360-fill-pct),
		var(--bs360-color-border) var(--bs360-fill-pct),
		var(--bs360-color-border) 100%
	);
}

.bs360-ecp-v5__slider::-moz-range-track {
	width: 100%;
	height: 8px;
	border-radius: 999px;
	background: var(--bs360-color-border);
}

.bs360-ecp-v5__slider::-moz-range-progress {
	height: 8px;
	border-radius: 999px;
	background: linear-gradient( to right, var(--bs360-color-primary-light), var(--bs360-color-primary) );
}

/* Thumb: weiss mit gruenem Rahmen (wie Preline), bei Hover 2x groesser (animiert, Punkt 4 letzte Runde) */
.bs360-ecp-v5__slider::-webkit-slider-thumb {
	-webkit-appearance: none;
	width: 18px;
	height: 18px;
	margin-top: -5px; /* (18px Thumb - 8px Track) / 2, zentriert den Thumb auf dem Track */
	border-radius: 50%;
	background: #fff;
	border: 4px solid var(--bs360-color-primary);
	transition: transform 0.2s ease;
}

.bs360-ecp-v5__slider:hover::-webkit-slider-thumb {
	transform: scale(2);
}

.bs360-ecp-v5__slider::-moz-range-thumb {
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: #fff;
	border: 4px solid var(--bs360-color-primary);
	transition: transform 0.2s ease;
}

.bs360-ecp-v5__slider:hover::-moz-range-thumb {
	transform: scale(2);
}

.bs360-ecp-v5__slider-scale {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	align-items: baseline;
	column-gap: 0.75rem;
	margin-top: 0.5rem;
}

.bs360-ecp-v5__slider-scale-min,
.bs360-ecp-v5__slider-scale-max {
	font-size: 0.75rem;
	color: var(--bs360-color-muted);
}

.bs360-ecp-v5__slider-scale-max {
	text-align: right;
}

.bs360-ecp-v5__slider-output {
	font-weight: 600;
	text-align: center;
	color: var(--bs360-color-primary-contrast);
}

.bs360-ecp-v5__slider-output--standalone {
	display: block;
	width: 100%;
	margin-top: 0.5rem;
}

.bs360-ecp-v5__field input[type="number"] {
	width: 100%;
	max-width: 220px;
	padding: 0.6rem 0.75rem;
	background: #fff;
	border: 1px solid var(--bs360-color-border);
	border-radius: 6px;
	font: inherit;
}

/**
 * Step 3A/3B's precise room-count field (4.1.1): a range slider (1er-
 * Schritte) with a coupled number input directly beside it - the slider
 * covers the branch's full min/max span at a glance, the number input
 * lets you jump straight to a large value (e.g. bis 2000 bei Kliniken)
 * without dragging through the whole range.
 */
.bs360-ecp-v5__rooms-fine-row {
	display: flex;
	align-items: center;
	gap: 1rem;
}

.bs360-ecp-v5__rooms-fine-row .bs360-ecp-v5__slider {
	flex: 1;
}

.bs360-ecp-v5__rooms-fine-row input[type="number"] {
	flex: 0 0 auto;
	width: 90px;
	max-width: 90px;
}

@media (max-width: 480px) {
	.bs360-ecp-v5__rooms-fine-row {
		flex-direction: column;
		align-items: stretch;
		gap: 0.5rem;
	}

	.bs360-ecp-v5__rooms-fine-row input[type="number"] {
		width: 100%;
		max-width: none;
	}
}

.bs360-ecp-v5__subtext {
	margin: 0.4rem 0 0;
	color: var(--bs360-color-muted);
	font-size: 0.9rem;
}

/* ---------- Step 1: branch cards ---------- */

/* Since 5.0.5: auto-fit (5.0.4) erlaubte rechnerisch beliebig viele
   Spalten auf breiten Containern - auf explizite Anweisung fest auf
   maximal 3 Spalten pro Reihe begrenzt (Desktop), 2 auf Mobile.
   @since 5.0.18 Auf 3 Stufen erweitert und mit dem Energieform-Grid
   (Step 3, .bs360-ecp-v5__energy-grid) vereinheitlicht: beide nutzen
   jetzt identische Spaltenzahlen je Breakpoint (2 mobile, 3 dazwischen,
   4 Desktop), vorher liefen Branchen-Grid (feste 3/2 Spalten) und
   Energieform-Grid (auto-fit, rechnerisch beliebig viele Spalten)
   auseinander. Breakpoints bei 768px/1024px, siehe Tailwind-Konvention
   des Themes. Eine unvollstaendige letzte Zeile bleibt weiterhin
   linksbuendig mit Luecke rechts (unveraendert seit 5.0.4,
   User-Entscheidung). */
.bs360-ecp-v5__branch-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 0.75rem;
	margin-bottom: 1rem;
}

@media (min-width: 768px) {
	.bs360-ecp-v5__branch-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (min-width: 1024px) {
	.bs360-ecp-v5__branch-grid {
		grid-template-columns: repeat(4, 1fr);
	}
}

/* @since 5.0.19 max-height: 200px und width: 100% ergänzt (explizite
   Anweisung): Branchenkarte und Energieform-Button (siehe
   .bs360-ecp-v5__energy-button weiter unten) waren trotz identischem
   aspect-ratio unterschiedlich hoch, da nur der Energieform-Button diese
   Deckelung hatte - bei den seit 5.0.18 gleich breiten Spalten (4 Grid-
   Spalten Desktop) fiel das als sichtbarer Höhenunterschied auf. */
.bs360-ecp-v5__branch-card {
	position: relative;
	aspect-ratio: 1 / 1;
	width: 100%;
	max-height: 200px;
	padding: 0;
	border: 2px solid var(--bs360-color-border);
	border-radius: 8px;
	background-color: #f6f7f7;
	background-size: cover;
	background-position: center;
	cursor: pointer;
	text-align: left;
	font: inherit;
	color: var(--bs360-color-text);
	overflow: hidden;
	transition: border-color 0.12s ease;
}

/* @changed 4.1.6: opacity in der transition-Liste ergaenzt - .has-bg-image
   ist spezifischer als das einfache .bs360-ecp-v5__branch-card aus dem
   Hover-Dimm-Block weiter unten, transition wird also komplett ersetzt
   statt vereinigt. Ohne opacity hier wuerde der Dimm-Fade bei Bild-Karten
   hart springen statt weich einzublenden (identischer Fund/Fix wie bei
   .bs360-ecp-v5__energy-button.has-bg-image). */
.bs360-ecp-v5__branch-card.has-bg-image {
	filter: grayscale(1);
	transition: filter 0.15s ease, border-color 0.12s ease, opacity 0.2s ease;
}

.bs360-ecp-v5__branch-card.has-bg-image:hover,
.bs360-ecp-v5__branch-card.has-bg-image:focus-visible,
.bs360-ecp-v5__branch-card.has-bg-image.is-selected {
	filter: grayscale(0);
}

.bs360-ecp-v5__branch-card:hover,
.bs360-ecp-v5__branch-card:focus-visible {
	border-color: var(--bs360-color-primary);
}

.bs360-ecp-v5__branch-card.is-selected {
	border-color: var(--bs360-color-primary);
}

/*
 * Punkt: beim Hover ueber eine Branchenkarte sollen alle anderen Karten im
 * Grid blasser werden, damit die gehoverte Karte optisch hervorsticht.
 *
 * @changed 4.1.5: vorher reagierte der Dimm-Effekt auf
 * :has(.branch-card:hover) - das griff nur, solange der Mauszeiger sich
 * exakt ueber einer Karte befand. Beim Wechsel zur naechsten Kachel
 * ueberquert die Maus zwangslaeufig kurz den Grid-Gap (0.75rem), wo keine
 * Karte gehovert ist; :has() wurde dabei fuer einen Frame false, alle
 * Karten sprangen zurueck auf volle Opazitaet und dann sofort wieder
 * zurueck - sichtbares Flackern. Fix: der Ein/Aus-Trigger ist jetzt
 * .bs360-ecp-v5__branch-grid:hover selbst (der Gap liegt INNERHALB der
 * Grid-Container-Flaeche, die Maus verlaesst den Container beim Wechsel
 * zwischen Kacheln also nie) - :has() wird nur noch benutzt, um
 * zusaetzlich zu bestimmen, WELCHE Karte hell bleiben soll, nicht mehr OB
 * gedimmt wird.
 */
@media (hover: hover) {
	.bs360-ecp-v5__branch-grid:hover .bs360-ecp-v5__branch-card {
		opacity: 0.6;
		transition: opacity 0.2s ease, border-color 0.12s ease;
	}

	.bs360-ecp-v5__branch-grid:has(.bs360-ecp-v5__branch-card:hover):hover
		.bs360-ecp-v5__branch-card:hover {
		opacity: 1;
	}
}

/*
 * @since 5.0.12 Analog zum Hover-Dimm-Effekt oben, aber dauerhaft statt
 * nur bei :hover: sobald eine Karte ausgewählt ist, werden alle anderen
 * dauerhaft abgeschwächt, die ausgewählte bleibt voll sichtbar - auch
 * auf Touch-Geräten ohne Hover-Fähigkeit (daher bewusst außerhalb von
 * @media (hover: hover)). Höhere Spezifität als der Hover-Block oben
 * (zusätzliche .is-selected-Klasse im :has()-Argument), daher gewinnt
 * beim reinen Betrachten (nichts gehovert) diese Regel; wird eine
 * ANDERE Karte gehovert, gewinnt dort weiterhin die spezifischere
 * Hover-Regel (:hover direkt auf der Karte) und blendet die Auswahl
 * kurzzeitig mit ab, genau wie es der Hover-Effekt für jede andere
 * Karte auch tut.
 */
.bs360-ecp-v5__branch-grid:has(.bs360-ecp-v5__branch-card.is-selected) .bs360-ecp-v5__branch-card {
	opacity: 0.6;
	transition: opacity 0.2s ease, border-color 0.12s ease;
}

.bs360-ecp-v5__branch-grid:has(.bs360-ecp-v5__branch-card.is-selected) .bs360-ecp-v5__branch-card.is-selected {
	opacity: 1;
}

/* @since 5.0.15 Grundlegend neu gestaltet (explizite Anweisung): Text
   jetzt mittig in der Kachel statt am unteren Rand (inset: 0 +
   flex-Zentrierung statt inset: auto 0 0 0).
   @since 5.0.17 Gradient-Overlay (5.0.16, davor 5.0.15) komplett entfernt
   - passte optisch nicht zu den tatsaechlichen Hintergrundbildern.
   Kontrast fuer die weisse Schrift kommt jetzt ausschliesslich ueber
   text-shadow: mehrere leicht versetzte, weiche dunkle Schatten wirken
   wie eine duenne Kontur um die Buchstaben, funktioniert unabhaengig vom
   jeweiligen Bildmotiv (hell oder dunkel) ohne einen zusaetzlichen
   Farbschleier ueber das Bild zu legen. */
.bs360-ecp-v5__branch-card-label {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0.85rem;
	color: #fff;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75), 0 1px 8px rgba(0, 0, 0, 0.55);
	font: inherit;
	font-size: 20px;
	font-weight: 600;
	text-align: center;
	line-height: 1.3;
	/* Since 5.0.3: nowrap+ellipsis cut the label off left/right on narrow
	   viewports instead of wrapping it - the card grid shrinks the card
	   width on mobile, but the label text stayed a single forced line.
	   Fix: allow normal wrapping, drop the now-pointless ellipsis. */
	white-space: normal;
	overflow-wrap: break-word;
}

/* Branchen ohne Hintergrundbild (heller, flacher Kachel-Hintergrund):
   weisse Schrift mit dunklem text-shadow waere hier unnoetig bzw. wirkt
   auf einer flachen Farbe seltsam - stattdessen dunkle Schrift ohne
   Schatten wie zuvor. */
.bs360-ecp-v5__branch-card:not(.has-bg-image) .bs360-ecp-v5__branch-card-label {
	color: var(--bs360-color-heading);
	text-shadow: none;
	min-width: 0;
}

/* ---------- Step 2: energy type buttons ---------- */

/* @since 5.0.18 Von auto-fit (rechnerisch beliebig viele Spalten je nach
   Breite) auf dieselben festen Spaltenzahlen wie das Branchen-Grid
   umgestellt (siehe .bs360-ecp-v5__branch-grid weiter oben fuer die
   ausfuehrliche Begruendung) - beide Grids sollen sich einheitlich
   verhalten (2 mobile, 3 dazwischen, 4 Desktop), explizite Anweisung. */
.bs360-ecp-v5__energy-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 0.75rem;
	margin-bottom: 1rem;
}

@media (min-width: 768px) {
	.bs360-ecp-v5__energy-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (min-width: 1024px) {
	.bs360-ecp-v5__energy-grid {
		grid-template-columns: repeat(4, 1fr);
	}
}

.bs360-ecp-v5__energy-button {
	position: relative;
	aspect-ratio: 1 / 1;
	width: 100%;
	max-height: 200px;
	padding: 0;
	border: 2px solid var(--bs360-color-border);
	border-radius: 8px;
	background-color: #f6f7f7;
	background-size: cover;
	background-position: center;
	font: inherit;
	font-weight: 600;
	cursor: pointer;
	overflow: hidden;
	transition: border-color 0.12s ease;
}

/* Buttons mit Hintergrundbild (Gas/Strom/Heizoel/Fernwaerme, kein Bild bei
   "Sonstiges/Eigenerzeugung", siehe Backend-Tab "Step 2"): Bild
   standardmaessig in Graustufen, nur bei Hover/Fokus/Auswahl in Farbe -
   macht den ausgewaehlten Zustand eindeutiger erkennbar.
   @changed: opacity in der transition-Liste ergaenzt - .has-bg-image ist
   spezifischer als das einfache .bs360-ecp-v5__energy-button aus dem
   Hover-Dimm-Block weiter unten, transition wird also komplett ersetzt statt
   vereinigt. Ohne opacity hier wuerde der Dimm-Fade bei Bild-Buttons hart
   springen statt weich einzublenden. */
.bs360-ecp-v5__energy-button.has-bg-image {
	filter: grayscale(1);
	transition: filter 0.15s ease, border-color 0.12s ease, opacity 0.2s ease;
}

.bs360-ecp-v5__energy-button.has-bg-image:hover,
.bs360-ecp-v5__energy-button.has-bg-image:focus-visible,
.bs360-ecp-v5__energy-button.has-bg-image[aria-checked="true"] {
	filter: grayscale(0);
}

.bs360-ecp-v5__energy-button[aria-checked="true"] {
	border-color: var(--bs360-color-primary);
}

/*
 * Punkt: gleicher Hover-Dimm-Effekt wie bei den Branchenkarten (Step 1,
 * .bs360-ecp-v5__branch-grid weiter oben) - beim Hover ueber einen
 * Energieform-Button werden alle anderen Buttons blasser, damit der
 * gehoverte Button hervorsticht. Trigger liegt auf dem Grid-Container
 * selbst (:hover), nicht auf den einzelnen Buttons, damit das Ueberqueren
 * des Grid-Gaps zwischen zwei Buttons kein Flackern verursacht (siehe
 * 4.1.5-Fix bei den Branchenkarten fuer die ausfuehrliche Begruendung).
 */
@media (hover: hover) {
	.bs360-ecp-v5__energy-grid:hover .bs360-ecp-v5__energy-button {
		opacity: 0.6;
		transition: opacity 0.2s ease, border-color 0.12s ease;
	}

	.bs360-ecp-v5__energy-grid:has(.bs360-ecp-v5__energy-button:hover):hover
		.bs360-ecp-v5__energy-button:hover {
		opacity: 1;
	}
}

/* @since 5.0.12 Dauerhafte Auswahl-Hervorhebung, analog zu den
   Branchenkarten (siehe dortiger, ausführlicherer Kommentar): sobald ein
   Energieform-Button ausgewählt ist ([aria-checked="true"]), werden alle
   anderen dauerhaft abgeschwächt statt nur bei :hover - auch auf
   Touch-Geräten. */
.bs360-ecp-v5__energy-grid:has(.bs360-ecp-v5__energy-button[aria-checked="true"]) .bs360-ecp-v5__energy-button {
	opacity: 0.6;
	transition: opacity 0.2s ease, border-color 0.12s ease;
}

.bs360-ecp-v5__energy-grid:has(.bs360-ecp-v5__energy-button[aria-checked="true"]) .bs360-ecp-v5__energy-button[aria-checked="true"] {
	opacity: 1;
}

/* @since 5.0.15 Grundlegend neu gestaltet, analog zu den Branchenkarten
   (siehe dortiger, ausfuehrlicherer Kommentar): Text jetzt mittig statt
   am unteren Rand. Kein eigener z-index hier (das Label liegt im DOM
   nach dem "Live"-Badge, siehe render_step3() - waere beide auf
   demselben z-index, gewinnt die spaetere Quellreihenfolge, das Label
   wuerde das Badge verdecken; das Badge bekommt daher unten den
   hoeheren Wert).
   @since 5.0.17 Gradient-Overlay (5.0.16, davor 5.0.15) entfernt, Kontrast
   stattdessen ueber text-shadow (siehe Branchenkarten-Label fuer die
   ausfuehrliche Begruendung). */
.bs360-ecp-v5__energy-button-label {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0.85rem;
	color: #fff;
	text-shadow: 0 1px 3px rgba(0, 0, 0, 0.75), 0 1px 8px rgba(0, 0, 0, 0.55);
	font: inherit;
	font-size: 20px;
	font-weight: 600;
	text-align: center;
	line-height: 1.3;
}

.bs360-ecp-v5__energy-button:not(.has-bg-image) .bs360-ecp-v5__energy-button-label {
	color: var(--bs360-color-heading);
	text-shadow: none;
}

/* "Live"-Badge (4.0.9, Position korrigiert 4.0.10): kennzeichnet
   Energieformen mit Live-Preisquelle (Strom, Gas, Heizoel). Oben links auf
   dem Button positioniert, mit Abstand zum Rand statt darueber hinauszuragen
   (top/left positiv statt negativ). Bordeaux 500 als Akzentfarbe (siehe
   Farbvariablen-Kommentar oben), weisser Text fuer WCAG-AA-Kontrast
   (6,97:1).
   @since 5.0.15 z-index von 1 auf 2 erhoeht: das Energieform-Label
   (.bs360-ecp-v5__energy-button-label) deckt seit 5.0.15 die komplette
   Kachel ab statt nur einen unteren Streifen, liegt im DOM ausserdem
   nach diesem Badge - ohne einen hoeheren z-index waere das Badge sonst
   vom Label-Overlay verdeckt. */
.bs360-ecp-v5__live-badge {
	position: absolute;
	top: 0.4rem;
	left: 0.4rem;
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	padding: 0.15rem 0.5rem;
	border-radius: 999px;
	background-color: var(--bs360-color-accent);
	color: #FFFFFF;
	font-size: 0.7rem;
	font-weight: 600;
	line-height: 1.4;
	white-space: nowrap;
	pointer-events: none;
	z-index: 2;
}

/* Aufnahme-Punkt (4.0.11): dezentes Pulsieren per Opacity statt An/Aus, damit
   es wie eine "live"-Anzeige wirkt (Kamera-Aufnahme-Symbol), ohne im
   Formular abzulenken. prefers-reduced-motion respektiert. */
.bs360-ecp-v5__live-dot {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background-color: #FFFFFF;
	flex-shrink: 0;
	animation: bs360-ecp-v5-live-pulse 1.8s ease-in-out infinite;
}

@keyframes bs360-ecp-v5-live-pulse {
	0%, 100% { opacity: 1; }
	50% { opacity: 0.35; }
}

@media (prefers-reduced-motion: reduce) {
	.bs360-ecp-v5__live-dot {
		animation: none;
	}
}

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

.bs360-ecp-v5__nav {
	grid-area: nav;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: 2.5rem;
}

/* Since 5.0.1: Step 4 ist der einzige Step, dessen Inhalt in ein <form>
   eingebettet ist (Submit-Button muss Teil des Formulars bleiben, siehe
   render_step4()). display:contents lässt das <form>-Element selbst aus
   dem Grid-Fluss verschwinden, ohne es aus dem DOM zu entfernen - seine
   direkten Kinder (.step-content, .result, .nav) werden dadurch genauso
   wie bei den anderen drei Steps direkt zu Grid-Items von
   .bs360-ecp-v5__step, statt eine zusätzliche Verschachtelungsebene zu
   bilden, die sonst die Named-Area-Zuordnung durchbrechen würde. */
.bs360-ecp-v5__form {
	display: contents;
}

.bs360-ecp-v5__nav .bs360-ecp-v5__button--secondary {
	flex: 0 0 auto;
}

.bs360-ecp-v5__nav .bs360-ecp-v5__button--primary {
	flex: 0 0 auto;
	/* Since 5.0.1: schiebt den Primary-Button (Weiter/Absenden) an den
	   rechten Rand der Nav-Zeile, auch auf Step 1, wo es keinen
	   Zurück-Button als Geschwister-Element gibt - justify-content:
	   space-between allein hätte den einzigen Button dort links
	   stehen lassen statt rechts. margin-left:auto funktioniert in
	   beiden Fällen identisch (mit oder ohne Zurück-Button davor). */
	margin-left: auto;
}

.bs360-ecp-v5__button {
	padding: 0.75rem 1.5rem;
	border-radius: 6px;
	border: 2px solid var(--bs360-color-primary-contrast);
	background: var(--bs360-color-primary-contrast);
	color: #fff;
	font: inherit;
	font-weight: 600;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
}

.bs360-ecp-v5__button--secondary {
	background: transparent;
	border-color: var(--bs360-color-primary-contrast);
	color: var(--bs360-color-primary-contrast);
}

.bs360-ecp-v5__button:disabled {
	opacity: 0.6;
	cursor: not-allowed;
}

/* @since 5.0.21 Submit-Button (Step 4, letzter Schritt) in Bordeaux
   statt Grün - hebt den finalen Handlungsschritt farblich von den
   "Weiter"-Buttons der Steps 1-3 ab, die weiterhin die grüne
   .bs360-ecp-v5__button--primary-Basisfarbe nutzen. data-submit-button
   ist ein eindeutiges Attribut, ausschließlich am Submit-Button, daher
   ohne Nebenwirkung auf die anderen Primary-Buttons.
   Schimmer-Effekt in Dauerschleife (explizite Anweisung "ohne nervig zu
   wirken"): der Effekt selbst läuft schnell (0.9s), aber mit einer
   langen Pause dazwischen (3.6s Gesamtzyklus je Durchlauf) - dieselbe
   Overlay-Technik wie bei .bs360-ecp-v5__result-hint.is-shimmering
   (Gradient-Streifen per translateX über die Fläche), aber mit
   animation-iteration-count: infinite statt einmalig, und einer langen
   Wartezeit zwischen den Durchläufen statt einer Dauerbewegung. Eine
   Animation, die ununterbrochen läuft, waere auf einem Button, den man
   laenger ansieht (z.B. beim Ausfuellen der Kontaktfelder direkt
   daneben), staendig im Augenwinkel sichtbar und damit ablenkend/nervig
   - die Pausen dazwischen geben dem Auge Ruhe. */
.bs360-ecp-v5__button[data-submit-button] {
	border-color: var(--bs360-color-accent);
	background: var(--bs360-color-accent);
	position: relative;
	overflow: hidden;
}

.bs360-ecp-v5__button[data-submit-button]::after {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: linear-gradient(115deg, transparent 0%, rgba(255, 255, 255, 0.35) 50%, transparent 100%);
	transform: translateX(-100%);
	animation: bs360-ecp-v5-submit-shimmer 3.6s ease-in-out infinite;
}

/* @since 5.0.22 Reihenfolge umgekehrt (explizite Anweisung: Pause soll
   VOR dem ersten sichtbaren Durchlauf stehen, nicht danach) - der
   Streifen bleibt jetzt von 0% bis 75% links außerhalb der Kachel
   stehen (Pause, 2.7s von 3.6s Zyklusdauer) und läuft erst in den
   letzten 25% (0.9s) einmal durch. Da die Animation ohnehin in
   Dauerschleife läuft (infinite), wiederholt sich "Pause dann
   Durchlauf" fortlaufend - der Button steht zwar schon vor dem
   Erreichen von Step 4 im DOM (siehe render_step4()), aber weil jeder
   Zyklus mit der Pause beginnt, sieht ein Besucher beim Betreten von
   Step 4 in aller Regel zunächst die Pause, bevor der erste sichtbare
   Durchlauf kommt - ganz ohne zusätzliches JS-Timing. */
@keyframes bs360-ecp-v5-submit-shimmer {
	0%   { transform: translateX(-100%); }
	75%  { transform: translateX(-100%); }
	100% { transform: translateX(200%); }
}

@media (prefers-reduced-motion: reduce) {
	.bs360-ecp-v5__button[data-submit-button]::after {
		animation: none;
	}
}

.bs360-ecp-v5__link-button {
	display: inline-block;
	margin: 0 0 1rem;
	background: none;
	border: none;
	padding: 0;
	color: var(--bs360-color-primary-contrast);
	font: inherit;
	font-weight: 600;
	text-decoration: underline;
	cursor: pointer;
}

@media (min-width: 768px) {
	.bs360-ecp-v5 .bs360-ecp-v5__nav {
		grid-column: 1 / -1;
	}
}

/* ---------- Step 4: contact form ---------- */

.bs360-ecp-v5__form .bs360-ecp-v5__field input[type="text"],
.bs360-ecp-v5__form .bs360-ecp-v5__field input[type="email"],
.bs360-ecp-v5__form .bs360-ecp-v5__field input[type="tel"],
.bs360-ecp-v5__form .bs360-ecp-v5__field select {
	width: 100%;
	padding: 0.6rem 0.75rem;
	background: #fff;
	border: 1px solid var(--bs360-color-border);
	border-radius: 6px;
	font: inherit;
}

.bs360-ecp-v5__field--consent {
	font-size: 0.9rem;
}

.bs360-ecp-v5__honeypot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.bs360-ecp-v5__form-error {
	color: var(--bs360-color-error);
	font-weight: 600;
}

.bs360-ecp-v5__spinner {
	width: 14px;
	height: 14px;
	border: 2px solid rgba(255, 255, 255, 0.5);
	border-top-color: #fff;
	border-radius: 50%;
	animation: bs360-spin 0.6s linear infinite;
}

@keyframes bs360-spin {
	to { transform: rotate(360deg); }
}

.bs360-ecp-v5__success {
	background: var(--bs360-color-result-bg);
	border: 1px solid var(--bs360-color-primary);
	border-radius: 8px;
	padding: 1.5rem;
	font-weight: 600;
}

/* ---------- Result panel ---------- */

.bs360-ecp-v5__result {
	grid-area: result;
	background: var(--bs360-color-result-bg);
	border: 1px solid #E1F1D0;
	border-radius: 10px;
	padding: 1.5rem 1.5rem 2.5rem;
}

/* @since 5.0.10 Auf 1.3rem angeglichen, siehe .bs360-ecp-v5__heading. */
.bs360-ecp-v5__result-heading {
	margin: 0 0 1rem;
	font-size: 1.3rem;
	color: var(--bs360-color-heading);
	font-weight: 600;
}

/* Admin-editierbarer Einleitungstext (4.0.19), direkt nach der
   Ueberschrift. Wird per JS befuellt (siehe updateResultIntro()) und
   bleibt leer/unsichtbar, solange kein Text im Backend hinterlegt ist -
   kein zusaetzlicher Leerraum ohne Inhalt.
   @since 5.0.14 Zusaetzlich per is-hidden gesteuert (siehe
   updateResultVisibility() in calculator.js): erscheint jetzt nur noch
   auf Step 4 zusammen mit den echten Zahlen, vorher durchgaengig ab
   Step 1 sichtbar. */
.bs360-ecp-v5__result-intro {
	margin: 0 0 1rem;
	color: var(--bs360-color-text);
}

.bs360-ecp-v5__result-intro:empty {
	display: none;
}

.bs360-ecp-v5__result-intro p {
	margin: 0 0 0.5rem;
}

.bs360-ecp-v5__result-intro p:last-child {
	margin-bottom: 0;
}

/* @since 5.0.24 data-step-hint-wrap: Positionierungs-Rahmen für den
   Hinweistext UND die dahinterliegende Mustervorschau (siehe
   .bs360-ecp-v5__result-sample unten). Nur Desktop (explizite
   Anweisung: auf Mobile würde die Mustervorschau bei jedem Step zu viel
   Platz wegnehmen) - auf Mobile bleibt der Hinweistext im normalen
   Fluss, ohne Wrapper-Höhe und ohne Muster dahinter.
   @since 5.0.28 Positionierung umgedreht (Fix: das Muster brach bei
   knapper Breite über die grüne Box hinaus aus): vorher lag das MUSTER
   per position:absolute + inset:0 über einer geschätzten fixen
   min-height des Wrappers - reichte die tatsächliche Musterhöhe nicht in
   diese geschätzte Höhe, brach der Inhalt sichtbar aus dem Wrapper aus.
   Nicht sinnvoll, da hier gar keine absolute Positionierung nötig ist:
   das Muster steht jetzt normal im Dokumentenfluss (bestimmt die Höhe
   des Wrappers automatisch, egal wie viel Platz sein Inhalt tatsächlich
   braucht) und nur der viel kleinere, immer gleich hohe Hinweistext wird
   per position:absolute + inset:0 mittig darüber gelegt. Kein Höhen-
   Raten mehr nötig, kein Ausbrechen möglich. display:flex zentriert hier
   am WRAPPER (nicht mehr am Hinweistext-Element selbst, siehe dortiger
   Kommentar) - der Wrapper selbst bleibt normal im Fluss (er hat keine
   position:absolute), display:flex hier steuert nur, wie sein
   position:absolute-Kind (der Hinweistext) sich innerhalb des durch
   inset:0 aufgespannten Raums ausrichtet. */
@media (min-width: 768px) {
	.bs360-ecp-v5__result-hint-wrap {
		position: relative;
		display: flex;
		align-items: center;
		justify-content: center;
	}
}

/* Rein statische, fest codierte Kopie der Ergebnisbox-Werte (siehe
   render_step1()/render_step2()/render_step3() für das identische
   Markup ohne die data-Attribute der echten, live berechneten Werte) -
   soll dem Besucher nur eine grobe Vorstellung geben, was am Ende
   erscheint, ändert sich selbst aber nie. 75% transparent (opacity:
   0.25) und weich geblurrt (filter: blur), damit sie klar als
   Andeutung statt als echtes Ergebnis erkennbar bleibt und den
   darüberliegenden Hinweistext nicht in den Hintergrund drängt. Nur
   auf Desktop im DOM sichtbar positioniert - siehe
   .bs360-ecp-v5__result-hint-wrap oben, dort steht auch die Begründung
   für "nur Desktop".
   @since 5.0.27 Fix: display: none als expliziter Basis-/Mobile-Wert
   ergänzt - ohne eigene Basis-Regel hatte das Element auf Mobile gar
   keine display-Vorgabe und rendert dort als normales Block-Element im
   Textfluss (sichtbar, mit voller Höhe), statt wie beabsichtigt
   komplett zu verschwinden.
   @since 5.0.28 Kein position: absolute mehr (siehe Kommentar am
   Wrapper oben für die ausführliche Begründung) - steht jetzt normal im
   Fluss und bestimmt damit selbst die nötige Höhe. */
.bs360-ecp-v5__result-sample {
	display: none;
}

@media (min-width: 768px) {
	.bs360-ecp-v5__result-sample {
		display: block;
		opacity: 0.15;
		filter: blur(3px);
		pointer-events: none;
		user-select: none;
	}
}

/* Since 5.0.0: ersetzt .bs360-ecp-v5__result-placeholder. Ein einziger,
   pro Step editierbarer Hinweistext (Steps 1-3), calculator.js schaltet
   zwischen der "offen"- und "bereit"-Variante um (siehe
   updateStepHint()). Auf Step 4 bleibt dieses Element leer und damit
   unsichtbar (:empty), dort erscheint stattdessen .__result-details.
   @since 5.0.8 Größer, kursiv, in --bs360-color-primary (statt gedeckter
   --bs360-color-muted) - Hinweistext ist jetzt die alleinige Hinweis-
   funktion in der Vorschaubox (die Kontextboxen der Steps entfielen),
   soll also deutlich als das zentrale, handlungsauffordernde Element
   wahrgenommen werden statt als beiläufige graue Randnotiz.
   @since 5.0.24 z-index: 1 ergänzt (nur wirksam ab Desktop, da erst dort
   die Mustervorschau dahinterliegt, siehe .bs360-ecp-v5__result-sample
   oben) - stellt sicher, dass der Text klar lesbar über dem geblurrten
   Muster liegt.
   @since 5.0.28 position:absolute (ohne top/left/right/bottom) auf
   Desktop ergänzt, damit der Hinweistext über dem im Fluss stehenden
   Muster liegt (siehe .bs360-ecp-v5__result-hint-wrap für die volle
   Begründung der neuen Positionierungslogik). Ohne top/left/right/
   bottom behält das Element seine natürliche, intrinsische Größe (statt
   sich zu strecken) und wird trotzdem vom Flex-Wrapper zentriert -
   absolut positionierte Flex-Kinder werden weiterhin von align-items/
   justify-content ihres Flex-Containers ausgerichtet, solange kein
   Offset gesetzt ist (Standardverhalten). Wichtig für den
   Schimmer-Effekt weiter unten: sein ::after mit width/height:100%
   bezieht sich dadurch nur auf die tatsächliche Textzeile dieses
   Elements, nicht auf die volle Musterhöhe - eine frühere Zwischen-
   version hatte den Text über display:flex auf die volle Höhe gestreckt,
   wodurch der Schimmer-Streifen ungewollt über die komplette
   Musterhöhe statt nur über die Textzeile lief. */
.bs360-ecp-v5__result-hint {
	margin: 0;
	font-size: 20px;
	font-style: italic;
	color: var(--bs360-color-primary);
	position: relative;
	z-index: 1;
	overflow: hidden;
	text-align: center;
}

@media (min-width: 768px) {
	.bs360-ecp-v5__result-hint {
		position: absolute;
		/* @since 5.0.25 Padding links/rechts, damit der Text nicht bis an
		   den Rand des geblurrten Musters heranreicht. */
		padding: 0 1.25rem;
	}
}

.bs360-ecp-v5__result-hint:empty {
	display: none;
}

/* Einmaliger Schimmer-Effekt, gleiche Art von Overlay-Mechanik wie zuvor
   bei .bs360-ecp-v5__progress-fill::after (Gradient-Overlay, per
   translateX über die Fläche geführt, seit 5.0.21 dort entfernt), aber
   bewusst mit eigener Keyframe-Regel statt einer geteilten Regel - beide
   Effekte sollten unabhängig voneinander bleiben. Läuft bei jedem
   Hinweistext-Wechsel (auch beim ersten Erscheinen) genau einmal über
   den Text und stoppt dann (animation-iteration-count: 1, kein
   infinite). calculator.js entfernt und setzt die Klasse is-shimmering
   bei jedem updateStepHint()-Aufruf neu (siehe dort) - erneutes
   Hinzufügen derselben Klasse würde die Animation sonst nicht neu
   starten, da der Browser keine Zustandsänderung erkennt. */
.bs360-ecp-v5__result-hint.is-shimmering::after {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: linear-gradient(115deg, transparent 0%, rgba(255, 255, 255, 0.55) 50%, transparent 100%);
	transform: translateX(-100%);
	animation: bs360-ecp-v5-hint-shimmer 0.9s ease-in-out 1;
}

@keyframes bs360-ecp-v5-hint-shimmer {
	from { transform: translateX(-100%); }
	to   { transform: translateX(200%); }
}

@media (prefers-reduced-motion: reduce) {
	.bs360-ecp-v5__result-hint.is-shimmering::after {
		animation: none;
	}
}

.bs360-ecp-v5__result-metrics {
	margin: 0 0 1.25rem;
}

.bs360-ecp-v5__result-metric {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 1rem;
	padding: 0.4rem 0;
	border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

.bs360-ecp-v5__result-metric dt {
	display: flex;
	align-items: center;
	gap: 0.4rem;
	flex: 0 0 auto;
	/* line-height:1 statt geerbtem Wert (4.0.21): SVGs sind
	   Inline-Elemente mit eigenem Baseline-Verhalten, das auch in einem
	   Flex-Container leicht zu einem 1-2px-Versatz gegenueber Text
	   fuehren kann, selbst mit align-items:center. line-height:1 auf dt
	   UND dd sorgt dafuer, dass beide Zeilenboxen exakt gleich hoch sind
	   und nicht durch geerbte, ggf. abweichende line-height-Werte
	   optisch verschoben wirken. */
	line-height: 1;
	color: var(--bs360-color-muted);
}

.bs360-ecp-v5__result-icon {
	flex-shrink: 0;
	width: 18px;
	height: 18px;
	/* display:block entfernt die SVG-Standard-Baseline-Ausrichtung
	   (Inline-Element), die sonst einen minimalen vertikalen Versatz
	   gegenueber dem Label-Text verursachen kann (4.0.21). */
	display: block;
}

.bs360-ecp-v5__result-value {
	flex: 1 1 auto;
	line-height: 1;
	text-align: right;
	font-weight: 700;
}

/* Since 5.0.0: Trennzeichen zwischen dem ersten (lesbaren) und dem
   zweiten (geblurrten) Wert einer Zeile - eigenes Element statt reinem
   Text, damit es vom :empty-Selektor auf .__result-value nicht
   mitgezaehlt werden muss und nicht versehentlich mitgeblurrt wird. */
.bs360-ecp-v5__result-value-sep {
	color: var(--bs360-color-muted);
	font-weight: 400;
}

/* Since 5.0.0: ersetzt die Wort-Skala aus dem urspruenglichen Konzept
   (Punkte 4/4a/9/10) - stattdessen bleiben die echten Zahlen stehen, nur
   der zweite (hoehere, "bessere") Wert wird per CSS unkenntlich gemacht,
   um einen Anreiz zu setzen, das Kontaktformular fuer die genaue Zahl
   abzuschicken. blur(6px) ist bewusst so gewaehlt, dass die Ziffern-
   ANZAHL (also die Groessenordnung, z.B. "das ist eine sechsstellige
   Zahl") noch grob erkennbar bleibt, einzelne Ziffern aber nicht mehr
   lesbar sind - ein staerkerer Blur wuerde auch die Zeichenbreite
   verwischen, ein schwaecherer liesse Ziffern noch erahnen. Nur eine
   CSS-Eigenschaft: der tatsaechliche Zahlenwert bleibt im DOM vorhanden
   (kein Sicherheitsmechanismus, rein visuelle Massnahme).
   user-select:none verhindert nur das bequeme Markieren/Kopieren per
   Maus, nicht das Auslesen aus dem DOM selbst (z.B. per Entwicklertools -
   dagegen hilft grundsaetzlich kein rein clientseitiger Mechanismus). */
.bs360-ecp-v5__result-value--blur {
	filter: blur(6px);
	user-select: none;
	-webkit-user-select: none;
}

/* Since 5.0.0: Handlungstext unterhalb der Energieklassen-Skala, nur auf
   Step 4 sichtbar (liegt innerhalb von .__result-details, das ohnehin
   nur dort eingeblendet wird).
   @since 5.0.8 Optisch an .bs360-ecp-v5__result-hint angeglichen (Größe,
   kursiv, --bs360-color-primary statt fett/dunkel) - beide sind
   inhaltlich dieselbe Art Hinweis, nur auf unterschiedlichen Steps.
   Trennstrich zu den Energieklassen entfernt. Kein Schimmer-Effekt hier:
   der CTA-Text ist ein einzelner, statischer Backend-Text ohne "offen"/
   "bereit"-Zustandswechsel wie bei den anderen Steps, es gibt also
   keinen Wechsel, den man antriggern könnte.
   @since 5.0.12 Abstand nach oben nochmals vergrößert (2rem -> 3rem,
   explizite Anweisung: noch mehr Luft zwischen Skala und Text). */
.bs360-ecp-v5__result-cta {
	margin: 3rem 0 0;
	font-size: 20px;
	font-style: italic;
	color: var(--bs360-color-primary);
}

.bs360-ecp-v5__result-subheading {
	margin: 0 0 2.25rem;
	font-size: 1.1rem;
	font-weight: 600;
	color: var(--bs360-color-heading);
}

/* ---------- Energy class scale (EU-EPBD A-G) ---------- */

.bs360-ecp-v5__ec-scale {
	display: flex;
	gap: 2px;
	position: relative;
}

.bs360-ecp-v5__ec-seg {
	flex: 1;
	position: relative;
	padding: 0.4rem 0.2rem;
	text-align: center;
	font-weight: 700;
	color: #fff;
	font-size: 0.8rem;
}

.bs360-ecp-v5__ec-seg[data-class="A"] { background: var(--bs360-ec-a); }
.bs360-ecp-v5__ec-seg[data-class="B"] { background: var(--bs360-ec-b); }
.bs360-ecp-v5__ec-seg[data-class="C"] { background: var(--bs360-ec-c); }
.bs360-ecp-v5__ec-seg[data-class="D"] { background: var(--bs360-ec-d); }
.bs360-ecp-v5__ec-seg[data-class="E"] { background: var(--bs360-ec-e); }
.bs360-ecp-v5__ec-seg[data-class="F"] { background: var(--bs360-ec-f); }
.bs360-ecp-v5__ec-seg[data-class="G"] { background: var(--bs360-ec-g); }

/* Punkt 4: Rahmen um die aktuelle Klasse, zusaetzlich zum Pfeil-Label. */
.bs360-ecp-v5__ec-seg--current {
	outline: 3px solid var(--bs360-color-heading);
	outline-offset: -3px;
	position: relative;
	z-index: 2;
}

.bs360-ecp-v5__ec-marker {
	position: absolute;
	bottom: 100%;
	left: 50%;
	transform: translateX(-50%);
	white-space: nowrap;
	font-size: 0.7rem;
	font-weight: 600;
	color: var(--bs360-color-text);
	transition: left 0.3s ease;
}

.bs360-ecp-v5__ec-marker::after {
	/* CSS-Unicode-Escape statt rohem UTF-8-Zeichen (4.0.11): ein direkt
	   eingebettetes "▼" wurde auf mind. einer Live-Umgebung als "â–¼"
	   dargestellt - typisches Mojibake, wenn Server oder Browser die Datei
	   ohne korrekten UTF-8-Charset-Hinweis ausliefern/interpretieren. Die
	   Escape-Schreibweise (\25bc = U+25BC BLACK DOWN-POINTING TRIANGLE) ist
	   reines ASCII und dadurch unabhaengig vom tatsaechlichen Datei- oder
	   Uebertragungs-Encoding korrekt. */
	content: "\25bc";
	display: block;
	text-align: center;
}

/* Punkt 4: Potenzial als eigenständiger Balken unter der Skala statt
   einem Pfeil auf einer Klasse. Position/Breite kommen per Inline-Style
   von updateEnergyClassMarkers() in calculator.js. */
.bs360-ecp-v5__ec-potential {
	position: absolute;
	top: 100%;
	margin-top: 6px;
	text-align: center;
	transition: left 0.3s ease, width 0.3s ease;
}

.bs360-ecp-v5__ec-potential-bar {
	height: 6px;
	border-radius: 999px;
	background: var(--bs360-color-primary-contrast);
	margin-bottom: 2px;
}

.bs360-ecp-v5__ec-potential-label {
	font-size: 0.7rem;
	font-weight: 600;
	color: var(--bs360-color-primary-contrast);
	white-space: nowrap;
}

/* ---------- Price display (Step 3A/3B) ---------- */

.bs360-ecp-v5__price-display {
	font-size: 0.9rem;
	color: var(--bs360-color-muted);
	margin-top: -0.5rem;
	margin-bottom: 1.5rem;
}

/* ---------- Mobile fixed footer panel (concept 20.3) ---------- */

.bs360-ecp-v5__footer-panel {
	display: none;
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1000;
	background: var(--bs360-color-result-bg);
	border-top: 2px solid var(--bs360-color-primary);
	padding: 0.6rem 1rem env(safe-area-inset-bottom, 0px);
}

.bs360-ecp-v5__footer-panel__metrics {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 0.5rem;
	text-align: center;
	font-weight: 700;
	margin-bottom: 0.4rem;
}

.bs360-ecp-v5__footer-panel__ec {
	display: flex;
	gap: 2px;
	height: 6px;
}

.bs360-ecp-v5__footer-panel__ec-seg {
	flex: 1;
	opacity: 0.35;
}

.bs360-ecp-v5__footer-panel__ec-seg[data-class="A"] { background: var(--bs360-ec-a); }
.bs360-ecp-v5__footer-panel__ec-seg[data-class="B"] { background: var(--bs360-ec-b); }
.bs360-ecp-v5__footer-panel__ec-seg[data-class="C"] { background: var(--bs360-ec-c); }
.bs360-ecp-v5__footer-panel__ec-seg[data-class="D"] { background: var(--bs360-ec-d); }
.bs360-ecp-v5__footer-panel__ec-seg[data-class="E"] { background: var(--bs360-ec-e); }
.bs360-ecp-v5__footer-panel__ec-seg[data-class="F"] { background: var(--bs360-ec-f); }
.bs360-ecp-v5__footer-panel__ec-seg[data-class="G"] { background: var(--bs360-ec-g); }

.bs360-ecp-v5__footer-panel__ec-seg--current,
.bs360-ecp-v5__footer-panel__ec-seg--potential {
	opacity: 1;
}

@media (max-width: 767px) {
	.bs360-ecp-v5 {
		padding-bottom: var(--bs360-footer-height);
	}

	.bs360-ecp-v5__footer-panel.is-visible {
		display: block;
	}
}
