/**
 * App-Startseite — Feed-Liste statt Farbblock-Plakate (Design-Handoff 2026-08-07).
 *
 * Ziel der Spec: 5 Artikel pro Screen bei 390×844 statt einem. Die Kategoriefarben
 * bleiben vollständig, sie wandern nur von der Vollfläche in Kicker und Kantenbalken.
 */

/* ── Tokens ─────────────────────────────────────────────────────────────────
 * ⭐ SCHRIFT-BODEN 14px — ENTSCHIEDEN (Stephan 2026-08-08, Handbuch §9.2):
 * „Minimum 14px für jeden sichtbaren Text, keine Label-Ausnahme." Damit ist die
 * offene Frage aus dem Startseiten-Bau erledigt: Die Spec-Werte Meta 13px und
 * Kicker 11px sind auf 14px gehoben.
 *
 * ⚠️ EINZIGE AUSNAHME SIND NUMERISCHE BADGES — `.mb-gs__badge` („N machen mit")
 * bleibt bei 12px. Sie zeigt eine Zahl, keinen Fließtext, und ist damit von der
 * Boden-Regel ausgenommen.
 *
 * Dass das hier zwei Werte sind und keine Suche durch die Datei, ist der Grund
 * für die Tokens: Kicker und Meta hängen an SIEBEN Stellen daran, inklusive der
 * Gewinnspiel-Frist im Kartenfuß und der Beliebteste-Kicker.
 */
/* ⚠️ TOKEN-SCOPE IST `body.mb-app`, NICHT `.mb-home` — HEBUNG 1.17.0.
 *
 * Grund: Die Related-Optik im App-Artikel braucht DIESELBEN Werte, aber dort
 * existiert `.mb-home` nicht (die Fläche rendert Elementor, wir stylen nur).
 * Eine zweite Token-Tabelle wäre die Zwei-Quellen-Krankheit aus 1.16.5 —
 * also EINE Quelle, von der beide Flächen erben.
 *
 * Vor der Hebung abgearbeitet (Risikoliste aus dem tourdates-Präzedenzfall
 * 2.10.12, wo dieselbe Hebung teuer gelernt wurde):
 * (1) FALLBACK-STELLEN — beim Hebungs-Audit gezählt, Stand 2026-08-12:
 *     9 von 68 `var()`-Nutzungen tragen einen Fallback. `--mb-pill-farbe`
 *     fällt auf `var(--mb-ink)` zurück und `--mb-pill-text` auf
 *     `var(--mb-grund)` — also auf TOKENS, nicht auf Literale; die übrigen
 *     hängen an inline/`nth-child` gesetzten Werten. Stille
 *     ⚠️ DIE ZAHL IST EIN STICHTAG, KEINE INVARIANTE: Sie stand hier bis
 *     1.23.0 als „6 von 69" und war schon vor der Konzert-Änderung falsch —
 *     das CSS ist gewachsen, nachgezählt hat niemand. Wer sie zitiert, zählt
 *     vorher nach; was WIRKLICH gilt, ist der Satz dahinter (kein Fallback
 *     dupliziert ein bewegliches Token als Literal).
 *     Wert-Wechsel sind hier strukturell unmöglich, weil ALLE 40 Regelköpfe
 *     `.mb-home` tragen — es gibt keine Regel außerhalb des alten Scopes,
 *     und genau die wäre die Bedingung für den tourdates-Effekt.
 * (2) NAMENSRAUM — keiner dieser Namen ist außerhalb app-backend definiert
 *     (Theme, Kit, Fremd-Plugins geprüft; die anderen fahren `--mb-eh-*`).
 *     Ladereihenfolge damit gegenstandslos.
 *
 * ⚠️ NEUE KOPPLUNG — DOKUMENTIERT STATT SPÄTER ENTDECKT: `body.mb-app`
 * (0,1,1) sticht `:root` (0,1,0). Führt ein FREMDES Plugin künftig einen
 * gleichnamigen Token ein, bekommt es im App-Mode UNSEREN Wert aufgedrückt,
 * ohne dass jemand etwas geändert hat. Wer hier Namen ergänzt, prüft sie
 * gegen die übrigen Plugins.
 */
body.mb-app {
	--mb-fs-titel-lead: 19px;
	--mb-fs-titel: 16px;
	--mb-fs-meta: 14px;
	--mb-fs-kicker: 14px;
	--mb-fs-pill: 14px;
	--mb-fs-rang: 26px;

	--mb-grund: #FFFFFF;          /* Seitengrund — Gegenfarbe zu --mb-ink */
	--mb-ink: #222227;
	--mb-ink-sek: #55555E;
	--mb-linie: rgba(34, 34, 39, .14);
	--mb-trenner: rgba(34, 34, 39, .10);
	--mb-flaeche: #F5F5F5;
	--mb-flaeche-hover: #E9E9E9;
	--mb-violett: #C22BF7;
	/* Kit-Violett (Stephan-Entscheid 2026-08-08, ersetzt das erfundene #BC16F8). */
	--mb-alben: #A41DD2;
	--mb-orange: #E36A34;

	/* ⚠️⚠️ GRABSTEIN — HIER STAND `--mb-kachel-hoehe: 177px` (1.33.0–1.41.2).
	 *
	 * Der Token koppelte GS- und Beliebteste-Kacheln auf eine gemeinsame Höhe
	 * (Stephan 2026-08-15: „beide 177 hoch so wie beliebteste"). Beide Nutzer sind
	 * inzwischen weg, und zwar auf Stephans eigene Ansage:
	 *  · 1.40.0 — die Beliebteste-Kachel folgt ihrem Inhalt („viel leere Fläche
	 *    unten"), die Kopplung war ab da einseitig.
	 *  · 1.41.3 — die GS-Kachel ist zurück auf ihrer ursprünglichen Größe
	 *    („es war ein test"), inhaltsbestimmt statt fest.
	 *
	 * Beide Reihen sind trotzdem in sich gleich hoch — weil ihre TEILE feste
	 * Höhen haben und der Behälter folgt. Das ist dieselbe Lehre wie beim GS-Fuss
	 * (1.35.0), nur zweimal angewandt. Wer wieder eine gemeinsame Höhe braucht,
	 * misst zuerst nach, ob er wirklich den Behälter meint. */

	/* ⚠️⚠️ DER GS-FUSS IST FEST — UND ZWAR GERECHNET, NICHT GERATEN.
	 * Stephan 2026-08-15 nach dem 1.33.0-Gerätetest: „die Boxen sollen
	 * natürlich immer gleich aussehen, FOTOTEIL IMMER GLEICH". In 1.33.0 nahm
	 * der Fuß sich, was sein Inhalt brauchte — ein 2-zeiliger Titel (Poliça)
	 * ergab ein großes Bild, ein 3-zeiliger (Love Spells) ein kleines. Genau
	 * die Tabelle aus dem 1.33.0-CHANGELOG, nur als sichtbares Symptom.
	 *
	 * ⚠️ WARUM DER FUSS FIXIERT WIRD UND NICHT DAS BILD: Eine gerechnete
	 * Bildhöhe wäre eine zweite Zahl, die bei jeder Schrift-/Polster-Änderung
	 * still falsch würde (der 1.33.0-Einwand gilt unverändert). Fixiert ist
	 * deshalb der Fuß — aus DENSELBEN Token, die seine Bestandteile stellen —
	 * und das Bild nimmt weiterhin einfach den Rest. Weil der Fuß jetzt
	 * konstant ist, ist es das Bild automatisch mit. Eine Quelle, keine
	 * Handrechnung: Ändert sich `--mb-fs-titel`, ändert sich der Fuß mit.
	 *
	 * ⚠️ DIE ZEILENHÖHEN SIND HIER TOKEN, WEIL SIE SONST GERATEN WÄREN: Die
	 * Frist hatte bis 1.33.0 GAR KEINE eigene `line-height` und erbte vom
	 * Theme — meine 1,4 in der 1.33.0-Tabelle war eine ANNAHME, die zufällig
	 * zur Live-Messung passte. Jetzt setzen dieselben Werte die Regel UND die
	 * Rechnung, damit „zufällig richtig" nicht wieder passieren kann.
	 *
	 * Ergibt: 11 + 13 + 14×1,4 + 3 + 16×1,3×3 = 109px Fuß. */
	/* ⚠️ EINE ZEILENZAHL FÜR ALLE LISTEN-TITEL (1.36.0 Zeilen → 1.38.0 auch
	 * Beliebteste und Charts). Hiess bis 1.37.0 `--mb-row-titel-zeilen`; der
	 * Name log, sobald ihn drei Bauteile teilen. Wer sie ändert, ändert alle
	 * drei — genau das ist der Zweck (Stephan: „in jedem View konsistent").
	 *
	 * ⚠️ SEIT 1.39.0 GILT SIE AUCH FÜR DEN AUFMACHER (Stephan-Entscheid). Nicht
	 * betroffen bleiben allein die GS-Kacheln — deren 3 Zeilen sind ein eigener
	 * Entscheid mit eigenem Token. */
	--mb-listen-titel-zeilen: 2;

	/* Zeilenhöhen je Bauteil — die Titel sind verschieden gesetzt, deshalb je
	 * ein eigener Wert; geteilt wird die ZEILENZAHL, nicht die Zeilenhöhe. */
	--mb-row-titel-lh: 1.32;
	--mb-pop-titel-lh: 1.32;
	--mb-chart-titel-lh: 1.3;
	--mb-lead-titel-lh: 1.28;

	--mb-gs-fuss-oben: 11px;
	--mb-gs-fuss-unten: 13px;
	--mb-gs-frist-lh: 1.4;
	--mb-gs-frist-abstand: 3px;
	--mb-gs-titel-lh: 1.3;
	--mb-gs-titel-zeilen: 3;
	--mb-gs-fuss-hoehe: calc(
		var(--mb-gs-fuss-oben) + var(--mb-gs-fuss-unten)
		+ var(--mb-fs-kicker) * var(--mb-gs-frist-lh)
		+ var(--mb-gs-frist-abstand)
		+ var(--mb-fs-titel) * var(--mb-gs-titel-lh) * var(--mb-gs-titel-zeilen)
	);
}

/* NUR die Tokens sind gewandert. Diese Deklarationen beschreiben das
 * Startseiten-Bauteil selbst und bleiben deshalb auf `.mb-home` — sie dürfen
 * NICHT für jede App-Seite gelten (`margin/padding: 0` auf dem Artikel-Body
 * wäre ein Durchgriff in fremdes Layout). */
.mb-home {
	margin: 0;
	padding: 0;
	color: var(--mb-ink);
	font-weight: 300;
	-webkit-font-smoothing: antialiased;
}

/* ⚠️⚠️ 12px LUFT ÜBER DEM AUFMACHER DER LISTENSEITEN (1.71.6, Stephan-Entscheid
 * 23.09., wörtlich: „Überall gleicher Abstand nach oben bitte").
 *
 * Rubrik-Archive, Musikstil-Seiten und Suche (`app-list.php`) begannen mit dem
 * randlosen Aufmacher-Bild direkt unter dem App-Kopf (0px), die Startseite dagegen
 * mit der Rubrik-Leiste bei 12px. Jetzt beginnt jede App-Seite 12px unter dem Kopf.
 * Der Aufmacher bleibt in der BREITE randlos — nur oben kommt Luft dazu.
 *
 * ⚠️ WARUM `main.`: Dieselbe Klassenkombination `mb-home mb-liste` tragen auch zwei
 * DIV-Hüllen — die Artikelliste unter Künstler-/Label-Seiten (`mb-term`) und „Das
 * könnte dir auch gefallen" unter Artikeln (`mb-related`). Die stehen mitten in einer
 * Seite und dürfen KEINE Kopf-Luft bekommen. Nur `app-list.php` rendert die Hülle als
 * `<main>`. Gemessen (Live, 390): Album, News, Musikstil, Suche 0 → 12; Startseite 12
 * unverändert; die beiden DIV-Listen unverändert (791 bzw. 9838).
 */
