/*
 * Compendion Content-Card – eine Card-Komponente fuer Inhalts-Listen.
 *
 * Spec: docs/superpowers/specs/2026-05-20-content-card-familie-design.md
 *
 * Architektur in Stichworten:
 *   - Markup-Wurzel ist `.compendion-content-card` (z.B. `<li>` oder `<article>`).
 *     Sie ist Container-Query-Container (`container-type: inline-size`).
 *   - Innen liegt der `<a>` mit Klasse `__link` als komplette Klickflaeche.
 *   - Modifier `.compendion-content-card--landscape` kennzeichnet Cards mit
 *     horizontalem Layout (Cover rechts, Body links). Default-Form (ohne
 *     Modifier) ist Portrait (Cover oben, Body darunter).
 *   - Markup-Reihenfolge im Link: Media, Body, Contributors-Strip – als drei
 *     Top-Level-Siblings. Body enthaelt Datum, Titel, Meta. Contributors-Strip
 *     ist Sibling, NICHT im Body – damit Body-Hoehe in Landscape kapselbar
 *     bleibt und die Card kontrolliert um exakt die Strip-Hoehe waechst.
 *   - Landscape-Card-Hoehe: ~110px ohne Strip; +35px+gap mit einzeiligem Strip
 *     (~151px); +70px+gap mit zweizeiligem Strip (~190px). Body-Inhalt bleibt
 *     in der oberen Row auf 110px gekapselt.
 *   - Mitwirkende-Strip ist Flex-Row mit wrap, 35x35px-Avataren – identisch in
 *     Portrait und Landscape. Border 1px in Primary-Color am Avatar.
 *
 * Tokens aus theme.json – keine Hardcoded-Farben.
 */

/* === Card-Grid-Wrapper – EIN Grid fuer ALLE Content-Card-Listen (DRY) ===
 *
 * Dieser Komma-Selektor ist die einzige Grid-Wahrheit fuer jede Liste, die
 * `compendion_render_content_card()` aufnimmt. Neue Listen-Render-Pfade haengen
 * sich hier an, statt eine eigene `grid-template-columns`-Regel anzulegen –
 * sonst entsteht Wrapper-Drift (Memory feedback_card_wrapper_grid_drift). CSS
 * wird global geladen (functions.php → `compendion-content-card`), liegt also
 * auf jeder Frontend-Seite vor (Anderswo, Person-Profil, Dachseiten-Episoden).
 *
 * Verhalten (Memory feedback_content_card_responsive):
 *   - Default: 1 Spalte → eine HORIZONTALE (landscape) Card ueber volle Breite.
 *   - Ab ≥600px Breite UND ≥572px Hoehe: auto-fill minmax(270px, 1fr) →
 *     sobald zwei Spalten passen, kippen die Cards auf VERTIKAL (Portrait,
 *     Cover oben). Schwelle 270px = Variante A (2 Spalten ab ~560px Breite).
 *
 * Drei gekoppelte Werte – IMMER zusammen aendern:
 *   1. Grid-minmax (hier: 270px)
 *   2. @media-Schwellen (min-width: 600px / min-height: 572px, weiter unten am
 *      Card-Toggle)
 *   3. Card-Container-Query (max-width: 480px, am Portrait-Toggle) – muss
 *      oberhalb der breitesten 2-Spalten-Card (~429px kurz vor dem
 *      3-Spalten-Sprung) liegen, sonst bleiben breite 2-Spalten-Cards faelsch-
 *      lich horizontal.
 *
 * Warum min-height: 572px (NICHT entfernen – Arne-Wunsch 2026-05-29):
 *   Auf quergehaltenen Mobiltelefonen (breiter Viewport, geringe Hoehe) sollen
 *   HORIZONTALE Cards erscheinen, auch wenn die nominelle Breite fuer mehrere
 *   vertikale Cards reichen wuerde. Vertikale Cards wuerden im Querformat oben/
 *   unten abgeschnitten; eine horizontale Card passt voll auf den Schirm. Die
 *   niedrige Viewport-Hoehe unterdrueckt deshalb das Portrait-Grid.
 */
.compendion-latest-network-episodes,
.wp-block-post-template.compendion-episode-grid,
.compendion-person-profile__episodes-list,
.ccl-cards {
	display: grid;
	grid-template-columns: 1fr;
	gap: clamp(0.75rem, 2vw, 1.25rem);
	list-style: none;
	margin: 0;
	padding: 0;
}

@media (min-width: 600px) and (min-height: 572px) {
	.compendion-latest-network-episodes,
	.wp-block-post-template.compendion-episode-grid,
	.compendion-person-profile__episodes-list,
	.ccl-cards {
		grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
	}
}

/* post-template wickelt jedes Item in `<li class="wp-block-post">`. Die
 * tatsaechliche Card kommt aus `compendion/episode-card` und ist heute ein
 * `<article>` (vom Content-Card-Renderer, wrapper=article). Das outer-`<li>`
 * bleibt unsichtbarer Pass-Through-Container. */
.wp-block-post-template.compendion-episode-grid > .wp-block-post {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
}

.wp-block-post-template.compendion-episode-grid > .wp-block-post > .compendion-content-card {
	flex: 1;
}

.compendion-latest-network-episodes--empty {
	color: var(--c-on-base-muted);
}

.compendion-content-card {
	container-type: inline-size;
	container-name: card;
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	/* SSOT fuer die Cover-Slot-Hoehe der Landscape-Card (Fundus):
	 * hoehengesteuert, Breite folgt dem Bildverhaeltnis. Compact-V (Rail)
	 * nutzt den ratio-getriebenen 16/9-Basis-Slot (Arne 2026-07-17, loest
	 * den hoehengesteuerten 4rem-Slot ab). */
	--content-card-landscape-h: 5.5rem;
}

.compendion-content-card__link {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: 0.4rem;
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 5%, transparent);
	border-radius: 0.5rem;
	/* Karten-Schatten netzweit (Arne 2026-06-12): der 5%-Tint allein laesst
	 * die Karte auf kraeftigen Seitenfarben (gelbe Dachmarke) mit dem
	 * Hintergrund verschmelzen. Dunkler Ring + Drop-Shadow trennen die
	 * Kartenflaeche auf jeder Ebene; feste Schwarz-Alphas, weil die
	 * Hintergrundfarbe beliebig ist. */
	box-shadow:
		0 2px 12px rgba(0, 0, 0, 0.25),
		0 0 0 1px rgba(0, 0, 0, 0.12);
	color: inherit;
	text-decoration: none;
	transition: background 150ms ease, transform 150ms ease;
}

.compendion-content-card__link:hover,
.compendion-content-card__link:focus-visible {
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 9%, transparent);
	transform: translateY(-1px);
	outline: none;
}

.compendion-content-card__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent, currentColor);
	outline-offset: 2px;
}

/* Dachmarken-Startseite: der 5%-Tint der geteilten Komponente ist auf der
 * Master-Front zu blass – die Cards heben sich kaum vom Sektions-Hintergrund ab.
 * Nur hier (Scope `.compendion-home-master`) staerker: mehr Fuellung + zarter
 * Rahmen. Palette-sicher ueber den contrast-Token (greift in Light wie Dark), die
 * geteilte Komponente bleibt fuer alle anderen Listen unveraendert. */
.compendion-home-master .compendion-content-card__link {
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 8%, transparent);
	border: 1px solid var(--c-page-border);
}

.compendion-home-master .compendion-content-card__link:hover,
.compendion-home-master .compendion-content-card__link:focus-visible {
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 12%, transparent);
	border-color: var(--c-page-border);
}


/* `__media` ist der definite 16/9-Slot, der das Cover zentriert ablegt – feste
 * Slot-Groesse => das Grid bleibt zeilenweise einheitlich, egal welches Bild-
 * Seitenverhaeltnis drin sitzt. Border + Border-Radius gehoeren aufs Cover
 * selbst (nicht auf den Slot), damit der Rahmen direkt am Bild klebt statt um
 * leere Slot-Flaeche. `overflow: visible` (vorher hidden, 2026-06-12): der
 * Cover-Glow (box-shadow am Bild, unten) wuerde sonst restlos weggeclippt,
 * sobald das Bild den Slot exakt fuellt. Gefahrlos: im Box-=-Bildverhaeltnis-
 * Modell (max-width/height:100%) waechst das Bild selbst nie ueber den Slot. */
.compendion-content-card__media {
	width: 100%;
	aspect-ratio: 16 / 9;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: visible;
}