main.mb-home.mb-liste {
	padding-top: 12px;
}

/* ⛔⛔ GRABSTEIN — HIER STAND DIE ENTFÄRBUNG (§6). ZWEI ENTSCHEIDE, BEIDE VON
 * STEPHAN, BEIDE MIT DATUM:
 *
 *   · 2026-08-12: „Bilder DURCHGÄNGIG entfärbt — die Farbe kommt aus den
 *     Kategoriewerten, nicht aus den Fotos." Regel war `.mb-home img { filter:
 *     grayscale(1) contrast(1.05) }`, mit EINER Ausnahme: der Aufmacher blieb
 *     farbig (`.mb-home .mb-lead__img { filter: none }`), weil die App keinen
 *     Hover hat und er ihr Farb-Moment war.
 *   · 2026-09-22: „nicht nur die startseite — JEDER artikel list view, auch die
 *     archive." Damit sind in der App ALLE Vorschaubilder farbig; die
 *     Aufmacher-Ausnahme ist gegenstandslos geworden und mit entfernt. Die
 *     Begründung von 08-12 (Kicker-Codierung schlägt Pressefoto) gilt für die
 *     App nicht mehr.
 *
 * ⚠️ WER HIER EINE „VERGESSENE" REGEL VERMISST: Sie ist nicht vergessen, sie ist
 * abgeräumt. Wer sie zurückholen will, braucht einen neuen Stephan-Entscheid.
 *
 * ⚠️ WEB BLEIBT SCHWARZWEISS — und zwar ohne unser Zutun: Im Web greift eine
 * ELEMENTOR-Element-Regel aus der Datenbank
 * (`.elementor-169349 .elementor-element.elementor-element-2bab915 img {
 * filter: grayscale(100%) }`), und diese Datei lädt dort gar nicht. Am
 * 22.09.2026 an Rubrik-Archiv, Künstler-Archiv und Artikel gemessen: Web
 * unverändert `grayscale(1)`, App `none`. Wer die App-Bilder wieder entfärben
 * will, fasst NICHT die Elementor-Regel an — die gehört dem Web.
 *
 * ⚠️ WARUM HIER KEINE `body.mb-app`-REGEL FÜR ELEMENTOR-FLÄCHEN STEHT: Das
 * Inventar vom 22.09. hat JEDE Listen-Fläche der App gemessen (Start-Feed,
 * Rubrik, Schlagwort, Künstler, Label, Location, Datum, Suche, Verwandte) —
 * alle laufen über `.mb-home` aus unseren Templates, KEINE über ein
 * Elementor-Loop-Grid. Der App-Mode ersetzt die Archive durch `app-list.php`.
 * Ein vorsorglicher Override wäre eine Regel ohne Gegenstand gewesen.
 *
 * `display: block` war Teil derselben Regel und wird weiterhin gebraucht —
 * es steht jetzt allein. */
.mb-home img {
	display: block;
}

/* ── Rubrik-Pills (§3.1) ───────────────────────────────────────────────────
 * ⚠️ EINE PILLE DARF NIE WIE EINE FREMDE KATEGORIE AUSSEHEN. Das ist die Regel,
 * die hier drei Fassungen ueberlebt hat — der Weg dahin steht bewusst mit:
 *   1.16.8 und frueher: JEDE aktive Pille trug #C22BF7. Auf dem Videos-Filter
 *     also der ALBEN-Ton — die Pille log ueber ihren eigenen Inhalt.
 *   1.16.9: Aktive Rubrik-Pillen tragen ihre EIGENE Rubrikfarbe. Bleibt so.
 *   1.24.0: „Alle" hat keine Rubrik und fiel deshalb weiter auf #C22BF7 zurueck
 *     — und #C22BF7 liegt neben Alben #A41DD2 und Video #810DAB. Stephan
 *     2026-08-12: „sollte wahrscheinlich nicht magenta sein, das ist ja die
 *     Farbe für die Alben Kategorie". Richtig: „Alle" IST keine Kategorie, also
 *     traegt es auch keine Kategoriefarbe, sondern Tinte.
 * Wer hier eine Farbe aendert, prueft sie gegen ALLE Werte in `FARBEN` — die
 * Kollision entsteht nicht an der Pille, sondern zwischen Pille und Rubrik. */
.mb-home__pills {
	display: flex;
	gap: 8px;
	overflow-x: auto;
	padding: 12px 16px;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}
.mb-home__pills::-webkit-scrollbar { display: none; }

/* ⚠️ HARTER RESET, UND ZWAR MIT ABSICHT: Ein <button> erbt die Button-Regeln des
 * Child-Themes — dort sind Buttons magenta gefüllt (bekannte Stelle, siehe die
 * Konto-Buttons). Ohne Zurücksetzen sahen ALLE Pills aktiv aus und der gewählte
 * Zustand war nicht unterscheidbar (Stephan-Gerätetest 2026-08-07). Die
 * Deklarationen stehen deshalb vollständig und nicht als Ergänzung. */
.mb-home .mb-pill {
	flex: 0 0 auto;
	appearance: none;
	-webkit-appearance: none;
	box-shadow: none;
	text-transform: none;
	min-height: 0;
	margin: 0;
	padding: 7px 15px;
	border: 1px solid rgba(34, 34, 39, .24);
	border-radius: 999px; /* dokumentierte Ausnahme von der 3px-Regel */
	background: transparent;
	color: var(--mb-ink);
	font: inherit;
	font-size: var(--mb-fs-pill);
	font-weight: 300;
	line-height: 1.2;
	cursor: pointer;
}
/* ⚠️ DER ALTE 4,21:1-KASTEN IST HIER WEG — UND ZWAR NICHT AUS NACHLAESSIGKEIT.
 * Bis 1.23.0 stand an dieser Stelle, „Alle" liege mit weiss auf #C22BF7 bei
 * 4,21:1 und das sei per Stephan-Entscheid A vom 2026-08-10 („Marke gewinnt",
 * Handbuch §5a-Aktiv-Ausnahme) so gewollt. Dieser Entscheid ist mit dem
 * Farbwechsel GEGENSTANDSLOS geworden, nicht aufgehoben: Er rechtfertigte eine
 * Marken-FLAECHE unter AA — „Alle" traegt jetzt gar keine Markenfarbe mehr.
 * Gemessen nach dem Wechsel: weiss auf --mb-ink #222227 = 15,84:1 (hell),
 * #2C2C31 auf #F5F5F7 = 12,76:1 (dunkel). Die Ausnahme wird hier also nicht
 * mehr GEBRAUCHT.
 * ⚠️ Sie gilt weiter fuer andere Aktiv-Flaechen — wer sie dort streichen will,
 * braucht einen neuen Stephan-Entscheid, nicht diesen Kommentar.
 *
 * ⚠️ RUBRIK-PILLEN BLEIBEN BEI IHRER FARBE (1.16.9) und liegen zwischen 5,70:1
 * und 8,14:1 — ein Kontrast-Sweep findet hier nichts mehr zu melden.
 *
 * ⚠️ UND NICHT VERWECHSELN: Unsere Text-Akzente (`#810DAB` hell, `#D98BF5` dunkel)
 * fallen nicht unter die Ausnahme — dort bleibt AA hart. */
.mb-home .mb-pill.is-active {
	/* Rubrik-Farbe, sonst Tinte („Alle" hat keine Rubrik) — siehe Template.
	 * ⚠️ BEIDE Eigenschaften kommen als Paar aus dem Template: Wer nur
	 * `--mb-pill-farbe` setzt, bekommt im DUNKLEN schwarze Schrift auf der
	 * Rubrikfarbe, weil der Textwert dann auf den Grund zurueckfaellt. */
	background: var(--mb-pill-farbe, var(--mb-ink));
	border-color: var(--mb-pill-farbe, var(--mb-ink));
	color: var(--mb-pill-text, var(--mb-grund));
	font-weight: 400;
}
/* ⚠️ GEDRUECKT WIRD NICHT UMGEFAERBT, SONDERN ABGESENKT. Bis 1.23.0 sprang JEDE
 * aktive Pille beim Druecken auf `--mb-violett-tief` — auch die gruene
 * Konzert-Pille wurde beim Antippen kurz violett. Das war dieselbe Kollision
 * wie Stephans Fund, nur eine Interaktion spaeter und deshalb nie gemeldet.
 * Deckkraft statt Ersatzfarbe funktioniert fuer JEDEN Pillenton — auch fuer
 * jeden, den erst eine kuenftige Rubrik mitbringt. */
.mb-home .mb-pill.is-active:active { opacity: .82; }

/* ⚠️⚠️ FREMD-HOVER NEUTRALISIEREN (1.41.2, Stephan-Gerätefund 2026-08-18):
 * Nach dem Rubrik-Reset blieb die zuvor getippte Pille optisch gefüllt neben
 * der aktiven „Alle"-Pille — klebender Touch-Hover aus fremdem CSS, das
 * KEINEN `@media (hover: hover)`-Riegel trägt (unserer schon, siehe unten).
 *
 * ⚠️ WARUM DIESE REGEL DEN ZUSTAND FESTHÄLT STATT EINE BESTIMMTE FREMDREGEL ZU
 * KONTERN: Ich habe alle **31** auf der Seite eingebundenen Stylesheets nach
 * der gemeldeten Farbe und nach Button-Hover-Regeln durchsucht. Gefunden habe
 * ich nur ein nacktes `button:hover{background-color:#c36}` — und das kann es
 * nicht sein: Unsere Ruhe-Regel `.mb-home .mb-pill` ist **(0,2,0)** und setzt
 * `background: transparent`, das nackte `button:hover` nur **(0,1,1)**.
 * Die gemeldete Farbe stammt also aus einer Regel, die ich von aussen nicht
 * lokalisieren konnte. Eine Regel gegen einen Selektor zu schreiben, den man
 * nicht kennt, wäre geraten; diese hier hält stattdessen fest, was in Ruhe
 * gelten SOLL — unabhängig davon, wer dagegenhält.
 *
 * ⚠️ SIE STEHT VOR dem `@media (hover: hover)`-Block, nicht danach: Bei
 * gleicher Spezifität gewinnt die spätere Regel. So behält der echte Zeiger
 * seinen Hover, und nur Touch fällt auf die Ruhe-Optik zurück.
 *
 * ⚠️ `:not(.is-active)` ist die Negativkontrolle im Code: Die WIRKLICH aktive
 * Pille behält ihre Rubrik-Farbe. Ohne diese Ausnahme löschte der Riegel genau
 * die Hervorhebung, um deren Echtheit es geht. */
.mb-home .mb-pill:hover:not(.is-active),
.mb-home .mb-pill:focus:not(.is-active):not(:focus-visible) {
	background: transparent;
	color: var(--mb-ink);
}

.mb-home .mb-pill.is-active:hover,
.mb-home .mb-pill.is-active:focus:not(:focus-visible) {
	background: var(--mb-pill-farbe, var(--mb-ink));
	color: var(--mb-pill-text, var(--mb-grund));
}

/* ⚠️ STICKY-HOVER-KANON (tourdates 2.7.18): Hover NUR mit echtem Zeiger. Auf
 * Touch bleibt ein :hover nach dem Tippen kleben — die zuletzt berührte Pille
 * sähe dauerhaft aus wie ausgewählt, obwohl sie es nicht ist. */
@media (hover: hover) {
	/* ⚠️ GLEICHE SELEKTOR-FORM WIE DER RIEGEL OBEN — SONST GEWINNT DER RIEGEL AUCH
	 * HIER. Am Messstand belegt: Mit `.mb-home .mb-pill:hover` (0,3,0) gegen den
	 * Riegel (0,4,0) blieb die Pille unter dem echten Zeiger transparent — die
	 * Fremdregel war zwar geschlagen, unsere eigene Rückmeldung aber auch. Bei
	 * gleicher Spezifität entscheidet die Reihenfolge, und dieser Block steht
	 * später. */
	.mb-home .mb-pill:hover:not(.is-active) { background: var(--mb-flaeche-hover); }
	.mb-home .mb-pill.is-active:hover { opacity: .9; }
}
/* Der Fokus-Ring steht BEWUSST außerhalb der hover-Abfrage — Tastatur- und
 * Screenreader-Bedienung darf nicht am Eingabegerät hängen. */
.mb-home .mb-pill:focus-visible {
	outline: none;
	box-shadow: 0 0 0 3px rgba(194, 43, 247, .55);
}

/* ── Aufmacher (§3.2) ──────────────────────────────────────────────────────
 * ⚠️ Der Farbblock ist INHALTSBESTIMMT hoch, nicht auf feste Höhe gestreckt —
 * genau das war der Kernfehler im Ist-Zustand (Meta-Balken ~300px für Datum
 * und Autor). */
.mb-home .mb-lead__link,
.mb-home .mb-row__link,
.mb-home .mb-gs__link,
.mb-home .mb-pop__link,
.mb-home .mb-chart__link { display: block; text-decoration: none; color: inherit; }

/* ⚠️⚠️ DRITTES KAPITEL DERSELBEN FRAGE — UND DAS ERSTE, DAS DIE WURZEL TRIFFT.
 * Wer hier etwas ändern will, liest zuerst alle drei; sonst dreht die nächste
 * Runde wieder an der Formel statt an der Box.
 *
 *  1. **1.27.0** — Hochformate bekamen einen berechneten `object-position`-Wert
 *     („keine Köpfe abschneiden", Love Spells zeigte Torso statt Kopf).
 *  2. **1.30.0** — für den Hero zurückgenommen: Angus & Julia (1200×1800, Meer
 *     und Himmel oben, Personen unten) — die Regel schob das Fenster nach oben
 *     und zeigte fast nur Himmel.
 *  3. **1.32.0 (hier)** — die Box selbst ist quadratisch. An EINEM Tag hatte
 *     jeder Pol seinen Beleg: Angus & Julia (Motiv unten) gegen Grace Cummings
 *     (Kopf oben, 1200×1800) — beide `a = 0,667`, entgegengesetzte Komposition,
 *     keine Schwelle trennt sie. Genau das ist der Beweis, dass die FORMEL das
 *     Problem nicht lösen KANN: Sie kennt nur Maße, und die sind identisch.
 *
 * ⚠️ STEPHANS EINSICHT, wörtlich: „Warum machst du das Bild nicht quadratisch
 * wie im Web? Dort funktioniert es ja gerade deswegen." Er hat recht, und es
 * ist nachrechenbar — sichtbar ist immer `a / R` der Bildhöhe:
 *
 *   | Box                     |   R   | sichtbar | Verlust oben |
 *   |-------------------------|-------|----------|--------------|
 *   | 375×180 (bisher)        | 2,083 |   32,0 % |     34,0 %   |
 *   | **Quadrat (Web-Kachel)**| 1,000 | **66,7 %**|  **16,7 %** |
 *
 * Ein Kopf liegt in einem Porträt praktisch nie in den obersten 16,7 % — das
 * ist Kopfraum/Himmel. In den obersten 34 % liegt er ständig. Deshalb löst die
 * Box, was keine Formel löste; die Website beweist es täglich an denselben
 * Fotos. An beiden Prüfstein-Bildern belegt (Sichtbeleg 2026-08-15): Grace'
 * Kopf liegt vollständig im Quadrat, Angus & Julia ebenso.
 *
 * ⚠️ ZENTRIERUNG BLEIBT — und zwar OHNE `object-position`. Das Quadrat braucht
 * keinen Versatz; ein Wert hier würde den 1.30.0-Entscheid still zurückdrehen.
 *
 * ⚠️ DER PREIS, bewusst abgenommen: Der Aufmacher wächst von 180px auf die
 * Viewport-Breite (bei 390px Gerätebreite also +210px). Im ersten Screen ist
 * entsprechend weniger Feed sichtbar — das ist die Gegenrechnung zur
 * 5-Artikel-Regel des Design-Handoffs, und sie ist gewollt.
 *
 * ⚠️ NICHT BETROFFEN: die Zeilen-Thumbs. Deren Box ist 1,33:1, zeigt 50 % der
 * Bildhöhe, und dort bleibt die milde Kopfraum-Regel (`bildPositionZeile()`)
 * unverändert in Kraft. */
.mb-home .mb-lead__img { width: 100%; aspect-ratio: 1 / 1; height: auto; object-fit: cover; }
.mb-home .mb-lead__block { padding: 13px 16px 15px; color: #fff; }
.mb-home .mb-lead__kicker {
	display: block;
	font-size: var(--mb-fs-kicker);
	font-weight: 600;
	letter-spacing: .14em;
	text-transform: uppercase;
	opacity: .92;
}
/* ⚠️ WEISS AUF DEM VOLLTON — Titel UND Meta (Stephan-Gerätetest 2026-08-07:
 * „Bitte weiße Schrift in der Kachel so wie auf der Website").
 * Der Block erbte die Textfarbe des Dokuments und stand deshalb SCHWARZ auf
 * dem Vollton. Spec §2 ist eindeutig: „Der Vollton ist für farbige Flächen MIT
 * WEISSEM TEXT gedacht" — die Website-Kacheln sind die lebende Referenz.
 *
 * ⚠️ UND DIE SPEZIFITÄT IST ABSICHT: `.mb-lead__title` allein reichte nicht. Der
 * Titel ist ein <h2>, und der Elementor-Kit setzt `.elementor-kit-119134 h2`
 * (am gerenderten Dokument gemessen, nicht vermutet). Mit `.mb-home` davor
 * gewinnt unsere Regel.
 */
/* ⚠️ ZWEI ZEILEN AUCH HIER (Stephan-Entscheid 2026-08-15, nach Erklärung der
 * Folgen): Der Aufmacher war das letzte Bauteil ohne Deckel — der Sweep mass
 * beim 162-Zeichen-Titel einen Farbblock von 95,3px auf 192,6px, also fünf
 * Titelzeilen im ersten Screen.
 *
 * ⚠️ HIER WIRD NICHT RESERVIERT, ANDERS ALS BEI ZEILEN UND KACHELN — und das
 * ist kein Vergessen: Dort sichert die Reservierung, dass NEBENEINANDER
 * stehende Geschwister gleich hoch sind. Der Aufmacher hat keine Geschwister;
 * ein kurzer Titel darf seinen Block kompakt lassen, statt künstlich Luft zu
 * tragen. Deckel gegen Ausreißer ja, Zwangshöhe nein. */
.mb-home .mb-lead__title {
	display: -webkit-box;
	-webkit-line-clamp: var(--mb-listen-titel-zeilen);
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin: 4px 0 0;
	color: #fff;
	font-size: var(--mb-fs-titel-lead);
	font-weight: 400;
	line-height: var(--mb-lead-titel-lh);
}
/* Aufmacher: dieselbe Einzeiler-Regel — die Meta stammt aus derselben Variablen,
 * und zwei Verhaltensweisen für denselben Text wären genau die Inkonsistenz,
 * um die es hier geht. */
.mb-home .mb-lead__meta {
	display: block;
	margin-top: 6px;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	color: #fff;
	font-size: var(--mb-fs-meta);
	font-weight: 300;
	opacity: .85;
}

/* ── Kompakte Artikelzeilen (§3.3) ─────────────────────────────────────────
 * Dieselbe Komponente wie der Aufmacher, andere Variante: Kantenbalken statt
 * Farbblock. Sie trägt den ganzen Feed. */
.mb-home .mb-row + .mb-row,
.mb-home .mb-lead + .mb-row { border-top: 1px solid var(--mb-trenner); }

.mb-home .mb-row__link { display: flex; gap: 12px; align-items: flex-start; padding: 13px 16px; min-height: 105px; box-sizing: border-box; }
/* ⚠️ JEDE REGEL DIESER KOMPONENTE TRÄGT `.mb-home` — und das ist kein Stil-Tick
 * (1.16.10). Auf Term-Seiten wird unser Markup IN EIN ELEMENTOR-WIDGET injiziert
 * (`…__figure` → `.elementor-widget-container` → `.elementor-widget-loop-grid`).
 * Dort greifen Elementor-Bildregeln, die auf der eigenen Startseite NIE zuschlagen.
 *
 * Ein Partial, zwei STIL-KONTEXTE — nicht zwei Render-Pfade. Gemessen: Auf der
 * Startseite berechnete sich `.mb-row__img` (0,1,0) zu 78px, auf der Term-Seite zu
 * 76,27px = 104 × 440/600, also aus dem Seitenverhältnis. Der Kantenbalken lief
 * weiter auf volle Kastenhöhe — genau der Versatz, den Stephan gesehen hat.
 *
 * Deshalb sind ALLE 40 Regelköpfe präfixiert, nicht nur das Bild: Wer nur die
 * gemeldete Regel härtet, wartet auf den nächsten Kontext-Durchgriff. */
.mb-home .mb-row__figure { position: relative; flex: 0 0 104px; width: 104px; height: 78px; border-radius: 3px; overflow: hidden; }
.mb-home .mb-row__img { width: 104px; height: 78px; object-fit: cover; }
.mb-home .mb-row__edge { position: absolute; inset: 0 auto 0 0; width: 3px; border-radius: 3px 0 0 3px;
	background: var(--mb-edge); }
.mb-home .mb-row__body { display: flex; flex-direction: column; min-width: 0; }
.mb-home .mb-row__kicker { font-size: var(--mb-fs-kicker); font-weight: 600; letter-spacing: .14em;
	text-transform: uppercase; color: var(--mb-kicker, currentColor); }
/* ⚠️ TITELFARBE FESTNAGELN — GEGEN EINEN KLEBENDEN FREMD-ZUSTAND.
 *
 * Gemessen (Stephan-Gerätefund 2026-08-07: eine Zeile mit grauem Titel, alle
 * anderen schwarz): `reset.css` des Themes setzt **global**
 * `a:active, a:hover { color: rgb(51,51,102) }` — OHNE `hover:hover`-Schutz. Auf
 * Touch bleibt `:active` nach dem Tippen kleben, und weil unsere Zeilen ihre Farbe
 * vom Link erben (`color: inherit`), färbte sich der zuletzt angetippte Titel
 * dauerhaft blaugrau. Es war also weder ein „besucht"-Stil noch unsere Regel.
 *
 * Das fremde Stylesheet fassen wir nicht an (nicht unser Plugin). Stattdessen
 * setzen unsere Zeilen ihre Farben SELBST — dann kann kein geerbter Zustand sie
 * mehr umfärben, egal wer ihn setzt.
 */
/* ⚠️⚠️ ZWEI ZEILEN, DANN AUSLASSUNG (Stephan-Gerätefund 2026-08-15, Künstler-
 * seite): Der King-Gizzard-Titel „PetroDragonic…" lief über SECHS Zeilen und
 * sprengte die Zeilenhöhe — daneben stehende Zeilen sahen dadurch verschieden
 * hoch aus. Entscheid: im Artikel-Listen-View **konsistent zwei** Titelzeilen.
 *
 * ⚠️ BESTAND VORHER: GAR KEIN Deckel. Der einzige `line-clamp` der Datei gehörte
 * den GS-Kacheln (drei Zeilen, eigene Klasse, **unberührt**). `.mb-row__link`
 * hatte nur `min-height: 105px` — eine Untergrenze, die lange Titel nicht hält.
 *
 * ⚠️ WO DAS WIRKT (Footprint, weil es EIN geteiltes Partial ist):
 * App-Startseite · Kategorie-/Suchlisten (`app-list.php`) · Term-/Künstler-
 * seiten (dort ersetzt `ersetzeTermListe()` Elementors `loop-grid`) ·
 * Related-Sektion auf Artikelseiten · per `/app-state` nachgelieferte Zeilen.
 * NICHT betroffen: die
 * GS-Kacheln, sowie Web-Feed und Theme-Zeilen (fremdes Gebiet).
 *
 * ⚠️ GEKÜRZT, NIE VERKLEINERT — Handbuch §9: Schrift-Boden 14px, „shrink-to-fit"
 * ist verboten. Der Deckel ist ein Token, damit die Zahl an EINER Stelle steht.
 *
 * ⚠️ `display: -webkit-box` ist hier gefahrlos: `.mb-row__body` ist bereits
 * `flex-direction: column`, der Titel also schon ein blockifiziertes Flex-Item —
 * das vorhandene `margin-top: 3px` wirkte vorher und wirkt nachher gleich. */
.mb-home .mb-row__title,
.mb-home .mb-row__link:active .mb-row__title,
.mb-home .mb-row__link:hover .mb-row__title {
	display: -webkit-box;
	-webkit-line-clamp: var(--mb-listen-titel-zeilen);
	-webkit-box-orient: vertical;
	overflow: hidden;
	/* ⚠️⚠️ HIER STAND EINE HÖHEN-RESERVIERUNG (1.36.0–1.40.1) — ZWEI ENTSCHEIDE,
	 * BEIDE VON STEPHAN, DER ZWEITE DREHT DEN ERSTEN TEILWEISE:
	 *
	 *  · 1.36.0: `min-height` über zwei Zeilen, „damit jede Zeile dieselbe Höhe
	 *    hat" — Anlass war der sechszeilige King-Gizzard-Titel.
	 *  · 1.41.0: **wieder entfernt.** Anlass (Gerätetest 2026-08-18): Bei
	 *    EINZEILIGEN Titeln stand die reservierte zweite Zeile als toter Raum
	 *    zwischen Titel und Meta. Stephans Vorgabe: „Abstand soll AUTOMATISCH
	 *    sein", Referenz ist das Web — dort steht Clamp OHNE Reservierung
	 *    (`musikblog-favorites/assets/css/style.css:147`).
	 *
	 * ⚠️ DER DECKEL BLEIBT, und er trägt das ursprüngliche Ziel weiter: Kein
	 * Titel sprengt mehr die Zeile, weil er bei zwei Zeilen gekürzt wird. Was
	 * die Reservierung zusätzlich brachte, war nur die letzte Angleichung —
	 * gemessen **3,23px** (105 gegen 108,23). Dafür verschwanden bei jedem
	 * einzeiligen Titel **21px** Leerraum. Der Tausch ist bewusst.
	 *
	 * ⚠️ NICHT ÜBERTRAGEN AUF `.mb-pop__titel`: Dort ist die Reservierung
	 * TRAGEND, seit die Kachelhöhe ihrem Inhalt folgt (1.40.0) — ohne sie wären
	 * nebeneinander stehende Kacheln wieder verschieden hoch. Wer hier
	 * aufräumt, prüft dort zuerst. */
	margin-top: 3px;
	color: var(--mb-ink);
	font-size: var(--mb-fs-titel);
	font-weight: 400;
	line-height: var(--mb-row-titel-lh);
}
.mb-home .mb-row__meta,
.mb-home .mb-row__link:active .mb-row__meta,
.mb-home .mb-row__link:hover .mb-row__meta { color: var(--mb-ink-sek); }
/* ⚠️ EINZEILIG IST DIE INVARIANTE (Stephan 2026-08-15): „15. August 2026 ·
 * MusikBlog Newcomer Programm" brach auf zwei Zeilen und machte die Zeile höher
 * als ihre Nachbarn. Zwei Hebel greifen davor — numerisches Datum und die
 * Autor-Kurzform (beide im Partial) —, dieser hier ist das NETZ für den Rest:
 * Reicht es trotzdem nicht (sehr langer Autorenname), wird gekürzt, nicht
 * umgebrochen. Verkleinert wird nie (Schrift-Boden 14px). */
.mb-home .mb-row__meta {
	margin-top: 4px;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	font-size: var(--mb-fs-meta);
	font-weight: 300;
	color: var(--mb-ink-sek);
}

.mb-home__leer { padding: 24px 16px; color: var(--mb-ink-sek); font-size: var(--mb-fs-titel); }

/* ── Modul-Köpfe (§4) ──────────────────────────────────────────────────────
 * Einheitlich: Titel links, rechts entweder Kontext oder „Alle anzeigen" —
 * unterstrichen in Textfarbe, kein Magenta, keine Pille (§6). */
.mb-home .mb-mod { margin-top: 8px; border-top: 8px solid var(--mb-flaeche); padding-top: 16px; }
.mb-home .mb-mod__kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 0 16px 10px; }
/* ⚠️ Trägt der Kopf einen KNOPF statt einer Textzeile, ist `baseline` falsch: Die
 * Schriftlinie eines 44px-Knopfes sitzt weit unter der Überschrift. Eigene Klasse
 * statt `:has()` — der WebView-Fuß muss nicht raten. */