/* Das Cover-`<img>` traegt KEIN object-fit und KEIN erzwungenes aspect-ratio
 * (frueher pro `data-ar`-Bucket gesetzt): mit `width/height: auto` + `max-*:
 * 100%` nimmt die `<img>`-Box exakt das ECHTE Bild-Seitenverhaeltnis an und
 * schrumpft passend in den 16/9-Slot. Folge: der Rahmen (outline) klebt direkt
 * am Bild – kein Spalt, keine Letterbox zwischen Rahmen und Bild (anders als bei
 * object-fit:contain, wo die `<img>`-Box den ganzen Slot fuellt und das Bild
 * darin schwebt, sodass der Rahmen um die leere Box sass). Kein Crop (Arne-Regel
 * feedback_keine_cover_crops): weil die Box = Bildverhaeltnis ist, wird nie
 * beschnitten, nur die Box selbst wird kleiner als der Slot. */
.compendion-content-card__cover {
	box-sizing: border-box;
	display: block;
	/* outline + negative outline-offset statt border: `.__cover` ist ein `<img>`-
	 * Element (Replaced Element). `box-shadow:inset` zeichnet hinter dem Bild-
	 * Inhalt – wird nicht zuverlaessig sichtbar (Bild ueberlagert die Inset-
	 * Shadow). `border` hat sichtbares Anti-Aliasing-Verluestchen an gerundeten
	 * Eckpunkten. `outline` mit `outline-offset:-1px` zeichnet ueber dem Bild-
	 * Inhalt, behaelt Linienstaerke an Ecken (outline respektiert border-radius
	 * in allen modernen Browsern). */
	outline: 1px solid var(--compendion-card-accent, var(--compendion-podlove-accent, var(--wp--preset--color--primary)));
	outline-offset: -1px;
	border-radius: 0.375rem;
	/* Cover-Glow fuer ALLE Card-Cover (Arne 2026-06-12, vorher nur compact-v):
	 * weisser Ring + dunkler Schein, neutral statt Token/Brand-Farbe - muss
	 * vor jedem Hintergrund (gelbe Dachmarke, Light, Dark) sichtbar sein.
	 * Setzt overflow:visible am __media-Slot voraus (oben). */
	box-shadow:
		0 0 0 2px rgba(255, 255, 255, 0.85),
		0 0 6px 3px rgba(0, 0, 0, 0.5);
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
}

.compendion-content-card__cover--empty {
	/* Ersatz-Cover ohne Bild (2026-10-22): quadratisch (data-ar 1x1 aus PHP/JS),
	   Zufallsmuster je Eintrag. data-pattern (0-5) waehlt die Form, die Inline-
	   Variablen --cmp-fb-angle/--cmp-fb-mix kommen aus der Eintrags-ID
	   (compendion_content_card_fallback_pattern). Farben nur aus Akzent + base,
	   damit Palette und Dunkelmodus greifen. */
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	padding: 0.6rem;
	/* Rahmen: Outline + Glow wie jedes Cover (Basisregel), kein eigener Schatten. */
	border-radius: 0.375rem;
	background-color: var(--wp--preset--color--base);
	overflow: hidden;
}

/* Cover-Groesse unabhaengig von der Eigengroesse des Bildes (2026-10-22).
   Mit width/height:auto stand ein Cover in der Groesse, die der Browser aus
   srcset/sizes errechnet. Sofort geladene Cards tragen sizes="200px", lazy
   geladene "auto, 200px" - war der Kasten breiter (groessere Grundschrift,
   Safari-Rechnung), blieben einzelne Cover klein (MWM „Starte hier“ #51) oder
   ein 100-px-Quellbild (Podcast-Faible) stand in Originalgroesse. Jetzt fuellen
   Breitformate die Kastenbreite, Quadrat/4:3 die Kastenhoehe. */
/* Ohne max-Kappung und ohne object-fit (2026-10-22): das Element muss genau
   das Bild umschliessen, damit Rahmen/Glow eng am Bild sitzen. Ein Bild
   breiter als 16:9 wird bei voller Breite nie hoeher als der Kasten, ein
   Bild schmaler als 16:9 bei voller Hoehe nie breiter. Safari zog mit Kappung
   + object-fit das Element auf Kastenhoehe (Rahmen um den Kasten statt ums
   Bild, MWM-Cover zu gross). Falsch eingestufte Bilder (Format ≠ Bucket)
   behebt der Cover-Sideload, nicht das CSS.
   Nur im 16:9-Kasten (compact-v, Portrait). Die Landscape-Card im Querformat
   hat einen hoehengesteuerten Kasten ohne feste Breite – dort bleibt ihre
   eigene Regel (height:100%, Breite folgt dem Bild), sonst verzerrt es. Die
   Portrait-Toggles der Landscape-Card holen die Regeln unten wieder herein. */
.compendion-content-card:not(.compendion-content-card--landscape) .compendion-content-card__media:is([data-ratio="16x9"], [data-ratio="221x1"]) > .compendion-content-card__cover {
	width: 100%;
	height: auto;
}

.compendion-content-card:not(.compendion-content-card--landscape) .compendion-content-card__media:is([data-ratio="1x1"], [data-ratio="4x3"]) > .compendion-content-card__cover {
	height: 100%;
	width: auto;
}


/* Ersatz-Cover ohne Bild hat keine Eigengroesse: Quadrat erzwingen. */
.compendion-content-card__media[data-ratio="1x1"] > .compendion-content-card__cover--empty {
	aspect-ratio: 1 / 1;
}

.cmp-pattern {
	/* Zufallsmuster (2026-10-22), geteilt von Ersatz-Covern und Initialen-
	   Avataren. Alle Merkmale kommen aus dem Startwert
	   (compendion_pattern_attrs, JS-Spiegel patternAttrs):
	   data-pattern 0-9 = Form, data-ink 0-2 = Farbton, inline --cmp-fb-angle
	   (Winkel), --cmp-fb-mix (Staerke), --cmp-fb-scale (Dichte), --cmp-fb-x/-y
	   (Mittelpunkt). Luecken transparent: das Element behaelt seine eigene
	   Hintergrundfarbe. Farbtoene nur aus Akzent + Kontrast, sonst auf der
	   Dachmarke Gelb auf Gelb. */
	--fb-accent: var(--compendion-card-accent, var(--compendion-podlove-accent, var(--wp--preset--color--primary)));
	--fb-contrast: var(--wp--preset--color--contrast);
	--fb-ink: color-mix(in srgb, var(--fb-accent), var(--fb-contrast) 45%);
	--fb-a: color-mix(in srgb, var(--fb-ink) var(--cmp-fb-mix, 40%), transparent);
	/* Mustereinheit relativ zur Flaeche (Prozent statt rem): dasselbe Muster
	   sieht auf dem 35-px-Kreis und der 220-px-Karte gleich aus, grosse Stufen
	   werden auf kleinen Avataren nicht zur Einfarb-Flaeche. Untergrenze 3 px. */
	--fb-u: max(3px, calc(4% * var(--cmp-fb-scale, 1)));
	--fb-line: max(1px, calc(1% * var(--cmp-fb-scale, 1)));
	--fb-at: var(--cmp-fb-x, 50%) var(--cmp-fb-y, 50%);
}

.cmp-pattern[data-ink="1"] {
	/* kraeftig: fast Kontrastfarbe */
	--fb-ink: color-mix(in srgb, var(--fb-accent) 10%, var(--fb-contrast));
}

.cmp-pattern[data-ink="2"] {
	/* mittel. Bewusst kein aufgehellter Ton: der war auf hellem Grund
	   (gelbe Dachmarke) fast unsichtbar. Alle drei Toene mischen Kontrast in
	   den Akzent und heben sich so hell wie dunkel ab. */
	--fb-ink: color-mix(in srgb, var(--fb-accent), var(--fb-contrast) 65%);
}

/* Initialen-Avatare: fester Grund und Musterfarbe aus der Seitenpalette statt
   aus der Umgebung. Die Avatar-Stile der einzelnen Stellen setzen teils eigene
   Hintergruende, und die Karten-Akzentfarbe ist je Show verschieden (DML:
   weiss) – weisses Muster auf weissem Kreis war unsichtbar (DML042, Jenni).
   Grundfarbe + Primaerfarbe/Kontrast sind auf jeder Palette ein Kontrastpaar. */