.mb-home .mb-mod__titel { margin: 0; font-size: var(--mb-fs-titel-lead); font-weight: 400; }
.mb-home .mb-mod__kontext { font-size: var(--mb-fs-pill); font-weight: 300; color: var(--mb-ink-sek); }

.mb-home .mb-mod__reihe {
	display: flex;
	gap: 12px;
	overflow-x: auto;
	padding: 0 16px 16px;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}
.mb-home .mb-mod__reihe::-webkit-scrollbar { display: none; }

/* ── Modul 1: Gewinnspiele (§4.1) — als einziges bildgeführt ───────────── */
/* ⚠️ DAS BLAUE FELD REICHT IMMER BIS ZUR KARTENUNTERKANTE — bei JEDER
 * Titellänge (Stephan 2026-08-15). Vorher endete es dort, wo der Text aufhörte:
 * Bei zwei Kacheln nebeneinander mit 2- und 3-zeiligem Titel blieb unter der
 * kürzeren ein weisser Streifen, weil die Reihe (`display:flex`,
 * `align-items:stretch`) die Karten auf gleiche Höhe zieht, der Farbfuss aber
 * nur so hoch war wie sein Inhalt.
 *
 * ⚠️ MINDESTHÖHE WÄRE DIE FALSCHE ANTWORT GEWESEN: Sie deckt nur Titel bis zu
 * ihrer Grenze; der erste vierzeilige Titel risse den Streifen wieder auf.
 * Strecken löst es für JEDE Länge, weil es keine Annahme über den Text macht.
 *
 * ⚠️ DIE KETTE MUSS DURCH DEN LINK: `.mb-gs__link` liegt zwischen Karte und
 * Fuss und stand auf `display:block` (Sammelregel weiter oben). Ohne diese drei
 * Zeilen zusammen greift die Streckung nicht — eine allein ist wirkungslos. */
/* ⚠️ GLEICHE HÖHE WIE DIE BELIEBTESTE-REIHE (Stephan 2026-08-15, Option a).
 * Vorher war die Kachel inhaltsbestimmt 172×235 (Bild 123 + Fuß 112) und damit
 * 58px höher als die Nachbarreihe. */
/* ⚠️ `box-sizing` ist hier KEIN Beiwerk: `.mb-pop` rechnet border-box, `.mb-gs`
 * tat es nicht — mit 1px Rahmen war die GS-Kachel real 179px aussen gegen 177px
 * der Nachbarreihe. „Gleich hoch" war also bis 1.33.0 um 2px daneben. */
/* ⚠️⚠️ EINHEITLICHE REIHENBREITE: 172px WIE DIE BELIEBTESTE-KACHEL
 * (Stephan-Entscheid 2026-08-20, Variante „B" — nach seiner Nachfrage „Ich denke,
 * die gs Box war genauso breit wie die beliebteste Boxen darunter?").
 *
 * ⚠️ DIE HISTORIE IN EINEM STÜCK — vierte Runde am selben Wert. Sie steht hier
 * KONSOLIDIERT statt weiter gestapelt: Vor dieser Änderung lagen an dieser Stelle
 * vier Kommentarblöcke übereinander, von denen zwei den Code unter sich bereits
 * widersprachen. Wer die Breite erneut anfasst, liest DIESEN Block — es gibt
 * keinen zweiten:
 *  · seit 1.13.0     210px (Ur-Zustand; die GS war als einzige Reihe bildgeführt)
 *  · b2e5fe6–1.41.2  172px als TEST, Bild proportional mit
 *  · 1.35.0          zusätzlich eine FESTE Höhe (177px). DAS drückte das Bild auf
 *                    170×66 — Verhältnis 2,58 statt 1,38. Stephans Ärgernis war
 *                    der Quetsch, nicht die Breite; die beiden wurden nur
 *                    zusammen erlebt.
 *  · 1.41.3          zurück auf 210px UND inhaltsbestimmte Höhe — beides zusammen,
 *                    weil 210px bei fester Höhe 208×66 ergäbe, also noch flacher.
 *  · 1.44.0 (hier)   172px BEWUSST, mit vollem Bild: einheitliche Reihenbreite
 *                    schlägt die bildgeführte Sonderrolle. Gleich breit waren die
 *                    beiden Reihen nämlich NUR im Test-Zeitraum — der Ur-Zustand
 *                    war ungleich. Stephan hat das gewusst und sich so entschieden.
 *
 * ⚠️ DIE FESTE HÖHE KOMMT NICHT ZURÜCK. Sie ist die Ursache des 66px-Quetsches und
 * wurde in 1.41.3 abgeschafft; dieser Entscheid ändert AUSSCHLIESSLICH die Breite.
 * Wer hier je wieder eine Höhe setzt, baut 1.35.0 nach.
 *
 * ⚠️ Die Kachelbreite steht NUR hier — keine `slidesPerView`-Konfiguration am
 * Swiper hält eine zweite Wahrheit (geprüft). Wer sie ändert, ändert sie an genau
 * einer Stelle.
 *
 * ⚠️ Schriften bleiben unangetastet: Titel 16px/400, identisch zur
 * Beliebteste-Kachel; der 3-Zeilen-Clamp bleibt. Schmaler brechen lange
 * Künstlernamen eher dreizeilig um — von Stephan benannt und akzeptiert. */