.cmp-pattern.cmp-pattern--initials {
	--fb-accent: var(--wp--preset--color--primary);
	background-color: var(--wp--preset--color--base);
}

/* Feste Personenfarben aus der Palette der Heimat-Show (fruehester Auftritt,
   compendion_pattern_person_palette): Grund, Muster und Schild sehen auf
   jeder Seite gleich aus, unabhaengig von der Palette der aktuellen Site und
   vom Farbmodus (Arne 2026-10-22). Hoehere Spezifitaet als die
   Kontext-Regeln (Seite, Podcast-Regal). */
.cmp-pattern.cmp-pattern--initials.cmp-pattern--pal {
	--fb-accent: var(--fb-pal-accent);
	--fb-contrast: var(--fb-pal-text);
	background-color: var(--fb-pal-base);
}

.cmp-pattern--pal .cmp-pattern__plate {
	background: var(--fb-pal-base);
	color: var(--fb-pal-text);
}

/* Schild fuer Initialen: Buchstaben auf Grundfarbe, wie das Schild des
   Ersatz-Covers – lesbar auf jedem Muster und Umgebungshintergrund. Groessen
   in em, damit es mit der Avatar-Schrift mitwaechst (35 px bis 220 px). */
.cmp-pattern__plate {
	display: inline-block;
	padding: 0.12em 0.32em;
	border-radius: 0.3em;
	background: var(--wp--preset--color--base);
	color: var(--c-on-base, var(--wp--preset--color--contrast));
	line-height: 1;
	box-shadow: 0 1px 3px rgb(0 0 0 / 0.18);
}

/* 0 Streifen */
.cmp-pattern[data-pattern="0"] {
	background-image: repeating-linear-gradient(var(--cmp-fb-angle, 45deg), var(--fb-a) 0 var(--fb-u), transparent var(--fb-u) calc(var(--fb-u) * 2));
}

/* 1 Punkte */
.cmp-pattern[data-pattern="1"] {
	background-image: radial-gradient(circle, var(--fb-a) 32%, transparent 34%);
	background-size: calc(var(--fb-u) * 1.7) calc(var(--fb-u) * 1.7);
	background-position: var(--fb-at);
}

/* 2 Ringe um einen versetzten Mittelpunkt */
.cmp-pattern[data-pattern="2"] {
	background-image: repeating-radial-gradient(circle at var(--fb-at), var(--fb-a) 0 calc(var(--fb-u) * 0.8), transparent calc(var(--fb-u) * 0.8) calc(var(--fb-u) * 1.6));
}

/* 3 Schachbrett, gedreht */
.cmp-pattern[data-pattern="3"] {
	background-image: conic-gradient(from var(--cmp-fb-angle, 0deg), var(--fb-a) 25%, transparent 0 50%, var(--fb-a) 0 75%, transparent 0);
	background-size: calc(var(--fb-u) * 2.3) calc(var(--fb-u) * 2.3);
}

/* 4 Strahlen aus einem versetzten Mittelpunkt */
.cmp-pattern[data-pattern="4"] {
	background-image: repeating-conic-gradient(from var(--cmp-fb-angle, 0deg) at var(--fb-at), var(--fb-a) 0 calc(10deg * var(--cmp-fb-scale, 1)), transparent calc(10deg * var(--cmp-fb-scale, 1)) calc(20deg * var(--cmp-fb-scale, 1)));
}

/* 5 Gitter */
.cmp-pattern[data-pattern="5"] {
	background-image:
		linear-gradient(var(--cmp-fb-angle, 0deg), var(--fb-a) calc(var(--fb-line) * 2.5), transparent calc(var(--fb-line) * 2.5)),
		linear-gradient(calc(var(--cmp-fb-angle, 0deg) + 90deg), var(--fb-a) calc(var(--fb-line) * 2.5), transparent calc(var(--fb-line) * 2.5));
	background-size: calc(var(--fb-u) * 1.4) calc(var(--fb-u) * 1.4);
}

/* 6 Nadelstreifen: duenne Linien, weite Abstaende */
.cmp-pattern[data-pattern="6"] {
	background-image: repeating-linear-gradient(var(--cmp-fb-angle, 45deg), var(--fb-a) 0 calc(var(--fb-line) * 1.5), transparent calc(var(--fb-line) * 1.5) calc(var(--fb-u) * 1.3));
}

/* 7 Zickzack */
.cmp-pattern[data-pattern="7"] {
	background-image:
		linear-gradient(135deg, var(--fb-a) 25%, transparent 25%),
		linear-gradient(225deg, var(--fb-a) 25%, transparent 25%),
		linear-gradient(315deg, var(--fb-a) 25%, transparent 25%),
		linear-gradient(45deg, var(--fb-a) 25%, transparent 25%);
	background-size: calc(var(--fb-u) * 2) calc(var(--fb-u) * 2);
	background-position: calc(var(--fb-u) * -1) 0, calc(var(--fb-u) * -1) 0, 0 0, 0 0;
}

/* 8 Grosse Kreise, versetzt. Radien relativ zur Flaeche (nicht in rem):
   die Form besteht nur aus wenigen Kreisen und waere bei kleiner
   Groessenstufe sonst fast leer (Jenni, 2026-10-22). Radius 28-60 % je nach
   Stufe, dazu ein dritter kleiner Kreis. */
.cmp-pattern[data-pattern="8"] {
	--fb-r: calc(28% + 9% * var(--cmp-fb-scale, 1));
	background-image:
		radial-gradient(circle at var(--fb-at), var(--fb-a) 0 var(--fb-r), transparent calc(var(--fb-r) + 1px)),
		radial-gradient(circle at calc(100% - var(--cmp-fb-x, 50%)) calc(100% - var(--cmp-fb-y, 50%)), var(--fb-a) 0 calc(var(--fb-r) * 0.55), transparent calc(var(--fb-r) * 0.55 + 1px)),
		radial-gradient(circle at var(--cmp-fb-y, 50%) calc(100% - var(--cmp-fb-x, 50%)), var(--fb-a) 0 calc(var(--fb-r) * 0.3), transparent calc(var(--fb-r) * 0.3 + 1px));
}

/* 9 Rauten */
.cmp-pattern[data-pattern="9"] {
	background-image: conic-gradient(from 45deg at 50% 50%, var(--fb-a) 25%, transparent 0 50%, var(--fb-a) 0 75%, transparent 0);
	background-size: calc(var(--fb-u) * 1.8) calc(var(--fb-u) * 3);
	background-position: var(--fb-at);
}

/* Schild mit Symbol und Quellname: ruhige Flaeche ueber dem Muster. */
.compendion-content-card__cover-plate {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.3rem;
	max-width: 100%;
	padding: 0.45rem 0.6rem;
	border-radius: 0.375rem;
	background: var(--wp--preset--color--base);
	color: var(--c-on-base, var(--wp--preset--color--contrast));
	box-shadow: 0 1px 4px rgb(0 0 0 / 0.18);
	text-align: center;
}

/* Symbol als Maske in Textfarbe; Pfade wie nav-icons.php bzw. Heroicons. */
.compendion-content-card__cover-plate::before {
	content: "";
	width: 1.4rem;
	height: 1.4rem;
	flex: none;
	background: currentColor;
	opacity: 0.75;
	-webkit-mask: var(--cmp-cover-icon) center / contain no-repeat;
	mask: var(--cmp-cover-icon) center / contain no-repeat;
}

.compendion-content-card__cover--empty[data-kind="podcast"] { --cmp-cover-icon: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.5%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M12 18.75a6 6 0 0 0 6-6v-1.5m-6 7.5a6 6 0 0 1-6-6v-1.5m6 7.5v3.75m-3.75 0h7.5M12 15.75a3 3 0 0 1-3-3V4.5a3 3 0 1 1 6 0v8.25a3 3 0 0 1-3 3Z%22/%3E%3C/svg%3E"); }
.compendion-content-card__cover--empty[data-kind="video"] { --cmp-cover-icon: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.5%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z%22/%3E%3Cpath d=%22m9.9 8.4 6 3.6-6 3.6V8.4Z%22/%3E%3C/svg%3E"); }
.compendion-content-card__cover--empty[data-kind="artikel"] { --cmp-cover-icon: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.5%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z%22/%3E%3C/svg%3E"); }
.compendion-content-card__cover--empty[data-kind="link"] { --cmp-cover-icon: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%221.5%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244%22/%3E%3C/svg%3E"); }

.compendion-content-card__cover-name {
	max-width: 100%;
	overflow-wrap: anywhere;
	font-weight: 700;
	font-size: 0.8rem;
	line-height: 1.15;
}

.compendion-content-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	padding: 0.15rem 0.35rem 0.35rem;
	min-width: 0;
	flex: 1;
}

.compendion-content-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.3rem;
	/* Meta (Podcasttag) klebt am Body-Boden – Titel ist das einzige
	 * variable Element, alle anderen sind fix positioniert. In Landscape
	 * fuellt Body die 110px-Row aus, margin-top:auto schiebt die Meta-Zeile
	 * an den unteren Rand. In Portrait ist Body content-driven, margin-top:
	 * auto bleibt wirkungslos (kein Extra-Raum zum Verteilen). */
	margin-top: auto;
}

.compendion-content-card__badge {
	display: inline-block;
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 12%, transparent);
	padding: 0.15rem 0.6rem;
	border-radius: 999px;
	font-weight: 600;
	font-size: 0.9rem;
	line-height: 1.4;
	color: var(--wp--preset--color--contrast, inherit);
}

.compendion-content-card__badge--external {
	background: transparent;
	border: 1px solid var(--c-page-border);
}

.compendion-content-card__source {
	font-size: 0.9rem;
	color: var(--c-on-base-muted);
}

.compendion-content-card__source-domain {
	font-weight: 600;
}

.compendion-content-card__date {
	font-size: 0.9rem;
	color: var(--c-on-base-muted);
	font-variant-numeric: tabular-nums;
	line-height: 1.3;
}

.compendion-content-card__title {
	font-size: 1.3rem;
	font-weight: 600;
	line-height: 1.3;
	color: var(--wp--preset--color--contrast, inherit);
	margin: 0;
	margin-top: 0.15rem;
	/* 2 Zeilen feste Hoehe (line-height 1.3 × 2) haelt das Grid zeilenweise
	 * einheitlich (Portrait: 3 Zeilen = 3.9em, Landscape/compact-v: 2 Zeilen = 2.6em, siehe unten). Zusaetzlich line-clamp (Arne 2026-10-01): ein zu langer Titel
	 * endet in der zweiten Zeile mit "…" statt mitten im Wort hart abgeschnitten
	 * zu werden (vorher nur height+overflow:hidden = keine Ellipse). Der volle
	 * Titel bleibt im DOM (Screenreader, Suche, Tooltip). Keine Hyphens, daher
	 * kein Reflow-Timing-Problem. */
	height: 3.9em;
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	line-clamp: 3;
	overflow: hidden;
	text-overflow: ellipsis;
	overflow-wrap: break-word;
}

/* Drei Titelzeilen fuer Portrait- und compact-v-Cards (Arne 2026-10-01: lange
 * Titel, v. a. Serienpodcasts, sollen nicht abgeschnitten werden; gemessen: bei
 * compact-v (Titelbreite 184 px) wurden mit zwei Zeilen 19 von 34 GHU-Titeln
 * abgeschnitten, mit drei nur 1). Landscape (Cover rechts kompakt, /episoden)
 * bleibt bei zwei Zeilen mit Ellipse. */
.compendion-content-card--landscape .compendion-content-card__title {
	height: 2.6em;
	-webkit-line-clamp: 2;
	line-clamp: 2;
}

/* Avatare fix 35x35px (1:1, Memory feedback_avatare_quadratisch) – bewusst keine
 * clamp/min/max-Spreizung, damit alle Avatare ueber alle Card-Konstellationen
 * identisch gross sind. Markup-Aufbau des Strips: siehe Baum-Beschreibung unten. */

/* === Contributors-Strip (flach) ===
 *
 * `flex nowrap; overflow:hidden`. DOM-Reihenfolge = visuelle Reihenfolge:
 *   typ-tag · von · hosts · mit · guests (kein Rollenwort: der Strip kennt nur
 *   die Rolle je Person und Show, nicht die der Episode; Arne 2026-10-19).
 * Das Fitting bei Platzmangel erledigt das globale JS
 * `assets/js/compendion-content-card.js` (browseruebergreifend – CSS scroll-state
 * war Chromium-only): es setzt `.__strip-shed` (display:none) der Reihe nach auf
 * typ-tag → byline2 → byline1 → guests, bis der Strip passt;
 * hosts (Kern) bleibt immer. `overflow:hidden` ist die graceful Schranke, falls
 * das JS (noch) nicht lief. `min-width:0`, damit der Strip als Grid-/Flex-Element
 * schmaler als sein Inhalt werden darf (sonst kein messbarer Overflow). */
.compendion-content-card__contributors {
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	align-items: center;
	gap: 0.4rem 0.5rem;
	margin-top: 0.25rem;
	min-width: 0;
	overflow: hidden;
}

/* Vom Fit-JS ausgeblendete Strip-Elemente. */
.compendion-content-card__strip-shed { display: none !important; }

/* Avatar-Gruppe: Flex-Item im Strip, Avatare nebeneinander; schrumpft nicht
 * (Fitting laeuft per display:none, nicht per Schrumpfen). */
.compendion-content-card__contributors-group {
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	gap: 0.25rem;
	align-items: center;
	flex: 0 0 auto;
}

/* Typus-Pille im Strip (z. B. „Episode"): Outline-Pille (Design-Regel 3). */
.compendion-content-card__strip-type {
	flex: 0 0 auto;
	padding: 0.1rem 0.55rem;
	border: 1px solid var(--c-page-border);
	border-radius: 999px;
	font-size: 0.72rem;
	font-weight: 600;
	line-height: 1.4;
	letter-spacing: 0.02em;
	white-space: nowrap;
	color: var(--c-on-base-muted);
	background: transparent;
}

/* === Praepositions-Text ("von" / "mit" / "ueber") ===
 * Schrift/Italic/Farbe + Flex-Layout im Strip. Auch von anderen Render-Pfaden
 * genutzt (z. B. episode-single). */
.compendion-preposition {
	flex: 0 0 auto;
	align-self: center;
	white-space: nowrap;
	font-size: 0.85rem;
	font-style: italic;
	line-height: 1;
	color: var(--c-on-base-muted);
}

.compendion-content-card__contributor-avatar {
	box-sizing: border-box;
	width: 35px;
	height: 35px;
	aspect-ratio: 1 / 1;
	/* outline + outline-offset:-1px – siehe Begruendung am `.__cover`-Block.
	 * Avatar ist `<img>`-Replaced-Element, box-shadow:inset waere unsichtbar. */
	outline: 1px solid var(--compendion-card-accent, var(--compendion-podlove-accent, var(--wp--preset--color--primary)));
	outline-offset: -1px;
	border-radius: 0.5rem;
	/* Personen-Avatar: cover (fuellt die 1:1-Box). no-crop gilt nur fuer Cover. */
	object-fit: cover;
	flex-shrink: 0;
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 8%, transparent);
	display: block;
}

/* Initialen-Fallback fuer Mitwirkende ohne Avatar-Bild. Gleiche Box-Geometrie
 * wie das Foto (35px, 1:1, abgerundetes Quadrat – feedback_avatare_quadratisch),
 * nur als <span> mit zentrierten Initialen und kraeftiger Akzent-Fuellung. */