.mb-home .mb-gs { display: flex; flex: 0 0 172px; width: 172px; box-sizing: border-box; border: 1px solid var(--mb-linie); border-radius: 3px; overflow: hidden; }
.mb-home .mb-gs__link { display: flex; flex-direction: column; flex: 1 1 auto; }

/* ⚠️ DER FIGURE WÄCHST UND SCHRUMPFT NICHT (`flex: 0 0 auto`): Seine Höhe kommt
 * allein vom Bild darunter. `position: relative` ist der Anker des Badges,
 * `overflow: hidden` hält den Bildausschnitt in der Kachelrundung.
 *
 * ⚠️ HIER STAND BIS 1.43.0 EIN KOMMENTAR, DER DEN CODE UNTER SICH BESTRITT: Er
 * beschrieb das Bild als „nachgebenden Teil", der „den Rest der 177px" bekomme —
 * eine Mechanik aus 1.35.0, die 1.41.3 mit der festen Höhe abgeschafft hat,
 * während direkt darunter längst `height: 150px` stand. Er ist beim Revert
 * mitgelaufen, statt mitgezogen zu werden. Deshalb die Regel an dieser Datei:
 * Wer einen Wert ändert, prüft den Kommentar DARÜBER auf denselben Wert. */
.mb-home .mb-gs__figure { position: relative; display: block; flex: 0 0 auto; overflow: hidden; }
/* ⚠️⚠️ DIE BILDHÖHE IST ABGELEITET, NICHT GESETZT — `aspect-ratio` STATT ZWEITER ZAHL.
 * Bis 1.43.0 stand hier `height: 150px`. Der Wert passte zu 210px Breite (208px
 * innerhalb des Rahmens, Verhältnis 1,387). Bei 172px Breite hätte dieselbe Zahl
 * das Bild auf 170×150 gestaucht — Verhältnis 1,13 — also genau die Quetsch-Klasse
 * von 1.35.0, nur aus der anderen Richtung. Eine Breitenänderung OHNE diese Zeile
 * wäre der halbe Auftrag gewesen.
 *
 * `aspect-ratio: 208 / 150` hält das ursprüngliche Verhältnis fest und leitet die
 * Höhe aus der jeweiligen Breite ab: bei 170px innen sind das 122,6px. Damit ist
 * die zweite Zahl verschwunden — die nächste Breitenänderung zieht das Bild von
 * selbst nach, ohne dass jemand eine Höhe nachrechnet und dabei danebenliegt.
 *
 * Gleich hohe Kacheln bleiben garantiert, ohne dass jemand eine Höhe setzt: Alle
 * GS-Kacheln sind gleich breit, also ist die abgeleitete Bildhöhe für alle gleich;
 * der Fuß ist ohnehin aus Token gerechnet (--mb-gs-fuss-hoehe). */
.mb-home .mb-gs__img { display: block; width: 100%; height: auto; aspect-ratio: 208 / 150; object-fit: cover; }
/* ⚠️ Platz für das Badge steht IMMER — die Zahl kommt per Nachladen (CLS 0).
 * Ohne reservierte Fläche springt die Karte, sobald der Zähler eintrifft. */
.mb-home .mb-gs__badge {
	position: absolute;
	top: 8px;
	right: 8px;
	min-height: 22px;
	min-width: 22px;
	display: inline-flex;
	align-items: center;
	gap: 4px;
	padding: 3px 9px;
	border-radius: 999px;
	background: var(--mb-orange);
	color: #fff;
	font-size: 12px;
	font-weight: 600;
	box-sizing: border-box;
	opacity: 0;
	transition: opacity 160ms cubic-bezier(.2, .6, .2, 1);
}
.mb-home .mb-gs__badge[data-mb-gefuellt="1"] { opacity: 1; }
/* Kit-Blau (Stephan-Entscheid 2026-08-08); Weiß darauf 7,45:1. */
/* ⚠️ DER FARBFUSS REICHT BIS ZUR KARTENKANTE (Regel aus 1.30.0) — und er nimmt
 * den Überschuss der Reihen-Streckung SELBST. `flex: 1 0 <basis>`: wachsen ja,
 * schrumpfen NEIN.
 *
 * ⚠️⚠️ GRABSTEIN (Stephan-Fund 02.09., über den Supervisor): Hier stand ein
 * Kommentar, der den Code unter sich bestritt — „Seit die Kachel ihre eigene
 * feste Höhe hat, nimmt der FIGURE den Überschuss." Beides war falsch: Die
 * feste Kachelhöhe wurde in 1.41.3 abgeschafft (siehe „DIE FESTE HÖHE KOMMT
 * NICHT ZURÜCK" weiter oben), und `.mb-gs__figure` steht auf `flex: 0 0 auto`,
 * nimmt also gar nichts. Seit dem 1.41.3/1.44.0-Umbau hatte die Streck-Kette
 * damit KEINEN Überschuss-Nehmer mehr; der 1.30.0-Fix war entkernt.
 * **Der Kommentar hat den Defekt nicht nur überlebt, er hat ihn versteckt** —
 * zweite Instanz derselben Fehlerklasse, die diese Datei 20 Zeilen weiter oben
 * schon dokumentiert („Wer einen Wert ändert, prüft den Kommentar DARÜBER").
 *
 * ⚠️ WARUM ES NIEMAND SAH: Sichtbar wird es nur, wenn zwei laufende Gewinnspiele
 * UNGLEICH lange Titel haben — die höhere Karte streckt die Reihe, die
 * niedrigere behält ihren Fuß auf der Basis und zeigt darunter Weiß. Latent
 * seit ~20.08.
 *
 * ⚠️ DIE 109px SIND EINE UNTERGRENZE, KEINE HÖHE — das entscheidet die Form des
 * Fixes. `min-height: auto` (die automatische Mindestgröße von Flex-Items)
 * schlägt die Basis, sobald der Inhalt höher ist: am 02.09. live gemessen trägt
 * die 3-Zeilen-Karte 128,58px Fuß gegen eine Basis von 109. `1 0` lässt genau
 * das unberührt und füllt nur noch die Lücke der gestreckten Nachbarin.
 *
 * ⚠️ WARUM NICHT `1 1` (die Fassung bis 1.32.0): Der damalige „das Bild
 * verschwindet"-Kampf kam vom SHRINK, nicht vom Grow. Shrink bleibt 0, der
 * FIGURE bleibt `0 0 auto` — gemessen ist das Bild vor wie nach dem Fix
 * 170×122,59 (Verhältnis 1,387), die `aspect-ratio` also unangetastet. */
.mb-home .mb-gs__fuss {
	display: block;
	flex: 1 0 var(--mb-gs-fuss-hoehe);
	box-sizing: border-box;
	padding: var(--mb-gs-fuss-oben) 12px var(--mb-gs-fuss-unten);
	background: #35558A;
	color: #fff;
}
.mb-home .mb-gs__frist {
	display: block;
	margin-bottom: var(--mb-gs-frist-abstand);
	line-height: var(--mb-gs-frist-lh);
	font-size: var(--mb-fs-kicker);
	font-weight: 600;
	letter-spacing: .14em;
	text-transform: uppercase;
	opacity: .92;
}
/* ⚠️ DECKEL AUF DREI ZEILEN — der Riegel, ohne den die feste Kachelhöhe eine
 * Falle wäre. Rechnung aus genau diesem CSS: Fuß = 24 Polster + 19,6 Frist +
 * 3 Abstand + n × 20,8 Titelzeile. Bei drei Zeilen sind das 109px, es bleiben
 * 68px Bild. Bei VIER Zeilen wären es 129,8px — das Bild fiele auf 47px, und
 * jede weitere Zeile schöbe den Titel unter die Kachelkante, wo `overflow:
 * hidden` ihn mitten im Wort abschneidet.
 *
 * ⚠️ WARUM DREI UND NICHT ZWEI: Drei ist der HEUTIGE Zustand, nicht eine neue
 * Entscheidung — der live gemessene Fuß ist 112px, das entspricht 3,1 Zeilen.
 * Der Deckel ändert also für die allermeisten Kacheln nichts; er begrenzt nur
 * den Ausreißer.
 *
 * ⚠️ NICHT VERKLEINERN: Der Handbuch-Boden von 14px und das Verbot von
 * „shrink-to-fit" gelten. Ein zu langer Titel wird gekürzt (mit Auslassung),
 * nie geschrumpft. */
.mb-home .mb-gs__titel {
	display: -webkit-box;
	-webkit-line-clamp: var(--mb-gs-titel-zeilen);
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: var(--mb-fs-titel);
	font-weight: 400;
	line-height: var(--mb-gs-titel-lh);
}

/* ── „Weitere Artikel" ─────────────────────────────────────────────────────
 * ⚠️ RUHIGER KNOPF, KEIN MAGENTA, KEINE PILLE (§6): Das Violett ist im Feed
 * bereits mit der Pill-Leiste belegt; ein zweites magenta Element würde mit ihr
 * um die Aufmerksamkeit konkurrieren. Volle Tap-Höhe, Radius 3px.
 * `.mb-home`-Präfix wie bei den Pills — ein <button> erbt sonst die
 * Child-Theme-Button-Regeln (dort magenta gefüllt). */
.mb-home__mehr { padding: 4px 16px 20px; }
.mb-home .mb-mehr {
	appearance: none;
	-webkit-appearance: none;
	display: block;
	width: 100%;
	min-height: 44px;
	margin: 0;
	padding: 12px 16px;
	border: 1px solid var(--mb-linie);
	border-radius: 3px;
	background: var(--mb-flaeche);
	color: var(--mb-ink);
	font: inherit;
	font-size: var(--mb-fs-pill);
	font-weight: 400;
	line-height: 1.2;
	text-transform: none;
	box-shadow: none;
	cursor: pointer;
}
/* ⚠️ ALLE ZUSTÄNDE FESTNAGELN — sonst holt sich der Elementor-Kit den Knopf zurück.
 *
 * Gemessen an der Trefferliste des gerenderten Knopfes: `.elementor-kit-119134
 * button` setzt `background: var(--e-global-color-primary)` — das Violett. Im
 * Grundzustand gewinnt unsere Regel, aber für `:active`, `:hover` und `:disabled`
 * hatten wir GAR KEINE — dort schlug der Kit durch. Auf dem Gerät kippte der
 * Knopf beim Antippen auf violette Vollfläche mit weißer Schrift
 * (Stephan 2026-08-08: „nachlade Button bitte hellgrau wie auf live").
 *
 * ⚠️ UND FACHLICH: Violett ist die PRIMÄR-AKTION. Ein Knopf, der gerade wartet,
 * ist keine Aktion — er soll ruhiger werden, nicht lauter. Der Ladezustand behält
 * deshalb die Ruhe-Optik und dämpft nur den Text.
 */
.mb-home .mb-mehr:hover,
.mb-home .mb-mehr:focus,
.mb-home .mb-mehr:active,
.mb-home .mb-mehr:disabled,
.mb-home .mb-mehr[aria-busy="true"] {
	background: var(--mb-flaeche);
	border-color: var(--mb-linie);
	color: var(--mb-ink);
}
/* Hover-Aufhellung NUR mit echtem Zeiger (Sticky-Hover-Kanon) — auf Touch bliebe
 * sie nach dem Tippen kleben. */
@media (hover: hover) {
	.mb-home .mb-mehr:hover { background: var(--mb-flaeche-hover); }
}
/* Wartender Knopf: nur der Zeiger ändert sich. Eine zusätzliche Text-Dämpfung war
 * kurz drin und griff nicht (gleiche Spezifität, die Sammel-Regel oben steht
 * dahinter) — statt eine dritte Schicht zu stapeln, bleibt es beim Ruhe-Text.
 * Der Wartezustand ist über „Lädt …" und `aria-busy` ohnehin eindeutig. */