.compendion-content-card__contributor-avatar--initials {
	display: flex;
	align-items: center;
	justify-content: center;
	object-fit: initial;
	font-size: 0.72rem;
	font-weight: 600;
	line-height: 1;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	/* Akzent als Vollfuellung, Text in base – beide Tokens kippen gegenlaeufig
	 * mit dem Color-Scheme (card-accent ueber den Dark-Override unten, base ueber
	 * compendion-dark.css). Da der Akzent per WCAG gegen die Card-Flaeche (≈ base)
	 * getunt ist, kontrastiert base-Text gegen Akzent-Fuellung in beiden Modi.
	 * Vorher: Text UND Hintergrund aus derselben Akzent-Variable (14%-Tint) →
	 * kein Kontrast. */
	color: var(--wp--preset--color--base, #fff);
	background: var(--compendion-card-accent, var(--compendion-podlove-accent, var(--wp--preset--color--primary)));
}

/* === Landscape-Modifier: horizontales Layout ===
 *
 * Link wird zum CSS-Grid mit zwei Rows:
 *   Row 1: Body links | Media rechts – fix 110px hoch (alter Landscape-Stand)
 *   Row 2: Contributors-Strip – auto-Hoehe (35px+gap einzeilig, 70px+gap bei
 *          zweizeiligem Wrap)
 *
 * Damit kapselt die obere Row Body+Media auf die fruehere 110px-Hoehe; die
 * Card waechst exakt um die Strip-Hoehe statt unkontrolliert mit dem Titel.
 *
 * Cover: Grid-Column "media", aspect-ratio via [data-ratio]; align-self:start
 * + max-height:100% damit es nicht aus der 110px-Row ausbricht.
 *
 * Body: Grid-Column "body", overflow:hidden + 2-Zeilen-Title-Clamp halten ihn
 * in der Row. Font-Sizes auf clamp() wie zuvor, damit lange Titel skalierbar
 * bleiben.
 */
.compendion-content-card--landscape .compendion-content-card__link {
	display: grid;
	/* Body nimmt den Rest; Media-Spalte folgt der nativen Cover-Breite
	 * (= Cover-Aspect-Ratio × 110px-Row-Hoehe). Damit gibt es keinen leeren
	 * 16/9-Slot um ein 1:1-Cover. Cap kommt per max-width am Media-Element. */
	grid-template-columns: 1fr auto;
	grid-template-rows: auto auto;
	grid-template-areas:
		"body  media"
		"strip strip";
	gap: 0 0.75rem;
	padding: 0.5rem;
	align-items: stretch;
}

/* `__media` ist im Landscape KEIN aspect-ratio-Slot mehr, sondern ein
 * transparenter Wrapper, der genau die native Cover-Groesse annimmt: Hoehe =
 * Row-Hoehe (110px), Breite = Cover-Aspect-Ratio × Hoehe. `max-width: 50cqw`
 * deckelt extrem breite Covers (2.21:1), damit der Body-Bereich nicht
 * unleserlich schrumpft. */
.compendion-content-card--landscape .compendion-content-card__media {
	grid-area: media;
	/* Bild fix hoch, oben buendig – kein Spanning ueber Contributors-Strip.
	 * Hoehe kommt aus dem SSOT --content-card-landscape-h (oben). */
	align-self: start;
	aspect-ratio: auto;
	width: auto;
	height: var(--content-card-landscape-h);
	max-width: 50cqw;
}

/* Cover im hoehengesteuerten Landscape-Slot: Slot-Hoehe diktiert das Cover –
 * Bild fuellt den Slot in der Hoehe, Breite folgt dem echten
 * Bild-Seitenverhaeltnis. Ueberschreibt Base-`height:auto`. */
.compendion-content-card--landscape .compendion-content-card__cover {
	height: 100%;
	width: auto;
	max-width: 100%;
	max-height: 100%;
}

/* Breitformat-Cover im Querformat (Arne 2026-10-22): hoechstens ein 16:9-
   Kasten in Slot-Hoehe (5,5 rem → 156 × 88 px). Vorher bestimmte die Hoehe
   das Bild, ein 2,4:1-MWM-Cover wurde 211 px breit und wirkte zu gross. Jetzt
   fuellt es die Breite des 16:9-Kastens, wird entsprechend niedriger und
   sitzt mittig; Rahmen und Glow liegen eng am Bild. Die Portrait-Toggles
   unten stellen die volle Breite wieder her. */
.compendion-content-card--landscape .compendion-content-card__media:is([data-ratio="16x9"], [data-ratio="221x1"]) {
	width: calc(var(--content-card-landscape-h) * 16 / 9);
}

.compendion-content-card--landscape .compendion-content-card__media:is([data-ratio="16x9"], [data-ratio="221x1"]) > .compendion-content-card__cover {
	width: 100%;
	height: auto;
}

/* Ersatz-Cover im Querformat: feste Quadrat-Groesse in Slot-Hoehe statt
   aspect-ratio + Prozent-Hoehe (Safari rechnet das im Flex-Slot unzuverlaessig).
   Schild und Schrift kompakt, damit das Muster sichtbar bleibt. Die
   Portrait-Toggles unten setzen das zurueck. */
.compendion-content-card--landscape .compendion-content-card__cover--empty {
	width: var(--content-card-landscape-h);
	height: var(--content-card-landscape-h);
	max-width: none;
	max-height: none;
	padding: 0.35rem;
}

.compendion-content-card--landscape .compendion-content-card__cover-plate {
	gap: 0.15rem;
	padding: 0.25rem 0.35rem;
}

.compendion-content-card--landscape .compendion-content-card__cover-plate::before {
	width: 1rem;
	height: 1rem;
}

.compendion-content-card--landscape .compendion-content-card__cover-name {
	font-size: 0.62rem;
	line-height: 1.1;
}

/* Cover im 16/9-Basis-Slot (compact-v/Rail): Browser haelt das native Verhaeltnis in
 * beiden Achsen — height/width:auto mit max-*:100% klammert das Bild in den Slot.
 * Filmframe (2.35:1) → Breite voll, Letterbox oben/unten; 1:1 → Hoehe voll, Pillarbox
 * links/rechts; 16:9 → Slot komplett. Kein Crop, kein Stretch (feedback_keine_cover_crops). */
.compendion-content-card--compact-v .compendion-content-card__cover {
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 100%;
}

/* Body in Landscape: feste 110px-Row, overflow:hidden clippt visuell.
 * max-height als Sicherheitsnetz gegen unkontrolliertes Wachsen. */
.compendion-content-card--landscape .compendion-content-card__body {
	grid-area: body;
	min-width: 0;
	min-height: 0;
	max-height: 200px;
	overflow: hidden;
	padding: 0.2rem 0.25rem 0.2rem 0.5rem;
	gap: 0.15rem;
	justify-content: flex-start;
	overflow-wrap: break-word;
}

/* Title-Clamp im Landscape: 2 Zeilen, font-size skaliert mit Card-Breite via
 * cqw, damit ein langer Titel bei schmalerer Card kleiner statt abgeschnitten
 * wird. */
.compendion-content-card--landscape .compendion-content-card__title {
	margin-top: 0;
	font-size: clamp(0.75rem, 4.9cqw, 1.3rem);
}

.compendion-content-card--landscape .compendion-content-card__badge,
.compendion-content-card--landscape .compendion-content-card__date,
.compendion-content-card--landscape .compendion-content-card__source {
	font-size: clamp(0.65rem, 3.4cqw, 0.9rem);
}

/* Contributors-Strip in Landscape: eigene Grid-Row darunter, voll-breit. */
.compendion-content-card--landscape .compendion-content-card__contributors {
	grid-area: strip;
	margin-top: 0;
}

/* === Compact-V-Modifier: minimale Hochkant-Card (Cover + Titel + Badge) ===
 *
 * Content-Grid v2 Stufe 1. Schmale Karte fuer den Card-Rail (Breite kommt vom
 * Container, nicht von der Card - Format und Container sind orthogonale
 * Achsen). Markup enthaelt nur Media, Titel und Meta (Badge + Episodennummer);
 * Datum/Tags/Strip erzeugt der Renderer in dieser Variante gar nicht.
 *
 * Der `__media`-Slot ist der ratio-getriebene 16/9-Basis-Slot (wie bei den
 * Portrait-/Fundus-Cards, Basis-Regel oben): volle Kartenbreite, das Cover
 * behaelt das Box-=-Bildverhaeltnis-Modell und dehnt sich maximal im Slot aus,
 * nie Crop (feedback_keine_cover_crops); die Base-Flex-Zentrierung legt es
 * mittig ab, der Slot-Hintergrund fuellt Pillarbox/Letterbox, Outline + Glow
 * kleben am Bild selbst (Basis-`__cover`-Regel). Kein eigener Media-Override
 * (Arne 2026-07-17, loest den hoehengesteuerten 4rem-Slot ab).
 *
 * min-height:0 ist im Rail-Kontext PFLICHT: die Karte ist dort Flex-Item eines
 * Flex-Tracks (anders als im Fundus-Grid), und Chromiums automatisches
 * `min-height:auto` laesst den 16/9-Slot auf die ungeklemmte Bildhoehe
 * anwachsen (1:1-Cover blaehte den Slot quadratisch auf, DOM-verifiziert
 * 2026-07-17) - erst mit der Schranke klemmt `max-height:100%` das Cover auf
 * die Slot-Hoehe. Vertikales Pendant zur min-width:0-Flex-Falle. */
.compendion-content-card--compact-v .compendion-content-card__media {
	min-height: 0;
}

.compendion-content-card--compact-v .compendion-content-card__body {
	gap: 0.35rem;
}

.compendion-content-card--compact-v .compendion-content-card__title {
	margin-top: 0;
	font-size: 1rem;
}

.compendion-content-card--compact-v .compendion-content-card__badge {
	font-size: 0.8rem;
	/* In der nowrap-Meta-Zeile (unten) darf nur die Pille schrumpfen - mit
	 * Ellipsis statt Umbruch (feedback_badge_truncation_flex: min-width:0
	 * am Flex-Kind, box-sizing am Badge). */
	flex: 0 1 auto;
	min-width: 0;
	box-sizing: border-box;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* Podcast-Pille + Episodennummer IMMER in einer Zeile (Arne 2026-06-12):
 * kein Umbruch, vertikal mittig - die Pille truncated notfalls (oben). */
.compendion-content-card--compact-v .compendion-content-card__meta {
	flex-wrap: nowrap;
	align-items: center;
}

/* Der Link braucht min-width:0, sonst haelt sein flex-Default min-width:auto
 * die min-content-Breite der nowrap-Meta (Pille + Nummer ungeschrumpft) und
 * sprengt die feste Rail-Kartenbreite - die Nummer ragte dann in die
 * Nachbarkarte und las sich dort als "Folge N <naechste Show>"
 * (Arne-Screenshot 2026-06-12). Erst mit dieser Schranke kann die Pille
 * ueberhaupt per Ellipsis schrumpfen. */
.compendion-content-card--compact-v .compendion-content-card__link {
	min-width: 0;
}

/* Episodennummer als Pille "#N" auf jeder Card mit Nummer (Arne 2026-10-01; die
 * Nummer im Titel wurde von der Titelklemme abgeschnitten).
 *
 * Position, je nach Layout:
 *   - Landscape (Cover rechts): im Body am RECHTEN Rand der Datumszeile, also direkt
 *     links neben dem Cover und ueber dem Titel - verdeckt kein Bild (Arne: die
 *     Ecke im Cover verdeckte zu viel).
 *   - Vertikale Modi (Default-Portrait, compact-v, Portrait-Toggle der Landscape-
 *     Cards): absolut in der oberen rechten Ecke der Card (= Ecke des Cover-Slots
 *     oben); dort liegt sie neben schmalen 1:1-Covern auf leerer Slot-Flaeche.
 *
 * Farben nur aus der Palette, kontrastkorrekt in Hell UND Dunkel: Fuellung
 * `contrast`, Schrift `base` (#161616 auf #F5F5F4 = 16,8:1; im Dunkel-Modus
 * tauschen beide Tokens, #E8E8E8 auf #141414 = 14,5:1; beides > WCAG AAA 7:1).
 * Der 1px-Ring in `base` loest die Pille von dunklen Flaechen. tabular-nums haelt
 * Ziffern gleich breit; white-space/flex-shrink verhindern jedes Abschneiden. */
.compendion-content-card__link {
	position: relative;
}

.compendion-content-card__dateline {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 0.4rem;
	min-width: 0;
}

.compendion-content-card__epnum {
	display: inline-block;
	flex-shrink: 0;
	margin-left: auto;
	box-sizing: border-box;
	padding: 0.1rem 0.5rem;
	border-radius: 999px;
	border: 1px solid var(--wp--preset--color--base);
	background: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--base);
	font-size: 0.8rem;
	font-weight: 700;
	line-height: 1.35;
	letter-spacing: 0.01em;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
	pointer-events: none;
}

/* Vertikale Modi: Pille in die obere rechte Card-Ecke. */
.compendion-content-card:not(.compendion-content-card--landscape) .compendion-content-card__epnum,
.compendion-content-card--compact-v .compendion-content-card__epnum {
	position: absolute;
	top: 0.7rem;
	right: 0.7rem;
	z-index: 2;
	margin-left: 0;
}

/* === Portrait-Toggle fuer --landscape Cards: Cover oben statt rechts ===
 *
 * Bedingungen (alle drei):
 *   1. Viewport-Breite ≥ 600px (auf schmalen Phones bleibt es bei Cover-rechts)
 *   2. Viewport-Hoehe ≥ 572px  (verhindert Toggle im Querformat – Arne-Wunsch,
 *      siehe Grid-Wrapper-Kommentar oben)
 *   3. Card-Container ≤ 480px  (Card sitzt im 2+-Spalten-Portrait-Grid und
 *      ist zu schmal fuer ein sinnvolles Landscape-Layout)
 *
 * Schwelle 480px gekoppelt an Grid-minmax(270px): eine 2-Spalten-Card wird kurz
 * vor dem 3-Spalten-Sprung bis ~415px breit. Die Schwelle muss oberhalb davon
 * liegen, sonst bleiben breite 2-Spalten-Cards faelschlich horizontal. Bei
 * Aenderung des Grid-minmax diesen Wert mitziehen (Memory
 * feedback_content_card_responsive: drei gekoppelte Werte).
 *
 * Der Toggle wechselt vom Landscape-Grid zurueck auf Portrait-Flex-Spalte.
 * Contributors-Strip sitzt damit wieder als drittes Spalten-Kind unter Body.
 */
@media (min-width: 600px) and (min-height: 572px) {
	@container card (max-width: 480px) {
		.compendion-content-card--landscape .compendion-content-card__link {
			/* Grid-Layout des Landscape-Modus zuruecksetzen – Portrait ist
			 * eine einfache Flex-Spalte. */
			display: flex;
			flex-direction: column;
			grid-template-columns: none;
			grid-template-rows: none;
			grid-template-areas: none;
			gap: 0.5rem;
		}
		.compendion-content-card--landscape .compendion-content-card__media {
			width: 100%;
			height: auto;
			aspect-ratio: 16 / 9;
			max-width: 100%;
		}
		/* Cover-Override aus Landscape (height:100%) zuruecksetzen. In Portrait
		 * skaliert das Bild wieder frei im 16/9-Slot (Base-Logik width/height:auto,
		 * Box = echtes Bildverhaeltnis). */
		.compendion-content-card--landscape .compendion-content-card__cover {
			width: auto;
			height: auto;
		}
		.compendion-content-card--landscape .compendion-content-card__media:is([data-ratio="16x9"], [data-ratio="221x1"]) {
			width: 100%;
		}
		.compendion-content-card--landscape .compendion-content-card__cover--empty {
			width: auto;
			height: 100%;
			padding: 0.6rem;
		}
		.compendion-content-card--landscape .compendion-content-card__cover-plate {
			gap: 0.3rem;
			padding: 0.45rem 0.6rem;
		}
		.compendion-content-card--landscape .compendion-content-card__cover-plate::before {
			width: 1.4rem;
			height: 1.4rem;
		}
		.compendion-content-card--landscape .compendion-content-card__cover-name {
			font-size: 0.8rem;
			line-height: 1.15;
		}
		/* 16:9-Kasten wie compact-v: Breitformat fuellt die Breite, Quadrat/4:3 die Hoehe. */
		.compendion-content-card--landscape .compendion-content-card__media:is([data-ratio="16x9"], [data-ratio="221x1"]) > .compendion-content-card__cover {
			width: 100%;
			height: auto;
		}
		.compendion-content-card--landscape .compendion-content-card__media:is([data-ratio="1x1"], [data-ratio="4x3"]) > .compendion-content-card__cover {
			height: 100%;
			width: auto;
		}
		.compendion-content-card--landscape .compendion-content-card__body {
			min-height: 0;
			overflow: visible;
			padding: 0.15rem 0.35rem 0.35rem;
			gap: 0.25rem;
		}
		.compendion-content-card--landscape .compendion-content-card__title {
			margin-top: 0.15rem;
			font-size: 1.3rem;
		}
		.compendion-content-card--landscape .compendion-content-card__badge,
		.compendion-content-card--landscape .compendion-content-card__date,
		.compendion-content-card--landscape .compendion-content-card__source {
			font-size: 0.9rem;
		}
		/* Portrait-Toggle: Nummern-Pille in die obere rechte Card-Ecke (Cover oben). */
		.compendion-content-card--landscape .compendion-content-card__epnum {
			position: absolute;
			top: 0.7rem;
			right: 0.7rem;
			z-index: 2;
			margin-left: 0;
		}
	}
}

/* Portrait-Toggle fuer sehr enge Landscape-Cards (z.B. 2-Spalten auf Mobile).
 * Der bestehende Toggle mit @media (min-width:600px) greift auf schmalen Phones
 * (<600px Viewport) nie. Diese Regel faengt den 2-Spalten-Fall (~175px) ab,
 * ohne bei Vollbreite (~390px) zu stoeren. */
@container card (max-width: 300px) {
	.compendion-content-card--landscape .compendion-content-card__link {
		display: flex;
		flex-direction: column;
		grid-template-columns: none;
		grid-template-rows: none;
		grid-template-areas: none;
		gap: 0.5rem;
	}
	.compendion-content-card--landscape .compendion-content-card__media {
		width: 100%;
		height: auto;
		aspect-ratio: 16 / 9;
		max-width: 100%;
	}
	.compendion-content-card--landscape .compendion-content-card__cover {
		width: auto;
		height: auto;
	}
	.compendion-content-card--landscape .compendion-content-card__cover--empty {
		width: auto;
		height: 100%;
		padding: 0.6rem;
	}
	.compendion-content-card--landscape .compendion-content-card__cover-plate {
		gap: 0.3rem;
		padding: 0.45rem 0.6rem;
	}
	.compendion-content-card--landscape .compendion-content-card__cover-plate::before {
		width: 1.4rem;
		height: 1.4rem;
	}
	.compendion-content-card--landscape .compendion-content-card__cover-name {
		font-size: 0.8rem;
		line-height: 1.15;
	}
	.compendion-content-card--landscape .compendion-content-card__media:is([data-ratio="16x9"], [data-ratio="221x1"]) {
		width: 100%;
	}
	.compendion-content-card--landscape .compendion-content-card__media:is([data-ratio="16x9"], [data-ratio="221x1"]) > .compendion-content-card__cover {
		width: 100%;
		height: auto;
	}
	.compendion-content-card--landscape .compendion-content-card__media:is([data-ratio="1x1"], [data-ratio="4x3"]) > .compendion-content-card__cover {
		height: 100%;
		width: auto;
	}
	.compendion-content-card--landscape .compendion-content-card__body {
		min-height: 0;
		overflow: visible;
		padding: 0.15rem 0.35rem 0.35rem;
		gap: 0.25rem;
	}
	.compendion-content-card--landscape .compendion-content-card__title {
		margin-top: 0.15rem;
		font-size: 1.3rem;
	}
	.compendion-content-card--landscape .compendion-content-card__badge,
	.compendion-content-card--landscape .compendion-content-card__date,
	.compendion-content-card--landscape .compendion-content-card__source {
		font-size: 0.9rem;
	}
	/* Portrait-Toggle (enge Cards): Nummern-Pille in die obere rechte Card-Ecke. */
	.compendion-content-card--landscape .compendion-content-card__epnum {
		position: absolute;
		top: 0.7rem;
		right: 0.7rem;
		z-index: 2;
		margin-left: 0;
	}
}

/* === Dark-Mode-Override fuer card-accent ===
 *
 * `--compendion-card-accent` wird in site-palette.php gegen die Light-Mode-
 * Card-Surface gerechnet (`surface-soft`). Im Dark Mode wechselt die Card-BG
 * auf ~`#1F1F1F` (base #141414 + 5% contrast #E8E8E8) – gegen diesen
 * Hintergrund gilt `--compendion-card-accent-dark`, der dort gegen den
 * Dark-Card-BG geprueft wurde. Selektor-Pattern analog zur Dark-Correction
 * in site-palette.php: Media-Query fuer prefers-color-scheme + explizite
 * data-color-scheme-Variante fuer User-Toggles.
 */
@media (prefers-color-scheme: dark) {
	html:not([data-color-scheme="light"]) :root,
	html:not([data-color-scheme="light"]) body {
		--compendion-card-accent: var(--compendion-card-accent-dark, var(--compendion-card-accent));
	}
}
html[data-color-scheme="dark"] :root,
html[data-color-scheme="dark"] body {
	--compendion-card-accent: var(--compendion-card-accent-dark, var(--compendion-card-accent));
}

/* Kuratierte Beschreibungszeile (description-Arg, z. B. Fang-hier-an-Reihe
   Codenaga-Profil): laufender Satz im Body - bewusst KEINE Pillen-Optik.
   currentColor-basiert, damit die Farbe dem Card-Text-Token folgt. */

.compendion-content-card__description {
    margin: 0.35rem 0 0;
    font-size: 0.9rem;
    line-height: 1.45;
    color: color-mix(in srgb, currentColor 75%, transparent);
}

/* Tag-Badges (Typ + Perspektive auf Anderswo-Cards) */

.compendion-content-card__tags {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    margin-top: 0.25rem;
}

.compendion-content-card__tag {
    display: inline-block;
    align-self: center;
    padding: 0.15rem 0.6rem;
    border: 1px solid var(--c-page-border);
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--c-on-base-muted);
    background: transparent;
}

.compendion-content-card__tag--avatar {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    border: none;
    padding: 0;
}

.compendion-content-card__tag-avatar {
    width: 35px;
    height: 35px;
}

/* === Card-Rail: geteilter einzeiliger Horizontal-Scroller ===
 *
 * Container-Achse des Content-Grid-v2-Systems (Card-Format ist die andere).
 * Track ist das scrollende Element: Flex-Zeile, Scroll-Snap, versteckte
 * Scrollbar. Edge-Fades als Affordanz via mask-image AM TRACK (nicht am
 * Wrapper, sonst wuerde der sichtbare Rahmen mitmaskiert).
 * Default (vor/ohne JS): nur rechter Fade. Das JS togglet `is-scrolled`
 * (links angeschnitten -> linker Fade) und `is-end` (rechts fertig -> kein
 * rechter Fade) und blendet die Pfeile nur bei Ueberlauf ein.
 *
 * Der Wrapper traegt einen sichtbaren Rahmen + zarten Tint, damit der Rail
 * klar als eigener scrollbarer Bereich lesbar ist (Arne 2026-06-12). */
.compendion-card-rail {
	position: relative;
	padding: 0.75rem 0.5rem;
	border: 1px solid var(--c-page-border);
	border-radius: 1rem;
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 3%, transparent);
}