.mb-home .mb-mehr:disabled,
.mb-home .mb-mehr[aria-busy="true"] { cursor: default; }
.mb-home .mb-mehr:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(194, 43, 247, .55); }
.mb-home .mb-mehr[hidden] { display: none; }

/* ── Modul 2: Beliebteste (§4.2) — BEWUSST BILDLOS ────────────────────────
 * Mit Covern sähe das Modul aus wie der Feed direkt darüber; die Rangziffer
 * muss führen, damit es als Ranking lesbar ist. Keine Pfeil-Knöpfe: gewischt
 * wird mit dem Finger. */
/* ⚠️⚠️ GRABSTEIN — HIER STAND `min-height: var(--mb-kachel-hoehe)` (1.33.0–1.39.1).
 * Der Token koppelte diese Kachel an die GS-Reihe, damit beide 177px hoch sind.
 * **Die Kopplung ist mit 1.40.0 aufgelöst**, und zwar auf Stephans Ansage:
 * „können wir die Boxen doch niedriger machen — es ist jetzt viel leere Fläche
 * unten." Seit dem 2-Zeilen-Deckel (1.38.0) endet der Inhalt weit über 177px;
 * der Rest war toter Raum.
 *
 * ⚠️ WARUM HIER KEINE RECHNUNG STEHT, obwohl der Auftrag eine anbot: Sie wäre
 * überflüssig. Titel (2 Zeilen reserviert) und Meta (1 Zeile) haben feste
 * Höhen — damit IST die Kachel schon für alle Einträge gleich hoch, ohne dass
 * irgendwer sie ausrechnet. Eine `calc()`-Formel aus Padding + Kopf + Titel +
 * Meta würde dasselbe Ergebnis erzeugen und dabei die Kopf-Zeile (Rang 26px
 * neben Kicker 14px, `align-items: baseline`) modellieren müssen — ein Wert,
 * den der Browser besser kennt als wir. Dieselbe Lehre wie beim GS-Fuß
 * (1.35.0): die TEILE festnageln, den Behälter folgen lassen.
 *
 * ⚠️ NACHTRAG 1.41.3: Auch die GS-Kachel hat den Token inzwischen verloren —
 * sie ist zurück auf ihrer ursprünglichen, inhaltsbestimmten Größe. Der Token
 * ist damit ganz entfallen (Grabstein im Token-Block oben). */
.mb-home .mb-pop {
	flex: 0 0 172px;
	width: 172px;
	background: var(--mb-flaeche);
	border: 1px solid var(--mb-linie);
	border-radius: 3px;
	padding: 14px 14px 15px;
	box-sizing: border-box;
}
.mb-home .mb-pop__kopf { display: flex; align-items: baseline; gap: 8px; }
.mb-home .mb-pop__rang { font-size: var(--mb-fs-rang); font-weight: 600; line-height: 1; }
/* ⚠️ HIER STAND VERSALIEN + .14em SPERRUNG — beides ist weg, und zwar aus einer
 * MESSUNG, nicht aus Geschmack (Stephan 2026-08-15: „Versalien weg oder Schrift
 * kleiner"). Verfügbar sind je nach Rang 104,7–121,6px; die zweistellige 10
 * frisst 17px mehr als die 1, der engste Fall ist also Rang 10.
 * Gemessen an der Live-App mit der echten Schrift:
 *     Variante              MB Newcomer   Gewinnspiel
 *     Versalien .14em (alt)     130,3         118,0    → beide brechen
 *     Versalien .06em           118,0         105,7    → beide brechen
 *     Versalien 0               108,8          96,5    → MB bricht knapp
 *     Mixed Case .06em          106,9          91,5    → MB bricht um 2,2px
 *     Mixed Case 0               97,7          82,3    → BEIDE passen, 7px Luft
 * Nur die letzte Zeile rettet beide Fälle, OHNE die Rang-Zahl anzufassen.
 * ⚠️ Die Sperrung fällt mit den Versalien: Tracking ist ein Versalien-Mittel;
 * auf Mixed Case wirkt es zerfasert. Beides gehört zusammen weg oder gar nicht.
 * ⚠️ 14px ist der Boden (Handbuch §9) — die Schrift war KEIN Hebel, sie stand
 * schon dort. */
.mb-home .mb-pop__kicker { font-size: var(--mb-fs-kicker); font-weight: 600; }
/* ⚠️ ZWEI ZEILEN — der schwerste Fall des Sweeps vom 2026-08-15: Mit dem
 * 162-Zeichen-Titel wuchs diese Kachel von 177px auf **335px** und riss damit
 * genau die Reihen-Gleichheit auf, die 1.33.0/1.35.0 hergestellt haben — sie
 * ist die Nachbarreihe, an der `--mb-kachel-hoehe` hängt.
 *
 * Reserviert wird wie bei den Zeilen, damit ein kurzer Titel die Kachel nicht
 * kleiner macht als ein zweizeiliger. */
.mb-home .mb-pop__titel {
	display: -webkit-box;
	-webkit-line-clamp: var(--mb-listen-titel-zeilen);
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: calc(var(--mb-fs-titel) * var(--mb-pop-titel-lh) * var(--mb-listen-titel-zeilen));
	margin-top: 8px;
	font-size: var(--mb-fs-titel);
	font-weight: 400;
	line-height: var(--mb-pop-titel-lh);
}
.mb-home .mb-pop__meta {
	display: block;
	margin-top: 5px;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	font-size: var(--mb-fs-meta);
	font-weight: 300;
	color: var(--mb-ink-sek);
}

/* ── Modul 3: Album Charts (§4.3) — Nummernblöcke, keine Thumbnails ───────
 * Ziel ≤60px pro Platz (heute ~180px). */
/* ── Lade-Zustand beim ERSTEN Tipp auf eine Rubrik (1.16.4) ───────────────
 * ⚠️ DER ALTE INHALT BLEIBT STEHEN UND TRITT ZURÜCK. Die Fläche leer zu räumen
 * wäre die unehrlichere Antwort: Ein weißer Block sieht aus wie „nichts
 * gefunden", obwohl noch gesucht wird. Jeder WEITERE Wechsel kommt aus dem
 * Sichten-Speicher und sieht diesen Zustand nie. */
.mb-home__feed[aria-busy="true"] { opacity: .55; transition: opacity .12s ease-out; }

.mb-home .mb-charts { margin: 0; padding: 0 16px 16px; list-style: none; }
.mb-home .mb-chart + .mb-chart { margin-top: 8px; }
/* ⚠️ `[hidden]` EXPLIZIT: Die UA-Regel ist schwach und fiele gegen jede
 * `display`-Regel aus Theme oder Kit — dann stünden die versteckten Plätze
 * sichtbar da und der Aufklapp-Knopf wäre sinnlos. Gleiches Muster wie beim
 * Nachlade-Knopf. */
.mb-home .mb-charts .mb-chart[hidden] { display: none; }
.mb-home .mb-chart__link { display: flex; align-items: stretch; gap: 14px; }
/* ── Rang-Verlauf wie im Web (Stephan-Entscheid 2026-08-10) ───────────────
 * ⚠️ AM LIVE-DOM DER STARTSEITE GEMESSEN, nicht aus der Spec übernommen: Die
 * Web-Charts geben dem Rang-Block die Grundfarbe mit RANGWEISE ABSINKENDER
 * DECKKRAFT — #1 kräftig, #10 blass. Unsere flache Fläche war ein
 * Konsistenz-Verstoß. Stephan: „Eine Design-Spec overruled nie unsere eigenen
 * Standards."
 *
 * Gemessene Leiter (computed background je Rang, hell):
 *   1.000 · .933 · .867 · .800 · .733 · .667 · .600 · .533 · .467 · .400
 * — dieselbe Alpha-Treppe wie der `.mb-nc-charts`-Block im Child-Theme
 * (ff/ee/dd/cc/bb/aa/99/88/77/66), dort in Grün.
 *
 * ⚠️ GRUNDFARBE IST DIE GEMESSENE: `rgb(195 43 247)`. Das ist EIN Rot-Wert neben
 * dem Kit-Primär #C22BF7 (194,43,247) — geraten hätte ich falsch. Der Wert steht
 * hier als Messergebnis, nicht als Token-Verweis; siehe Vollzug 2026-08-10.
 *
 * ⚠️ TINTE WECHSELT AB RANG 6 AUF DUNKEL — ebenfalls gemessen (Rang 1–5 weiß,
 * 6–10 schwarz). Auf den blassen Stufen trägt Weiß nicht mehr.
 *
 * ⚠️ IM DUNKELMODUS BLEIBT SIE DURCHGEHEND HELL. Begründung steht im Child-Theme
 * am Dark-Block: „Alpha-Grün wirkt dunkel -> Ziffern immer hell". Auf dunklem
 * Grund verliert die blasse Fläche ihre Helligkeit, dunkle Ziffern verschwänden.
 */
.mb-home .mb-chart { --mb-rang-alpha: 1; }
.mb-home .mb-chart:nth-child(2)  { --mb-rang-alpha: .933; }
.mb-home .mb-chart:nth-child(3)  { --mb-rang-alpha: .867; }
.mb-home .mb-chart:nth-child(4)  { --mb-rang-alpha: .800; }
.mb-home .mb-chart:nth-child(5)  { --mb-rang-alpha: .733; }
.mb-home .mb-chart:nth-child(6)  { --mb-rang-alpha: .667; }
.mb-home .mb-chart:nth-child(7)  { --mb-rang-alpha: .600; }
.mb-home .mb-chart:nth-child(8)  { --mb-rang-alpha: .533; }
.mb-home .mb-chart:nth-child(9)  { --mb-rang-alpha: .467; }
.mb-home .mb-chart:nth-child(10) { --mb-rang-alpha: .400; }