/* Rahmen und Tint nur, wenn der Rail wirklich scrollt (Arne 2026-10-22): sie
 * markieren den scrollbaren Bereich, wie die Pfeile darunter. Passen alle
 * Karten (z. B. „Starte hier“ mit 5 Karten auf breiten Schirmen), steht das
 * Rail rahmenlos. Klassen setzt compendion-card-rail.js; ohne JS bleibt der
 * Rahmen (sicherer Default). Vorbild: „Was gerade läuft“ auf der Startseite,
 * wo der Rahmen im dunklen Band ohnehin nicht zu sehen ist. */
.compendion-card-rail.is-ready:not(.is-overflowing) {
	border-color: transparent;
	background: transparent;
}

/* Scroll-Snap-Alignment: CENTER (Arne 2026-08-07, gilt weiterhin trotz
 * Zwischenstopp bei "start" am 2026-06-16 - der wurde als Wechsel des
 * Design-Ziels wieder verworfen). Die Karten rasten auf ihre Mitte ein;
 * "buendig links" war nur eine kurzlebige Alternativloesung und ist NICHT
 * mehr der Zielzustand (naechster Kommentarblock unten an
 * `__track > *` beschreibt das Snap-Verhalten der Karten selbst).
 *
 * padding-inline (Arne 2026-08-07): derselbe Karten-Schatten, der unten den
 * vertikalen Clip-Raum begruendet (0 2px 12px, blurt ohne x-Offset ca.
 * 12-13px nach LINKS/RECHTS), hatte inline nie Clip-Raum - padding-inline
 * war 0. Ergebnis: an der Rail-Ruheposition (scrollLeft 0) sass die erste
 * Karte mit ihrem Schatten exakt auf der Track-Clip-Kante; der Schatten
 * wurde links hart abgeschnitten, was wie ein paar abgeschnittene Pixel an
 * der Karte selbst aussah (WebKit/Safari macht das sichtbarer, da
 * mandatory Snap dort bei unerreichbarem Center-Ziel der ersten/letzten
 * Karte zusaetzlich minimal ueber die eigentliche Ruheposition hinaus-
 * schiebt - genau in den ungepolsterten Bereich hinein). 1rem (16px) deckt
 * den Schatten-Bleed. Anders als beim Block-Padding braucht es HIER kein
 * kompensierendes negatives margin-inline: bei einem Block-Element mit
 * width:auto und margin-inline:0 loest der Browser die Breite so auf, dass
 * die Aussenkanten gleich bleiben (padding geht zulasten des Innenraums,
 * nicht des Layouts) - per DevTools-Messung auf compendion.net verifiziert
 * (Track-Rect vor/nach Padding-Aenderung identisch). scroll-padding-inline
 * matcht das Padding, damit der reine Sicherheitsraum nicht in die
 * Snap-Zielberechnung einfliesst (Karte 1/letzte Karte bleiben die
 * Snap-Ziele, nicht der Puffer davor/danach). Ein exaktes Center-Snapping
 * der ersten/letzten Karte bleibt bei mehreren sichtbaren Karten geometrisch
 * unerreichbar (das Ziel laege ausserhalb des Scroll-Bereichs) - das ist
 * kein Bug, der Browser rastet dann sauber auf die Grenzposition. Wichtig
 * ist nur, dass diese Grenzposition die Karte vollstaendig zeigt statt sie
 * anzuschneiden.
 *
 * padding-block + margin-block (Arne 2026-06-12, vergroessert 2026-06-22): der
 * Track ist ein Scroll-Container (overflow-x:auto impliziert zwingend
 * overflow-y:auto - ein overflow-y:visible wuerde von der Spec auf auto
 * hochgerechnet) UND traegt die Edge-Fade-Masken; beides clippt an der
 * Track-Padding-Box. Karten-Schatten (0 2px 12px -> ~14px nach unten),
 * Border-Radius und der compact-v-Cover-Glow brauchen darum vertikalen
 * Innenraum INNERHALB des Paddings. 0.75rem (12px) reichten nicht: die
 * Card-Unterkante inkl. Radius + Schatten wurde sichtbar angeschnitten (Arne
 * 2026-06-22, auf jeder Rail-Seite). Jetzt 1.5rem (24px Clip-Raum) deckt
 * Schatten + Radius + Glow. Das negative margin-block haelt den Layout-Effekt
 * aussen klein (netto 1rem). --ep bleibt bei 1.25rem (ep-Cards tragen keinen
 * Schatten, nur 0.75rem-Radius). */