/* Ab Rang 6 trägt Weiß auf der blassen Fläche nicht mehr — gemessen am Web. */
.mb-home .mb-chart:nth-child(n+6) { --mb-rang-tinte: #222227; }
body.mb-dark .mb-home .mb-chart { --mb-rang-tinte: #F5F5F7; }

.mb-home .mb-chart__rang {
	flex: 0 0 46px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: 3px;
	background: rgb(195 43 247 / var(--mb-rang-alpha, 1));
	color: var(--mb-rang-tinte, #fff);
	/*
	 * ⚠️ 18px/300 IST DIE WEB-ZIFFER, GEMESSEN — nicht geschätzt (1.29.0).
	 * Stephan: „ich meinte eigentlich auch nur den Font." Die Web-Rang-Kacheln
	 * sind PSEUDO-ELEMENTE (`ol.mb-charts > li::before` mit `content: "#"
	 * counter(…)`) — deshalb fand sie kein Element- oder Text-Scan; erst
	 * `getComputedStyle(li, '::before')` bringt sie zum Vorschein. Dort steht
	 * `-apple-system 18px/300`, gemessen am 375px-Viewport der Live-Startseite.
	 * Vorher stand hier 16px/600 (`--mb-fs-titel`) — schwerer und kleiner.
	 *
	 * ⚠️ ALPHA-LEITER UND WECHSELPUNKT STIMMEN BEREITS: Unsere Werte 1 → .400
	 * und der Tinten-Wechsel ab Rang 6 sind identisch mit dem Web (alle zehn
	 * Ränge nachgemessen). Hier war NUR der Font verschieden.
	 *
	 * ⚠️ DIE KACHEL-BREITE BLEIBT 46px (Web: 50px). Stephans Ansage war
	 * ausdrücklich „nur der Font"; die 4px Differenz sind dokumentiert, nicht
	 * vergessen.
	 *
	 * ⚠️ UND DIE DUNKLE TINTE BLEIBT `#222227` (Web: reines Schwarz). Das ist
	 * unser Haus-Tintenton aus der Token-Tabelle; ihn für zwei nicht
	 * unterscheidbare RGB-Schritte aufzugeben, bräche die Token-Konsistenz für
	 * nichts.
	 */
	font-size: 18px;
	font-weight: 300;
}
.mb-home .mb-chart__body { display: flex; flex-direction: column; justify-content: center; min-width: 0; padding: 6px 0; }
/* ⚠️ ZWEI ZEILEN (Sweep 2026-08-15: 51,3px → 113,7px beim 162-Zeichen-Titel). */
.mb-home .mb-chart__titel {
	display: -webkit-box;
	-webkit-line-clamp: var(--mb-listen-titel-zeilen);
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-size: var(--mb-fs-titel);
	font-weight: 400;
	line-height: var(--mb-chart-titel-lh);
}
.mb-home .mb-chart__interpret {
	display: block;
	margin-top: 2px;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	font-size: var(--mb-fs-pill);
	font-weight: 300;
	color: var(--mb-ink-sek);
}

/* ⚠️ §6: Bewegung respektiert die Systemeinstellung. */
@media (prefers-reduced-motion: reduce) {
	.mb-home *,
	.mb-home *::before,
	.mb-home *::after {
		transition-duration: .01ms !important;
		animation-duration: .01ms !important;
	}
}


/* ── Aufklapp-Knopf im Modul-Kopf: ERSATZLOS ENTFERNT (1.29.0) ────────────
 * Hier standen die Regeln für `.mb-mod__alle` („Alle 10 anzeigen"). Der Knopf
 * ist mit der Aufklapp-Mechanik der Album-Charts entfallen (Stephan
 * 2026-08-15: „Aufklappen der Charts ist Overkill") — alle zehn Ränge stehen
 * jetzt sofort da, wie im Web.
 *
 * ⚠️ DIE LEHRE DAHINTER GILT WEITER und lebt bei `.mb-mehr` (oben): Ein
 * `<button>` ohne `.mb-home` im Selektor verliert gegen `.elementor-kit-… button`
 * und bekommt weiße Schrift auf weißem Grund. Wer hier je wieder einen Knopf
 * einsetzt, pinnt ALLE Zustände selbst — nicht nur den Ruhezustand. */

/* ── Zustands-Pinnung der Link-Bauteile (Review 2026-08-10, P2-2) ─────────
 * ⚠️ VIER FREMDE REGELN ZIELEN AUF JEDEN UNSERER ARTIKEL-LINKS — gemessen am
 * gerenderten Dokument über die CSSOM (152 Zustands-Regeln, Positivkontrolle
 * bestanden):
 *   reset.css              a:active, a:hover        → color #333366
 *   post-119134.css        .elementor-kit-… a:hover → --e-global-color-b74f46a
 *   mb-theme-standards.css a:hover                  → color #CC3366
 *   style.css              a:focus-visible          → outline 2px
 *
 * ⚠️ GEGENWEHR HATTE NUR `.mb-row__link` — aus 1.14.1, als ein fremdes `a:active`
 * den Zeilentitel grau färbte (Stephans Gerätefund). Repariert wurde damals die
 * EINE gemeldete Stelle; die gleichrolligen Geschwister blieben offen. Auf dem
 * Aufmacher-Band hieße ein Treffer: #333366 statt Weiß auf farbigem Vollton.
 *
 * Dieselbe Wurzel wie 1.16.8 und 1.16.10: Wer nur die gemeldete Stelle härtet,
 * wartet auf den nächsten Gerätefund. Deshalb hier alle vier gemeinsam.
 */
.mb-home .mb-lead__link,
.mb-home .mb-lead__link:hover,
.mb-home .mb-lead__link:focus,
.mb-home .mb-lead__link:active,
.mb-home .mb-pop__link,
.mb-home .mb-pop__link:hover,
.mb-home .mb-pop__link:focus,
.mb-home .mb-pop__link:active,
.mb-home .mb-chart__link,
.mb-home .mb-chart__link:hover,
.mb-home .mb-chart__link:focus,
.mb-home .mb-chart__link:active {
	color: inherit;
	text-decoration: none;
}

/* Der Aufmacher-Block bleibt in JEDEM Zustand weiß auf seinem Vollton. */
.mb-home .mb-lead__link:hover .mb-lead__title,
.mb-home .mb-lead__link:focus .mb-lead__title,
.mb-home .mb-lead__link:active .mb-lead__title,
.mb-home .mb-lead__link:hover .mb-lead__kicker,
.mb-home .mb-lead__link:active .mb-lead__kicker,
.mb-home .mb-lead__link:hover .mb-lead__meta,
.mb-home .mb-lead__link:active .mb-lead__meta { color: #fff; }

/* Beliebteste und Charts behalten ihre Tinte; der Kicker seine Rubrik-Farbe. */
.mb-home .mb-pop__link:hover .mb-pop__titel,
.mb-home .mb-pop__link:active .mb-pop__titel,
.mb-home .mb-chart__link:hover .mb-chart__titel,
.mb-home .mb-chart__link:active .mb-chart__titel { color: var(--mb-ink); }
.mb-home .mb-pop__link:hover .mb-pop__meta,
.mb-home .mb-pop__link:active .mb-pop__meta,
.mb-home .mb-chart__link:hover .mb-chart__interpret,
.mb-home .mb-chart__link:active .mb-chart__interpret { color: var(--mb-ink-sek); }

/* Fokus sichtbar halten — außerhalb des hover-Guards (Tastatur/Screenreader). */
.mb-home .mb-lead__link:focus-visible,
.mb-home .mb-pop__link:focus-visible,
.mb-home .mb-chart__link:focus-visible,
.mb-home .mb-row__link:focus-visible {
	outline: 2px solid var(--mb-violett);
	outline-offset: -2px;
}

/* ── Dunkles Schema (1.16.6) ──────────────────────────────────────────────
 * ⚠️ AUSLÖSER IST `body.mb-dark`, NICHT `prefers-color-scheme`. Die Site schaltet
 * per KLASSE (eigener Umschalter); ein reines Media-Query würde am Nutzerwunsch
 * vorbeischalten und wäre gegen den Rest der Seite inkonsistent.
 *
 * ⚠️ HAUS-TOKENS, KEINE EIGENEN: Grund #2c2c31, abgesetzt #3a3a40, Rahmen #45454c,
 * gedämpft #B6B6BE — dieselben Werte wie bookmark.css und Termin-Landing.
 */
body.mb-app.mb-dark {
	/* ⚠️ ABWEICHUNG ZUM HANDBUCH BEWUSST UND GEMELDET: Dessen Token-Tabelle führt
	 * `--mb-surface` dunkel als #2A2A30 und `--mb-surface-2` als #33333B; der
	 * Auftrag nennt #2c2c31 / #3a3a40. #2c2c31 ist im Handbuch die Grundfläche, an
	 * der auch das Dark-Akzent-Violett gemessen wurde — die Rollen sind also
	 * verschieden (Seite vs. Bauteil). Alle Akzente unten halten ≥5:1 auf BEIDEN
	 * Kandidaten, die Entscheidung ändert daher keine Zusage. */
	--mb-grund: #2C2C31;          /* Seitengrund dunkel (siehe .mb-home unten) */
	--mb-ink: #F5F5F7;            /* Handbuch `--mb-fg` dunkel; auf #2c2c31 12,76:1 */
	--mb-ink-sek: #B6B6BE;        /* auf #2c2c31:  6,90:1 */
	--mb-linie: #45454C;
	--mb-trenner: rgba(255, 255, 255, .12);
	--mb-flaeche: #3A3A40;
	--mb-flaeche-hover: #45454C;
}

/* Die Fläche selbst bleibt am Bauteil (siehe Hell-Block oben): Ein
 * `background` auf `body.mb-app.mb-dark` würde jede App-Seite einfärben,
 * auch die, die ihren Hintergrund von Elementor bekommt. */
body.mb-dark .mb-home {
	background: #2C2C31;
}

/* ⚠️ DIE AUFMACHER-VOLLTÖNE BLEIBEN IN BEIDEN SCHEMES DIESELBEN Kit-Farben — sie
 * sind MARKEN-Flächen mit weißer Schrift, wie die Gewinnspiel-Kartenfüße, und
 * kommen ohnehin als Inline-Wert aus der Farbtabelle. Hier steht bewusst NICHTS. */

/* Der Kicker wechselt auf die aufgehellte Variante desselben Farbtons. Beide Werte
 * liefert PHP als Variablen ans Markup — siehe `farbeDunkel()`. */
body.mb-dark .mb-home .mb-row__kicker { color: var(--mb-kicker-dark, var(--mb-kicker)); }
/* ⚠️ DER BALKEN TAUSCHT MIT — SONST IST ER IM DUNKELN FAST UNSICHTBAR.
 * Volltoene auf #2c2c31 lagen zwischen 1,56:1 und 2,97:1 (alle sieben Rubriken,
 * gemessen 2026-08-12); mit den Dunkelwerten sind es 5,00:1 bis 6,84:1.
 * ⚠️ NICHT ZU VERWECHSELN mit den AUFMACHER-Volltoenen weiter unten: Das sind
 * Marken-FLAECHEN mit weisser Schrift darauf und bleiben bewusst in beiden
 * Schemes gleich. Hier geht es um den 3px-Kantenbalken der Listenzeile. */
body.mb-dark .mb-home .mb-row__edge { background: var(--mb-edge-dark, var(--mb-edge)); }

/* Fremde Flächen im Dunkeln: der Nachlade-Knopf und die Pills leben von den Tokens
 * oben, brauchen also keine eigene Regel. Was NICHT über Tokens läuft, steht hier. */
body.mb-dark .mb-home__feed,
body.mb-dark .mb-home .mb-row,
body.mb-dark .mb-home .mb-liste { background: transparent; }

/* ⚠️ DER PILL-RAHMEN IST HART AUF DUNKLE TINTE GESETZT (`rgba(34,34,39,.24)`) —
 * auf dunklem Grund wäre er praktisch unsichtbar und die Pills verlören ihre
 * Kontur. Als einziger Wert der Komponente, der NICHT über ein Token läuft,
 * braucht er hier eine eigene Zeile. */
body.mb-dark .mb-home .mb-pill { border-color: rgba(255, 255, 255, .28); }

/* ── Kommentarfeld im App-Artikel (1.22.6) ──────────────────────────────────
 * ⚠️ WERTE AUS DEM GEWINNSPIEL-FORMULAR ÜBERNOMMEN, NICHT GESCHÄTZT.
 * Stephan („Dim. 8"): Beide Kommentarfelder sollen gleich aussehen. Unseres war
 * WordPress-Default und rund achtzeilig, das GS-Feld ist zweizeilig.
 *
 * Quelle: `musikblog-gewinnspiel/participation.css:37-52` — das Feld wird dort
 * zur LAUFZEIT von `participation.js` injiziert, deshalb steht die Größe weder
 * im Markup noch in Elementor. Soll-Höhe: 2 × 16 × 1,4 = 44,8 + 20 Padding + 2
 * Border ≈ 67px.
 *
 * ⚠️ `font-size: 16px` ist Pflicht, keine Kosmetik: Darunter zoomt iOS beim
 * Fokus in das Feld — der Nutzer landet in einer vergrößerten Seite.
 *
 * ⚠️ Gescopet auf `body.mb-app`: Im Web bleibt das Kommentarfeld unverändert.
 * Wir gleichen die APP-Ansicht an, nicht die Website.
 */
/* ⚠️ LABEL-REZEPT EBENFALLS AUS DEM GS-FORMULAR (`participation.css:24-35`) —
 * Stephan: „dort noch abstand fixen!". Der WP-Default klebte ohne Abstand am
 * Rahmen. `margin-bottom: 6px` ist der GS-Wert, nicht geschätzt; `display:block`
 * ist die Bedingung dafür, dass der Abstand überhaupt wirkt (inline-Labels
 * ignorieren vertikale Margins). */
/* ⚠️ 18px = WEB-PARITAET (Stephan-Fund 28.08.: "font kleiner als im Web").
   Hier stand bis dahin 14px — der HAUS-SCHRIFTBODEN. Er war nicht falsch, aber
   der Boden ist kein Ziel: Das Web setzt 18px, und der Sprung war am Geraet
   sichtbar. Wer ihn wieder senkt, senkt gegen die Web-Fassung, nicht gegen eine
   Regel. */
/* ⚠️⚠️ GEWICHT 300, NICHT 400 — Stephan-Gerätefund 28.08. („‚Deine Wunschstadt'
   hat in der App ein anderes Gewicht als im Web"). Am Live-Dokument gemessen,
   390 px, mit gewinnspiels echtem Feld-Markup:

       Web  300 · App 400   ← die 400 hier war die Abweichung

   ⚠️ ES WAR NICHT NUR DAS GS-FELD: Das Web setzt auf BEIDEN Flächen 300 —
   auf dem Artikel-Label wie auf dem Teilnahme-Label. Aufgefallen ist es nur
   dort, wo es dick aufträgt. Deshalb keine Ausnahme für die eine Fläche,
   sondern der richtige Wert für beide.
   ⚠️ „Dunkler" aus Stephans Fund ist die WIRKUNG des Gewichts, keine
   Farbdifferenz: `color` misst in beiden Modi rgb(34,34,39).
   ⚠️ Und es deckt sich mit dem Design-Kanon (§Typo: „Grundgewicht 300,
   Überschriften 400") — ein Feld-Label ist keine Überschrift.
   Die 18px, `display:block` und `margin-bottom:6px` BLEIBEN: die sind
   gemessene Web-Parität bzw. Stephans Abstands-Fund von heute Mittag. */
body.mb-app .comment-form-comment label[for="comment"] {
	display: block;
	margin-bottom: 6px;
	font-size: 18px;
	font-weight: 300;
	line-height: 1.4;
	color: var(--mb-ink, #222227);
}

/* ⚠️ 44px IST ABSICHT, KEINE ABWEICHUNG — nicht "auf Web-Mass" zurueckdrehen:
   Der Design-Kanon verlangt "Tap-Targets >= 44x44, Eingabefelder min-height:44px".
   Stephans Beobachtung "Feld groesser als im Web" ist richtig gesehen und
   gewollt (Entscheid Supervisor 28.08.).

   ⚠️ HIER STAND BIS 02.09. EINE BEGRUENDUNG, DIE SO NIE STIMMTE: "Das Web hat
   40px, weil dort eine Maus zielt." Gemessen am 01.09. hat das Web die 40px
   NICHT gewollt — es gibt dort ueberhaupt keine height-/min-height-Regel fuer
   das Feld; die 40 sind EMERGENT (2x8 padding + 2x1 border + 22 content).
   Der Satz erklaerte also eine Absicht, die niemand gefasst hatte. Das ist die
   teuerste Sorte Kommentar: er beantwortet die Frage, bevor sie jemand stellt,
   und verhindert damit genau die Messung, die den Fehler gezeigt haette.

   STAND DER FRAGE (Weitergabe Theme-Stream ueber Supervisor, 02.09.):
   Ab Theme 3.22.6 hat das Web-Feld MOBIL (390/Touch) ebenfalls 44px.
   ⚠️ 3.22.6 liegt in Stephans QUEUE, ist also NICHT live — solange gilt mobil
   weiter 40px im Web. Danach ist der Unterschied nur noch ein Desktop-Thema.
   Unsere Regel bleibt in beiden Welten unberuehrt: body.mb-app gegen
   body:not(.mb-app), beide (1,1,1), disjunkt (vom Theme-Stream geprueft).
   ⚠️ font-size: 16px ist harte Untergrenze, nicht Geschmack — darunter zoomt
   iOS beim Fokus in das Feld hinein. */
body.mb-app #comment {
	display: block;
	width: 100%;
	min-height: 44px;
	box-sizing: border-box;
	padding: 10px 12px;
	border: 1px solid var(--mb-linie, rgba(34, 34, 39, .14));
	border-radius: 3px;
	font-size: 16px;
	font-weight: 300;
	line-height: 1.4;
	resize: vertical; /* Wer viel schreibt, zieht selbst auf. */
}

/* ── Kommentar-Sektion: Abgrenzung nach oben ─────────────────────────────────
 * ⚠️⚠️ DER GRAUE BALKEN IST RAUS (Stephan-Entscheid 28.08.: „a) weg"). Er stand
 * hier seit dem 15.08. als Antwort auf „Die Kommentare stellen wir in der App
 * sehr unübersichtlich dar" — damals der Modul-Trenner der App-Startseite,
 * 8px Balken in `--mb-flaeche` plus 16px Polster, von Stephan ausdrücklich
 * freigegeben. Am Gerät hat er ihn dann als störend empfunden. **Der Entscheid
 * kippt den früheren; beide stehen hier, damit die nächste Runde nicht den
 * ersten „wiederherstellt".**
 *
 * ⚠️ DIE TRENNUNG BLEIBT, NUR OHNE LINIE. Der Balken war nicht Zierde, er war
 * Abstandshalter: Termine-Sektion und Erklärtexte sitzen unmittelbar darüber,
 * und die Kommentare wirkten sonst wie deren Fortsetzung. Seine 8px werden
 * deshalb NICHT gestrichen, sondern ins Polster verlegt (16px → 24px) — der
 * sichtbare Abstand bleibt gleich, der graue Streifen verschwindet.
 *
 * ⚠️ AM GERENDERTEN `/app/`-ARTIKEL GEMESSEN (28.08., voller Kaskaden-Stand mit
 * allen 42 Stylesheets in Live-Reihenfolge, `body.mb-app` gesetzt):
 *     vorher   Spalt 28px + Balken 8px + Polster 16px = 52px, graue Linie
 *     nachher  Spalt 28px + Polster 24px             = 52px, keine Linie
 * Der Spalt von 28px kommt NICHT aus `margin-top` allein — er entsteht mit dem
 * Wrapper darüber. Deshalb wurde er gemessen und nicht gerechnet; wer hier
 * schraubt, misst nach, statt zu addieren (Margen kollabieren).
 *
 * ⚠️ Gescopet auf `body.mb-app`: Im Web bleibt die Kommentar-Sektion unberührt.
 * Wir gleichen die APP-Ansicht an, nicht die Website. */
body.mb-app #comments {
	margin-top: 8px;
	padding-top: 24px;
}

/* ── GEWINNSPIELE: der Aufschlag von oben wird hier ZURÜCKGENOMMEN ───────────
 * ⚠️⚠️ WARUM DIESELBE FLÄCHE ZWEI ANTWORTEN BRAUCHT: Die 24px oben sind der
 * Ersatz für den grauen Balken (28.08.) — sie trennen die Kommentare von dem,
 * was darüber steht. Auf ARTIKELN steht darunter die sichtbare Überschrift
 * „N Responses", der Abstand liegt also ÜBER einer Überschrift und liest sich
 * als Sektions-Trennung.
 * Auf GEWINNSPIELEN verbirgt die Elementor-Vorlage genau diese Überschrift
 * (`.title-comments{display:none}` — in 15 von 15 Gewinnspielen über vier
 * Jahrgänge belegt, Positivkontrolle an zwei Artikeln: dort fehlt die Regel).
 * Sichtbar ist stattdessen ein Elementor-`<h3>` „N Teilnahmen" AUSSERHALB von
 * `#comments`. Die 32px liegen damit **nackt zwischen Widget und erster
 * Teilnahme**.
 *
 * ⚠️ AM LIVE-DOM GEMESSEN (30.08., Gast, 390x753, gleiche Seite, einziger
 * Unterschied das `/app/`-Präfix):
 *     Web   #comments oben 0 / 0     Nachbar -> 1. Zeile   77,59px
 *     App   #comments oben 8 / 24    Nachbar -> 1. Zeile  109,59px
 *                                    Differenz            +32,00px
 * Stephans Wort dazu (30.08.): „b) bitte wie empfohlen".
 *
 * ⚠️ WAS HIER NICHT PASSIERT: Der Artikel bleibt unverändert. Und auf einer
 * hypothetischen Gewinnspiel-Seite mit SICHTBARER Überschrift stellte diese
 * Regel den WEB-Zustand her (das Web hat den Aufschlag nirgends) — verloren
 * ginge nur die App-Extra-Trennung, keine Web-Parität.
 *
 * ⚠️ Die Klasse ist UNSERE (`AppModeController::GS_KLASSE`), gesetzt über den
 * dokumentierten Vertrag `mb_gewinnspiel/is_contest`. Sie ist bewusst NICHT die
 * fremde `mb-gs`: Die gehört gewinnspiel, ist kein Vertrag, und eine Umbenennung
 * dort liesse diesen Abstand STILL zurückkippen. */
body.mb-app.mb-app-gs #comments {
	margin-top: 0;
	padding-top: 0;
}

/* ── Quittung nach dem Absenden ──────────────────────────────────────────────
 * ⚠️ SIE ERSETZT DAS FORMULAR, sie steht nicht darunter (siehe `fertig()` in
 * app-state.js) — ein leeres Feld unter der eigenen Quittung lädt zum zweiten,
 * identischen Kommentar ein. Das war Teil 2 des Gerätefunds.
 *
 * ⚠️ DIE ZUSTÄNDE ÄNDERN NUR DIE KANTE, NIE DIE SCHRIFTFARBE: #222227 auf
 * #F5F5F5 sind gerechnet 14,53:1 — das gilt in JEDEM Zustand. Wer den
 * Fehlerfall stattdessen orange EINFÄRBT, verliert genau dann die Lesbarkeit,
 * wenn der Text am wichtigsten ist. Der Kantenbalken ist ohnehin das Hausmuster.
 * Er selbst kommt auf 3,02:1 gegen die Fläche — über der 3:1-Schwelle für
 * grafische Elemente, aber knapp; er ist deshalb bewusst nur VERSTÄRKUNG der
 * Aussage, nie ihr einziger Träger (der Text sagt den Fehler selbst). */
body.mb-app .mb-app-comment-msg {
	margin: 0 0 12px;
	padding: 12px;
	border-radius: 3px;
	background: var(--mb-flaeche, #F5F5F5);
	font-size: 14px;
	font-weight: 400;
	line-height: 1.4;
	color: var(--mb-ink, #222227);
}

body.mb-app .mb-app-comment-msg[data-mb-art="fehler"] {
	box-shadow: inset 3px 0 0 var(--mb-orange, #E36A34);
}