.compendion-card-rail__track {
	display: flex;
	flex-wrap: nowrap;
	/* Karten mittig, solange sie passen; bei Ueberlauf faellt `safe` auf
	   start zurueck und das Band scrollt wie bisher (Arne, Go 2026-10-15). */
	justify-content: safe center;
	gap: 0.75rem;
	margin: -0.5rem 0;
	padding: 1.5rem 1rem;
	list-style: none;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	scroll-snap-type: x mandatory;
	scroll-padding-inline: 1rem;
	scrollbar-width: none;
	-webkit-mask-image: linear-gradient(to right, #000 calc(100% - 3rem), transparent);
	mask-image: linear-gradient(to right, #000 calc(100% - 3rem), transparent);
}

.compendion-card-rail__track::-webkit-scrollbar {
	display: none;
}

/* Feste Kartenbreite (13rem, seit 2026-06-12 - vorher 11.5rem, zu schmal
 * fuer die Podcast-Pillen in einer Zeile) - die Breite gehoert zum
 * Container, nicht zur Card: dieselbe compact-v-Card darf spaeter in einem
 * Grid anders sitzen. Gekoppelt an das Track-padding-inline (oben). */
.compendion-card-rail__track > * {
	flex: 0 0 13rem;
	scroll-snap-align: center;
}

.compendion-card-rail__track.is-scrolled:not(.is-end) {
	-webkit-mask-image: linear-gradient(to right, transparent, #000 3rem, #000 calc(100% - 3rem), transparent);
	mask-image: linear-gradient(to right, transparent, #000 3rem, #000 calc(100% - 3rem), transparent);
}

.compendion-card-rail__track.is-scrolled.is-end {
	-webkit-mask-image: linear-gradient(to right, transparent, #000 3rem);
	mask-image: linear-gradient(to right, transparent, #000 3rem);
}

.compendion-card-rail__track.is-end:not(.is-scrolled) {
	-webkit-mask-image: none;
	mask-image: none;
}

/* Breite Rail-Variante fuer VOLLE Portrait-Cards (Fang-hier-an-Reihe
 * Codenaga-Profil): volle Cards tragen Datum/Meta/Description und brauchen
 * mehr Breite als compact-v. Seit dem Start-Snap (2026-06-16) kein eigenes
 * padding-inline mehr noetig - die Karte steht wie im Basis-Rail buendig
 * links. */
.compendion-card-rail--wide .compendion-card-rail__track > * {
	flex-basis: 17rem;
}

/* Pfeil-Buttons: vom JS erzeugt (in einer __nav-Zeile UNTER dem Track,
 * Arne 2026-06-12), nur bei Ueberlauf sichtbar. Pill-Form (Design-Regel 2/3),
 * primary + on-primary-Token (Design-Regel 1). */
.compendion-card-rail__nav {
	display: flex;
	justify-content: center;
	gap: 0.75rem;
	margin-top: 0.6rem;
}

.compendion-card-rail__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	padding: 0;
	border: none;
	border-radius: 999px;
	background: var(--compendion-color-primary-fill, var(--wp--preset--color--primary));
	color: var(--compendion-color-on-primary, var(--wp--preset--color--base));
	font-size: 1.25rem;
	line-height: 1;
	cursor: pointer;
	box-shadow: 0 2px 8px color-mix(in srgb, var(--wp--preset--color--contrast, #000) 25%, transparent);
	transition: opacity 150ms ease;
}

/* Gedimmt statt unsichtbar: die Button-Zeile bleibt stabil, die Richtung
 * "geht hier nicht weiter" bleibt ablesbar. */
.compendion-card-rail__btn[disabled] {
	opacity: 0.35;
	pointer-events: none;
}

.compendion-card-rail__nav[hidden],
.compendion-card-rail__btn[hidden] {
	display: none;
}

/* ─── Episode-Rail-Card (Sub-Site „Weitere Folgen", Nummer-first) ──── */

/* Mehr vertikales Padding als Basis-Rail (0.75rem): ep-Card-Links haben
 * border-radius 0.75rem. Netto-Atemluft = padding - 0.5rem (neg. margin) muss
 * >= border-radius sein. 1.25rem - 0.5rem = 0.75rem = exakt passend. */
.compendion-card-rail--ep .compendion-card-rail__track {
	padding-block: 1.25rem;
}

.compendion-card-rail--ep .compendion-card-rail__track > * {
	flex: 0 0 15rem;
}

/* overflow: hidden entfernt: der Track clippt ohnehin an seinen Raendern
 * (overflow-y:auto), die Card selbst muss nicht zusaetzlich abschneiden.
 * Titel klemmt per fester height:2.6em (content-card__title). */
/* display:flex macht die <li> zum Flex-Container, damit der Link-Child
 * per align-items:stretch (default) die volle Card-Hoehe einnimmt – ohne
 * height:inherit oder height:100%, die beide einen JS-Reflow-Trigger
 * brauchen bevor die Hoehe korrekt aufgeloest wird. */
.compendion-ep-card {
	list-style: none;
	min-width: 0;
	display: flex;
}

.compendion-ep-card__link {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	gap: 0.2rem;
	padding: 0.85rem 1rem;
	border-radius: 0.75rem;
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 5%, transparent);
	text-decoration: none;
	/* contrast-Token direkt: kein Fallback auf inherit (wuerde auf DML die
	 * pinke Link-Farbe aufgreifen = pink-auf-pink, kaum lesbar). */
	color: var(--wp--preset--color--contrast);
	transition: background 150ms ease;
}

.compendion-ep-card__link:hover {
	background: color-mix(in srgb, var(--wp--preset--color--contrast, #000) 10%, transparent);
}

.compendion-ep-card__code {
	font-size: 1.2rem;
	font-weight: 700;
	color: var(--wp--preset--color--contrast);
	line-height: 1.2;
	margin-bottom: 0.15rem;
}

.compendion-ep-card__title {
	font-size: 0.9rem;
	font-weight: 400;
	line-height: 1.35;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.compendion-ep-card__subtitle {
	font-size: 0.8rem;
	line-height: 1.4;
	opacity: 0.85;
	display: -webkit-box;
	-webkit-line-clamp: 5;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.compendion-ep-card__date {
	font-size: 0.75rem;
	opacity: 0.7;
	margin-top: auto;
	padding-top: 0.25rem;
}

@media (max-width: 600px) {
	.compendion-card-rail--ep .compendion-card-rail__track > * {
		flex: 0 0 72vw;
	}
}
