/**
 * YSA Leverkusen — Design-System für das GeneratePress-Child-Theme.
 * Quelle: design_handoff_ysa_landingpage/README.md (Variante D "Große Bühne").
 */

/* -----------------------------------------------------------------------
 * Fonts — lokal gehostet, kein Google-Fonts-CDN (DSGVO).
 * Nur der Latin-Subset (deckt deutsche Umlaute, ß und Halbgeviertstrich ab).
 * --------------------------------------------------------------------- */
@font-face {
	font-family: 'Anton';
	src: url('../fonts/anton-400.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Yellowtail';
	src: url('../fonts/yellowtail-400.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Montserrat';
	src: url('../fonts/montserrat-400.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Montserrat';
	src: url('../fonts/montserrat-600.woff2') format('woff2');
	font-weight: 600;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Montserrat';
	src: url('../fonts/montserrat-700.woff2') format('woff2');
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}

/* -----------------------------------------------------------------------
 * Design-Tokens
 * --------------------------------------------------------------------- */
:root {
	/*
	 * Farben — verweisen auf GeneratePress' Customizer-Variablen
	 * (Anpassen → Farben → Global Colors), mit den Handoff-Werten als
	 * Fallback. Ändert eine Redaktion dort z. B. "Accent", zieht das
	 * automatisch hier durch. --ysa-accent-2 ist ein von uns zusätzlich
	 * angelegtes Farbfeld (Red hat keine eigene GP-Standardrolle).
	 *
	 * Nur noch EIN Markenrot (Farbregel-Update, verbindlich): "--ysa-red"
	 * (#C8242A, "Vorhangrot") ist das einzige Rot für Flächen (Buttons,
	 * Badges, Bänder, Hintergründe) — dort immer mit weißer Schrift
	 * (--ysa-paper), nie schwarz. "--ysa-red-glow" (#E84A50, das alte
	 * "Leuchtrot") ist keine eigenständige Markenfarbe mehr, sondern nur
	 * noch eine hellere Variante für Schrift/Linie/Lichtschein auf
	 * Schwarz (--ysa-ink-900 / --ysa-ink-800) — nie als Fläche und nie auf
	 * hellem Grund (dort ebenfalls immer --ysa-red).
	 */
	--ysa-ink-900: var(--base-2, #141110);
	--ysa-ink-800: var(--base, #1E1918);
	--ysa-paper: var(--contrast, #F4F2EF);
	--ysa-red-glow: var(--accent, #E84A50);
	--ysa-red: var(--ysa-accent-2, #C8242A);

	/* Textschleier (abgestufte Sekundärtexte auf dunklem Grund) — aus --ysa-paper gemischt */
	--ysa-veil-90: color-mix(in srgb, var(--ysa-paper) 90%, transparent);
	--ysa-veil-85: color-mix(in srgb, var(--ysa-paper) 85%, transparent);
	--ysa-veil-82: color-mix(in srgb, var(--ysa-paper) 82%, transparent);
	--ysa-veil-78: color-mix(in srgb, var(--ysa-paper) 78%, transparent);
	--ysa-veil-70: color-mix(in srgb, var(--ysa-paper) 70%, transparent);

	/* Trennlinien auf dunklem Grund — aus --ysa-paper gemischt */
	--ysa-line-14: color-mix(in srgb, var(--ysa-paper) 14%, transparent);
	--ysa-line-18: color-mix(in srgb, var(--ysa-paper) 18%, transparent);
	--ysa-line-20: color-mix(in srgb, var(--ysa-paper) 20%, transparent);

	/*
	 * Schriften — Fallback-Werte hier; die tatsächlichen Werte kommen als
	 * Inline-Override aus ysa_typography_css_vars() in functions.php,
	 * synchron mit dem Customizer-Typography-Panel (Body/Überschriften).
	 * Yellowtail bleibt fix: keine eigene GP-Typografie-Rolle dafür.
	 */
	--ysa-font-display: 'Anton', 'Arial Narrow', sans-serif;
	--ysa-font-script: 'Yellowtail', cursive;
	--ysa-font-body: 'Montserrat', system-ui, sans-serif;

	/*
	 * Schriftstärke/Textumwandlung der Sektionstitel (H2 mit
	 * font-family: var(--ysa-font-display), außer .ysa-hero-title — die
	 * bleibt bewusst fest bei 700, siehe dort) — Fallback-Werte hier, echte
	 * Werte kommen ebenfalls als Inline-Override aus
	 * ysa_typography_css_vars() in functions.php, synchron mit dem
	 * Customizer-Typography-Panel ("Alle Überschriften"). Anton wirkt schon
	 * bei 400 (ihrem einzigen Schnitt) kräftig genug — 700 erzeugt nur
	 * unnötiges Fake-Bold.
	 */
	--ysa-heading-weight: 400;
	--ysa-heading-transform: uppercase;

	/* Kleintext-Stufen (Großbuchstaben mit Sperrung), siehe "Kleintext" unten */
	--ysa-text-sm: clamp(12px, .85vw, 13px);
	--ysa-text-md: clamp(12px, .9vw, 14px);
	/*
	 * Anreißer-/Einleitungstext: EINE Größe für alle Sektionen (Blick nach vorn,
	 * Blick zurück, Partner, Team, Hero-Subline). Nicht pro Sektion neu setzen.
	 */
	--ysa-text-lead: clamp(15px, 1.15vw, 18px);
	--ysa-lead-leading: 1.6;

	--ysa-kicker-tracking: .32em;
	--ysa-link-tracking: .16em;
	--ysa-label-tracking: .14em;

	/* Abstände */
	--ysa-space-section: clamp(50px, 8vw, 140px);
	--ysa-space-side: clamp(16px, 3vw, 48px);
	--ysa-space-block: clamp(16px, 2vw, 28px);

	/* Schatten */
	--ysa-shadow-h1: 0 14px 46px rgba(0, 0, 0, .55);
	--ysa-shadow-script: 0 8px 28px rgba(0, 0, 0, .55);

	/* Radius — 0 überall, Teil der Plakat-Ästhetik */
	--ysa-radius: 0px;

	/* Bewegung — starke Kurven statt der schwachen Browser-Defaults */
	--ysa-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
	--ysa-ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);

	/* Header-Höhe (grober Richtwert für scroll-margin-top der Anker-Sektionen) */
	--ysa-header-h: clamp(64px, 9vh, 96px);
}

/* -----------------------------------------------------------------------
 * Barrierefreiheit (global)
 * --------------------------------------------------------------------- */
/*
 * Der dunkle Seitenhintergrund kommt jetzt aus dem GeneratePress-Customizer
 * (Global Colors → Base 2, per functions.php/Customizer-Defaults auf
 * --ysa-ink-900 gesetzt) statt hier hart verdrahtet zu sein — damit
 * Redakteur:innen ihn im Backend tatsächlich ändern können. `body`
 * übernimmt das automatisch von GP, `html` erbt es per CSS-Hintergrund-
 * Propagation auf den Viewport.
 */
html {
	scroll-behavior: smooth;
}

:where([id]) {
	scroll-margin-top: var(--ysa-header-h);
}

:focus-visible {
	outline: 2px solid var(--ysa-red-glow);
	outline-offset: 3px;
}

/*
 * Fokus-Ring kontextabhängig: "--ysa-red-glow" (E84A50) gilt nur auf
 * Schwarz (Standard-Seitenhintergrund). Auf dem hellen Spielplan-Abschnitt
 * (Papier-Hintergrund) und dem roten CTA/Partner-Abschnitt wäre das
 * regelwidrig bzw. kontrastarm — dort stattdessen Markenrot bzw. Papier.
 */
.ysa-spielplan :focus-visible {
	outline-color: var(--ysa-red);
}

.ysa-cta :focus-visible {
	outline-color: var(--ysa-ink-900);
}

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

/* -----------------------------------------------------------------------
 * Header (sticky, site-weit)
 *
 * Farben aus dem Customizer (Farben → Header / Navigation), gespiegelt in
 * --ysa-header-bg, --ysa-site-title, --ysa-nav-* (functions.php). Der
 * zweite Wert in var() ist jeweils das Design, falls dort nichts steht.
 * --------------------------------------------------------------------- */
#masthead {
	position: sticky;
	top: 0;
	z-index: 40;
	background: color-mix(in srgb, var(--ysa-header-bg, var(--ysa-ink-900)) 94%, transparent);
	-webkit-backdrop-filter: blur(14px);
	backdrop-filter: blur(14px);
	border-bottom: 1px solid var(--ysa-line-14);
}

#masthead .inside-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 16px;
	padding: clamp(12px, 1.4vw, 20px) var(--ysa-space-side);
	max-width: none;
}

/* Logo-Lockup: "YS" (rot) + "Leverkusen" (Papierfarbe), gleiche Schrift */
#masthead .site-branding,
#masthead .ysa-logo-lockup {
	margin: 0;
}

#masthead .ysa-logo-lockup a {
	display: flex;
	align-items: baseline;
	gap: 8px;
	padding-bottom: 3px;
	text-decoration: none;
}

/*
 * Schriftart, -stärke und Textumwandlung von "YSA" erbt das Element von
 * .main-title — die steuert der Customizer (Typografie → "Website-Titel").
 */
#masthead .ysa-logo-mark {
	font-size: clamp(16px, 1.5vw, 24px);
	letter-spacing: .04em;
	color: var(--ysa-site-title, var(--ysa-red-glow));
}

#masthead .ysa-logo-script {
	font-size: clamp(16px, 1.5vw, 24px);
	color: var(--ysa-paper);
}

#masthead .site-description {
	display: none;
}

/* Navigation */
#masthead #site-navigation,
#masthead .main-navigation {
	background: var(--ysa-nav-bg, transparent);
}

#masthead .inside-navigation {
	padding: 0;
	max-width: none;
}

/*
 * Nur ab GeneratePress' eigenem Mobile-Breakpoint (769px) als Flex-Zeile
 * layouten — darunter regelt GP selbst das Ein-/Ausblenden über die
 * ".toggled"-Klasse (display:none per Default), das wollen wir nicht
 * überschreiben.
 */
@media (min-width: 769px) {
	#masthead #primary-menu.main-nav {
		display: flex;
	}

	#masthead #primary-menu.main-nav > .menu {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		gap: clamp(12px, 1.7vw, 28px);
		margin: 0;
		padding: 0;
		list-style: none;
	}
}

#masthead #primary-menu.main-nav .menu {
	list-style: none;
	margin: 0;
	padding: 0;
}

/*
 * ".menu > li", nicht ".menu-item", damit die Styles auch dann greifen, wenn
 * der Primary-Standort (noch) kein Menü hat und GeneratePress auf
 * wp_list_pages() zurückfällt (Klasse "page_item" statt "menu-item").
 *
 * Schriftart, -stärke, Textumwandlung und Zeichenabstand kommen bewusst
 * NICHT von hier, sondern aus dem Customizer (Typografie → "Primary
 * Navigation"); gilt auch für den Burger-Button (.mobile-menu).
 */
#masthead #primary-menu.main-nav .menu > li > a {
	display: inline-block;
	padding: 0 0 4px;
	margin: 0;
	line-height: normal;
	font-size: clamp(12px, .9vw, 14px);
	color: var(--ysa-nav-text, var(--ysa-paper));
	text-decoration: none;
}

#masthead #primary-menu.main-nav .menu > li[class*="current-menu-"] > a {
	color: var(--ysa-nav-text-current, var(--ysa-nav-text, var(--ysa-paper)));
}

/*
 * Ticket-Button — Menüpunkt mit CSS-Klasse "ysa-nav-cta"; bewusst immer
 * fett, Farben wie der Block-Style "YSA – Gefüllt" (Farben → Buttons).
 */
#masthead #primary-menu.main-nav .menu > li.ysa-nav-cta > a {
	font-weight: 700;
	background: var(--ysa-button-bg, var(--ysa-red));
	color: var(--ysa-button-text, var(--ysa-paper));
	padding: 11px 20px;
	line-height: normal;
}

#masthead #primary-menu.main-nav .menu > li.ysa-nav-cta > a:focus-visible {
	background: var(--ysa-button-bg-hover, var(--ysa-paper));
	color: var(--ysa-button-text-hover, var(--ysa-red));
}

@media (hover: hover) and (pointer: fine) {
	#masthead #primary-menu.main-nav .menu > li.ysa-nav-cta > a:hover {
		background: var(--ysa-button-bg-hover, var(--ysa-paper));
		color: var(--ysa-button-text-hover, var(--ysa-red));
	}
}

/* Mobile Burger-Menü im Entwurfs-Stil einfärben */
#masthead .menu-toggle {
	background: transparent;
	border: none;
	color: var(--ysa-nav-text, var(--ysa-paper));
	transition: opacity 150ms ease;
}

#masthead .menu-toggle:focus-visible {
	opacity: .75;
}

@media (hover: hover) and (pointer: fine) {
	#masthead .menu-toggle:hover {
		opacity: .75;
	}
}

#masthead .menu-toggle .gp-icon svg {
	fill: currentColor;
}

#masthead .mobile-menu {
	font-size: clamp(12px, .9vw, 14px);
	line-height: normal;
}

@media (max-width: 768px) {
	#masthead .main-navigation.toggled #primary-menu.main-nav {
		display: block;
		background: var(--ysa-header-bg, var(--ysa-ink-900));
		border-top: 1px solid var(--ysa-line-14);
	}

	#masthead .main-navigation.toggled #primary-menu.main-nav .menu {
		display: flex;
		flex-direction: column;
	}

	#masthead #primary-menu.main-nav .menu > li > a {
		display: block;
		padding: 14px var(--ysa-space-side);
	}

	#masthead #primary-menu.main-nav .menu > li.ysa-nav-cta {
		padding: 8px var(--ysa-space-side);
	}
}

/* -----------------------------------------------------------------------
 * Landingpage — Basis (Klasse .ysa-landing, siehe page-landing.php)
 * --------------------------------------------------------------------- */
.ysa-landing {
	background: var(--ysa-ink-900);
	color: var(--ysa-paper);
	font-family: var(--ysa-font-body);
	line-height: normal;
	overflow-x: hidden;
	/* "clip" statt nur "hidden": erzeugt keinen eigenen Scroll-Container, sonst hängen scroll-getriebene Animationen (view()) an diesem Element statt am Fenster. */
	overflow-x: clip;
}

/*
 * GeneratePress' .site-content is a flex container; #main has flex-grow:0
 * by default, so it shrinks to its content's preferred width instead of
 * filling the row. Drop the flex layout here so .ysa-landing is a normal
 * full-width block — needed on top of the no-sidebar/full-width-content
 * body classes set in functions.php.
 */
body.ysa-landing-page .site-content {
	display: block;
}

/*
 * Der Editor-Canvas begrenzt JEDEN Block (auch verschachtelte, nicht nur
 * die Top-Level-Sektion) standardmäßig auf GeneratePress' Editor-
 * "Inhaltsbreite" — via `body .wp-block { max-width: var(--content-width) }`
 * und `body { --content-width: 820px }`. "align":"full" greift dagegen bei
 * Group-Blöcken mit eigenem tagName (unsere <section>) im Editor nicht
 * zuverlässig. Statt jeden verschachtelten Block einzeln zu überschreiben,
 * setzen wir die Custom Property selbst zurück — sie vererbt sich dann
 * automatisch an alles innerhalb der Sektion (Hero-Bild, Ensemble-Grid,
 * Spielplan-Zeilen, CTA-Titel, Partner-Logos, …). Das Frontend nutzt
 * bereits volle Breite (siehe oben) und ist von dieser Regel nicht betroffen.
 */
.editor-styles-wrapper .ysa-hero,
.editor-styles-wrapper .ysa-marquee,
.editor-styles-wrapper .ysa-vorn,
.editor-styles-wrapper .ysa-ensembles,
.editor-styles-wrapper .ysa-spielplan,
.editor-styles-wrapper .ysa-rueckblick,
.editor-styles-wrapper .ysa-rueckblick-doku,
.editor-styles-wrapper .ysa-partner,
.editor-styles-wrapper .ysa-team,
.editor-styles-wrapper .ysa-cta {
	--content-width: none;
	max-width: none !important;
	width: 100% !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
}

.ysa-landing * {
	box-sizing: border-box;
}

.ysa-landing h1,
.ysa-landing h2,
.ysa-landing h3,
.ysa-landing p,
.ysa-landing ul,
.ysa-landing figure {
	margin: 0;
}

.ysa-landing a {
	color: inherit;
	text-decoration: none;
}

/*
 * Bildoptimierer (EWWW "Picture WebP Rewriting") packen jedes <img> in ein
 * <picture>. Ein inline-<picture> ist ein zusätzlicher Container, in dem
 * "height: 100%" von Kacheln (Galerie als Flex-Spalte) ins Leere läuft.
 * display: contents lässt den Wrapper aus dem Layout fallen, <img> bleibt
 * Kind der Kachel wie ohne Plugin.
 */
.ysa-landing picture {
	display: contents;
}

/*
 * Mit "display: contents" am <picture> nimmt das Basis-CSS (source { display: block })
 * die <source>-Tags als leere Flex-Kinder mit: In der Logo-Zeile (display:flex,
 * gap, space-between) schob so ein unsichtbares Element die PNG-Logos aus der
 * linken Ausrichtung in die Mitte. <source> ist nie sichtbar.
 */
.ysa-landing picture > source {
	display: none;
}

/*
 * YSA-Button-Styles ("YSA – Gefüllt" / "YSA – Outline", registriert in
 * functions.php über register_block_style()) — wählbar wie jeder andere
 * Block-Style direkt im Sidebar-Stil-Panel des Button-Blocks, keine
 * manuell einzutippende CSS-Klasse mehr nötig.
 *
 * ".wp-block-button" wird bewusst mit in den Selektor genommen (statt z. B.
 * ".ysa-landing" davorzusetzen): das ist ohnehin immer vorhanden, macht den
 * Style überall auf der Seite nutzbar (nicht nur auf der Landingpage) und
 * gibt genug Spezifität, um GeneratePress' eigene
 * "a.wp-block-button__link:not(.has-background):hover"-Regel zuverlässig
 * zu schlagen.
 *
 * Schriftart, -stärke, Textumwandlung und Zeichenabstand kommen aus dem
 * Customizer (Typografie → "Buttons"), die Farben von "Gefüllt" aus
 * Farben → Buttons (gespiegelt in --ysa-button-*, siehe
 * ysa_sync_typography_css_vars() in functions.php).
 *
 * Die ".editor-styles-wrapper"-Varianten schlagen GPs Editor-Regel
 * ".block-editor-block-list__layout .wp-block-button .wp-block-button__link"
 * (font-size: inherit; padding: 10px 15px), sonst sieht der Button im
 * Editor anders aus als im Frontend.
 */
.wp-block-button.is-style-ysa-filled .wp-block-button__link,
.wp-block-button.is-style-ysa-outline .wp-block-button__link,
.editor-styles-wrapper .wp-block-button.is-style-ysa-filled .wp-block-button__link,
.editor-styles-wrapper .wp-block-button.is-style-ysa-outline .wp-block-button__link {
	display: inline-block;
	line-height: normal;
	font-size: clamp(12px, 1vw, 15px);
	padding: 18px 34px;
	border-radius: var(--ysa-radius);
	text-decoration: none;
}

/* "Gefüllt" — Standardfarben (Hero-Kontext und überall sonst) */
.wp-block-button.is-style-ysa-filled .wp-block-button__link {
	background: var(--ysa-button-bg, var(--ysa-red));
	color: var(--ysa-button-text, var(--ysa-paper));
}

.wp-block-button.is-style-ysa-filled .wp-block-button__link:focus-visible {
	background: var(--ysa-button-bg-hover, var(--ysa-paper));
	color: var(--ysa-button-text-hover, var(--ysa-red));
}

@media (hover: hover) and (pointer: fine) {
	.wp-block-button.is-style-ysa-filled .wp-block-button__link:hover {
		background: var(--ysa-button-bg-hover, var(--ysa-paper));
		color: var(--ysa-button-text-hover, var(--ysa-red));
	}
}

/* "Outline" — Standardfarben */
.wp-block-button.is-style-ysa-outline .wp-block-button__link {
	background: transparent;
	border: 1.5px solid color-mix(in srgb, var(--ysa-paper) 65%, transparent);
	color: var(--ysa-paper);
}

.wp-block-button.is-style-ysa-outline .wp-block-button__link:focus-visible {
	background: color-mix(in srgb, var(--ysa-paper) 16%, transparent);
	color: var(--ysa-paper);
}

@media (hover: hover) and (pointer: fine) {
	.wp-block-button.is-style-ysa-outline .wp-block-button__link:hover {
		background: color-mix(in srgb, var(--ysa-paper) 16%, transparent);
		color: var(--ysa-paper);
	}
}

/* CTA-Sektion (roter Hintergrund) braucht andere "Gefüllt"-Farben */
.ysa-cta .wp-block-button.is-style-ysa-filled .wp-block-button__link {
	background: var(--ysa-paper);
	color: var(--ysa-red);
}

.ysa-cta .wp-block-button.is-style-ysa-filled .wp-block-button__link:focus-visible {
	background: var(--ysa-ink-900);
	color: var(--ysa-paper);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-cta .wp-block-button.is-style-ysa-filled .wp-block-button__link:hover {
		background: var(--ysa-ink-900);
		color: var(--ysa-paper);
	}
}

.ysa-cta .wp-block-button.is-style-ysa-outline .wp-block-button__link {
	border-color: var(--ysa-paper);
}

.ysa-cta .wp-block-button.is-style-ysa-outline .wp-block-button__link:focus-visible {
	background: color-mix(in srgb, var(--ysa-paper) 18%, transparent);
	color: var(--ysa-paper);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-cta .wp-block-button.is-style-ysa-outline .wp-block-button__link:hover {
		background: color-mix(in srgb, var(--ysa-paper) 18%, transparent);
		color: var(--ysa-paper);
	}
}

/* -----------------------------------------------------------------------
 * Kleintext — drei Stufen für Großbuchstaben-Texte mit Sperrung.
 * Werte stehen als Tokens im :root; die Komponenten unten setzen nur noch
 * Farbe und Abstände. Navigation, Buttons und Footer-Schrift kommen
 * stattdessen aus dem Customizer.
 * --------------------------------------------------------------------- */

/* Kicker — Überzeile über einem Sektionstitel */
.ysa-hero-kicker,
.ysa-kicker,
.ysa-spielplan-venue {
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-sm);
	font-weight: 700;
	letter-spacing: var(--ysa-kicker-tracking);
	text-transform: uppercase;
}

/* Link — einzelner Textlink ("Alle Ensembles →") */
.ysa-ensembles-link {
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-md);
	font-weight: 700;
	letter-spacing: var(--ysa-link-tracking);
	text-transform: uppercase;
}

/* Label — Beschriftungen und Meta-Angaben */
.ysa-stat-label,
.ysa-spielplan-meta {
	font-family: var(--ysa-font-body);
	font-weight: 600;
}

/* Footer-Menü: Schriftart und -stärke kommen aus dem Customizer ("Footer"). */
.ysa-stat-label,
.ysa-spielplan-meta,
.ysa-footer-menu a {
	font-size: var(--ysa-text-sm);
	letter-spacing: var(--ysa-label-tracking);
	text-transform: uppercase;
}

/* -----------------------------------------------------------------------
 * Sektion 2 — Hero
 * --------------------------------------------------------------------- */
.ysa-hero {
	position: relative;
	min-height: clamp(600px, 94vh, 1080px);
	min-height: clamp(600px, 94svh, 1080px);
	display: grid;
	align-items: center;
	overflow: hidden;
	background: var(--ysa-ink-800);
}

/*
 * .ysa-hero-media ist jetzt ein core/cover-Block: object-fit:cover, Bild-
 * Ersetzen-UI im Editor und die "leer = Platzhalterfarbe"-Logik liefert der
 * Block selbst — wir positionieren ihn nur noch absolut im Hero.
 */
.ysa-hero-media.wp-block-cover {
	position: absolute;
	inset: 0;
	margin: 0;
	min-height: 0;
	padding: 0;
}

/*
 * Entsättigt und dezent gehalten, damit Titel/Text davor lesbar bleiben —
 * ergänzt (statt ersetzt) den Cover-eigenen Dunkel-Überzug (dimRatio +
 * Overlay-Farbe, im Editor über "Vorlage bearbeiten" einstellbar). Grayscale
 * gibt es dort nicht als Regler, das geht nur per CSS-Filter.
 */
.ysa-hero-media .wp-block-cover__image-background {
	filter: grayscale(100%);
	opacity: .33;
}

.ysa-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to top,
		color-mix(in srgb, var(--ysa-ink-900) 94%, transparent) 0%,
		color-mix(in srgb, var(--ysa-ink-900) 50%, transparent) 45%,
		color-mix(in srgb, var(--ysa-ink-900) 35%, transparent) 100%
	);
	pointer-events: none;
	z-index: 1;
}

.ysa-hero::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: min(78vw, 1150px);
	aspect-ratio: 1;
	transform: translate(-50%, -50%);
	background: radial-gradient(
		circle,
		color-mix(in srgb, var(--ysa-red-glow) 32%, transparent) 0%,
		color-mix(in srgb, var(--ysa-red-glow) 0%, transparent) 68%
	);
	pointer-events: none;
	z-index: 1;
}

.ysa-hero-content {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: clamp(20px, 3vh, 44px);
	text-align: center;
	padding: clamp(80px, 12vh, 150px) var(--ysa-space-side) clamp(28px, 4vw, 60px);
	margin: 0 auto;
}

.ysa-hero-kicker {
	color: var(--ysa-veil-82);
}

.ysa-hero-title-wrap {
	display: flex;
	flex-direction: column;
	align-items: center;
	width: 100%;
	max-width: 1240px;
}

.ysa-hero-title {
	font-family: var(--ysa-font-display);
	/*
	 * Bewusst fest auf 700 statt var(--ysa-heading-weight): der Hero-Titel
	 * ist die eine Bühnen-Aussage der Seite und bleibt exakt wie im
	 * Leitentwurf immer im (Fake-)Bold — unabhängig davon, was Redaktion
	 * bei "Alle Überschriften" im Customizer einstellt. Anton hat nur einen
	 * Schnitt (400), der Browser rendert 700 daher als Fake-Bold.
	 */
	font-weight: 700;
	text-transform: var(--ysa-heading-transform);
	color: var(--ysa-paper);
	font-size: clamp(50px, 11.8vw, 200px);
	line-height: .78;
	letter-spacing: .002em;
	text-shadow: var(--ysa-shadow-h1);
}

.ysa-landing .ysa-hero-script {
	margin-top: -0.34em;
}

.ysa-hero-script {
	font-family: var(--ysa-font-script);
	color: var(--ysa-red-glow);
	font-size: clamp(38px, 8.2vw, 138px);
	line-height: 1;
	text-shadow: var(--ysa-shadow-script);
}

.ysa-hero-subline {
	max-width: 46ch;
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-lead);
	line-height: var(--ysa-lead-leading);
	color: var(--ysa-veil-90);
}

.ysa-hero-actions.wp-block-buttons {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: center;
	margin: 0;
}

/*
 * Schmal: min-height:94vh war für den Content viel zu hoch bemessen (Titel
 * & Co. skalieren per vw deutlich kleiner) — die Grid-Zentrierung hat das
 * mit riesigen Leerräumen über UND unter dem Content aufgefüllt, wodurch
 * die Laufschrift erst nach viel Scrollen auftauchte. Betrifft nicht nur
 * Handys, sondern jedes schmalere Fenster (Tablet, verkleinertes
 * Desktop-Fenster) — daher an der Breite und nicht an "mobil" festgemacht.
 * Ohne min-height richtet sich die Höhe nach dem Content, die Laufschrift
 * rückt direkt unter den Fold (auf sehr kleinen/kurzen Screens bleibt
 * minimales Scrollen).
 */
@media (max-width: 1024px) {
	.ysa-hero {
		min-height: 0;
	}
}

/* -----------------------------------------------------------------------
 * Sektion 3 — Laufschrift
 * --------------------------------------------------------------------- */
@keyframes ysa-marquee {
	from {
		transform: translateX(0);
	}

	to {
		transform: translateX(-50%);
	}
}

.ysa-marquee {
	background: var(--ysa-red);
	color: var(--ysa-paper);
	padding: clamp(12px, 1.4vw, 20px) 0;
	overflow: hidden;
	border-top: 1px solid color-mix(in srgb, var(--ysa-paper) 20%, transparent);
	border-bottom: 1px solid color-mix(in srgb, var(--ysa-paper) 20%, transparent);
}

.ysa-marquee-track {
	display: flex;
	width: max-content;
	animation: ysa-marquee 26s linear infinite;
}

.ysa-marquee:hover .ysa-marquee-track {
	animation-play-state: paused;
}

.ysa-marquee-item {
	margin: 0;
	font-family: var(--ysa-font-display);
	text-transform: uppercase;
	font-size: clamp(16px, 2vw, 34px);
	letter-spacing: .06em;
	/*
	 * "pre" statt "nowrap": erhält das Leerzeichen am Textende (setzt der
	 * Shortcode), sonst entsteht an der Nahtstelle zweier Kopien eine Lücke.
	 * Die Breite kommt allein vom Text — genug Kopien für breite Fenster
	 * legt assets/js/marquee.js an.
	 */
	white-space: pre;
	flex-shrink: 0;
}

/*
 * Optionale Links im Laufschrift-Text (z. B. auf ein einzelnes Event) —
 * eigene Farbe/Unterstreichung statt der globalen Link-Styles, weil die
 * sonst zu wenig Kontrast auf dem roten Band hätten.
 */
.ysa-marquee-item a {
	color: inherit;
	text-decoration: underline;
	text-decoration-color: color-mix(in srgb, var(--ysa-paper) 45%, transparent);
	text-underline-offset: .12em;
}

.ysa-marquee-item a:focus-visible {
	text-decoration-color: currentColor;
}

@media (hover: hover) and (pointer: fine) {
	.ysa-marquee-item a:hover {
		text-decoration-color: currentColor;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ysa-marquee-track {
		animation: none;
	}
}

/*
 * Im Editor gibt es keinen Grund für die laufende Animation — der Text wird
 * ohnehin nur über das Feld "Laufschrift-Text" unter dem Inhalt gepflegt,
 * nicht hier. Ein ruhiges Standbild ist für die Vorschau ausreichend und
 * zeigt zuverlässig nur eine Zeile (die zweite, unsichtbare Kopie ist fürs
 * Redigieren ohne Bedeutung).
 */
.editor-styles-wrapper .ysa-marquee-track {
	animation: none;
}

.editor-styles-wrapper .ysa-marquee-item[aria-hidden="true"] {
	display: none;
}

/* Wiederverwendbarer Kicker (Blick nach vorn / Blick zurück) */
.ysa-kicker {
	margin: 0;
	color: var(--ysa-red-glow);
}

/* -----------------------------------------------------------------------
 * Sektion 4 — Blick nach vorn
 * --------------------------------------------------------------------- */
.ysa-vorn {
	padding: var(--ysa-space-section) var(--ysa-space-side);
	display: grid;
	/* Explizit statt auto-fit: das vollbreite Kennzahlen-Band (.ysa-vorn-stats)
	 * würde sonst alle auto-fit-Spalten belegen und nichts einklappen lassen. */
	grid-template-columns: 1fr;
	gap: clamp(28px, 4vw, 70px);
	align-items: center;
}

@media (min-width: 720px) {
	.ysa-vorn {
		grid-template-columns: repeat(2, 1fr);
	}
}

.ysa-vorn-left {
	display: flex;
	flex-direction: column;
	gap: var(--ysa-space-block);
}

.ysa-vorn-title {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(42px, 5.4vw, 96px);
	line-height: .86;
	color: var(--ysa-paper);
}

.ysa-vorn-title-script {
	font-family: var(--ysa-font-script);
	text-transform: none;
	color: var(--ysa-red-glow);
	font-size: .82em;
	line-height: 1.1;
}

.ysa-vorn-text {
	margin: 0;
	max-width: 42ch;
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-lead);
	line-height: var(--ysa-lead-leading);
	color: var(--ysa-veil-78);
}

.ysa-vorn-stats {
	grid-column: 1 / -1;
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: clamp(20px, 2.4vw, 36px) clamp(14px, 2vw, 28px);
	border-top: 1px solid var(--ysa-line-20);
	padding-top: clamp(16px, 2vw, 26px);
}

@media (min-width: 640px) {
	.ysa-vorn-stats {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (min-width: 1100px) {
	.ysa-vorn-stats {
		grid-template-columns: repeat(6, 1fr);
	}
}

.ysa-stat {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.ysa-stat-number {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-size: clamp(28px, 3.2vw, 54px);
	color: var(--ysa-red-glow);
	line-height: 1;
}

.ysa-stat-label {
	margin: 0;
	color: var(--ysa-veil-70);
}

.ysa-vorn-media.wp-block-cover {
	aspect-ratio: 4 / 5;
	margin: 0;
	min-height: 0;
	padding: 0;
}

/* -----------------------------------------------------------------------
 * Sektion 5 — Ensembles (vier Karten)
 * --------------------------------------------------------------------- */
.ysa-ensembles {
	padding: 0 var(--ysa-space-side) var(--ysa-space-section);
	display: flex;
	flex-direction: column;
	gap: clamp(24px, 3vw, 48px);
}

.ysa-ensembles-head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 18px;
	border-bottom: 1px solid var(--ysa-line-20);
	padding-bottom: clamp(14px, 1.8vw, 24px);
}

.ysa-ensembles-title {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(40px, 5vw, 88px);
	line-height: .88;
	color: var(--ysa-paper);
}

.ysa-ensembles-link {
	margin: 0;
	color: var(--ysa-red-glow);
}

.ysa-ensembles-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--ysa-space-block);
}

@media (min-width: 1000px) {
	.ysa-ensembles-grid {
		grid-template-columns: repeat(4, 1fr);
	}
}

.ysa-ensemble-card {
	position: relative;
	aspect-ratio: 3 / 4;
	overflow: hidden;
	background: var(--ysa-ink-800);
}

.ysa-ensemble-media.wp-block-cover {
	position: absolute;
	inset: 0;
	margin: 0;
	min-height: 0;
	padding: 0;
}

/*
 * Foto-Zoom bei Hover/Fokus: das eigentliche <img> (nicht der Cover-Wrapper)
 * skaliert, damit ".ysa-ensemble-card"s "overflow:hidden" das Herauswachsen
 * abschneidet und nichts über die Kartengrenze hinausragt.
 */
.ysa-ensemble-media img.wp-block-cover__image-background {
	transition: transform 500ms var(--ysa-ease-out);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-ensemble-card:hover .ysa-ensemble-media img.wp-block-cover__image-background {
		transform: scale(1.06);
	}
}

.ysa-ensemble-card:focus-within .ysa-ensemble-media img.wp-block-cover__image-background {
	transform: scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
	.ysa-ensemble-card:hover .ysa-ensemble-media img.wp-block-cover__image-background,
	.ysa-ensemble-card:focus-within .ysa-ensemble-media img.wp-block-cover__image-background {
		transform: none;
	}
}

/*
 * Stretched Link: die ganze Karte ist klickbar (verlinkt auf die
 * Ensemble-Unterseite), der sichtbare Linktext bleibt aber
 * ".screen-reader-text" — Titel/Untertitel sind weiterhin normaler,
 * bindbarer Text und kein Linkziel selbst.
 */
.ysa-ensemble-link {
	margin: 0;
}

.ysa-ensemble-link a {
	position: absolute;
	inset: 0;
	z-index: 2;
}

.ysa-ensemble-card::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to top,
		var(--ysa-ink-900) 0%,
		color-mix(in srgb, var(--ysa-ink-900) 70%, transparent) 28%,
		transparent 72%
	);
	pointer-events: none;
}

.ysa-ensemble-text {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1;
	padding: clamp(16px, 1.8vw, 28px);
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.ysa-ensemble-title {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-size: clamp(22px, 2.3vw, 38px);
	font-weight: 400;
	text-transform: uppercase;
	line-height: 1;
	color: var(--ysa-paper);
}

.ysa-ensemble-subtitle {
	margin: 0;
	font-family: var(--ysa-font-body);
	font-size: clamp(12px, .95vw, 15px);
	line-height: 1.5;
	color: var(--ysa-veil-85);
}

/*
 * Hover/Fokus: der Textblock hebt sich leicht und ein roter Strich wächst über
 * dem Titel. "transform" am Wrapper (nicht "translate" an Titel/Untertitel):
 * die scroll-getriebene Einblendung hält deren "translate" dauerhaft fest.
 */
.ysa-ensemble-text {
	transition: transform 450ms var(--ysa-ease-out);
}

.ysa-ensemble-text::before {
	content: "";
	position: absolute;
	top: 0;
	left: clamp(16px, 1.8vw, 28px);
	width: 40px;
	height: 3px;
	background: var(--ysa-red-glow);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 450ms var(--ysa-ease-out);
}

.ysa-ensemble-card:focus-within .ysa-ensemble-text {
	transform: translateY(-8px);
}

.ysa-ensemble-card:focus-within .ysa-ensemble-text::before {
	transform: scaleX(1);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-ensemble-card:hover .ysa-ensemble-text {
		transform: translateY(-8px);
	}

	.ysa-ensemble-card:hover .ysa-ensemble-text::before {
		transform: scaleX(1);
	}
}

@media (prefers-reduced-motion: reduce) {
	.ysa-ensemble-text,
	.ysa-ensemble-text::before {
		transition: none;
	}

	.ysa-ensemble-card:hover .ysa-ensemble-text,
	.ysa-ensemble-card:focus-within .ysa-ensemble-text {
		transform: none;
	}
}

/* Einleitung unter der Kopfzeile — gleicher Anreißer-Stil wie in den anderen Sektionen. */
.ysa-ensembles .ysa-ensembles-intro {
	margin: 0;
	max-width: 62ch;
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-lead);
	line-height: var(--ysa-lead-leading);
	color: var(--ysa-veil-85);
}

/*
 * Ensemble-Overlay (<dialog>, siehe assets/js/ensemble-dialog.js): Foto links,
 * Text rechts, mobil gestapelt. Öffnen/Schließen ohne Übergang beim Schließen —
 * der Auftritt ist ein kurzes Einblenden, das Schließen soll sofort wirken.
 */
@keyframes ysa-dialog-in {
	from {
		opacity: 0;
		transform: translateY(14px) scale(.985);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

html:has(dialog.ysa-ensemble-dialog[open]) {
	overflow: hidden;
}

.ysa-ensemble-link a {
	cursor: pointer;
}

dialog.ysa-ensemble-dialog {
	box-sizing: border-box;
	width: min(980px, calc(100vw - 2 * var(--ysa-space-side)));
	max-height: calc(100vh - 2 * var(--ysa-space-side));
	max-height: calc(100dvh - 2 * var(--ysa-space-side));
	margin: auto;
	padding: 0;
	overflow: auto;
	overscroll-behavior: contain;
	border: 0;
	border-top: 3px solid var(--ysa-red);
	border-radius: var(--ysa-radius);
	background: var(--ysa-ink-800);
	color: var(--ysa-paper);
	font-family: var(--ysa-font-body);
}

dialog.ysa-ensemble-dialog[open] {
	display: block;
	animation: ysa-dialog-in 300ms var(--ysa-ease-out);
}

.ysa-ensemble-dialog-inner {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	/* Der Schließen-Knopf davor (44 px + 10 px Rand) liegt über dem Inhalt statt ihn zu verschieben. */
	margin-top: -54px;
}

dialog.ysa-ensemble-dialog::backdrop {
	background: color-mix(in srgb, var(--ysa-ink-900) 82%, transparent);
	-webkit-backdrop-filter: blur(4px);
	backdrop-filter: blur(4px);
}

dialog.ysa-ensemble-dialog[open]::backdrop {
	animation: ysa-fade 250ms ease both;
}

.ysa-ensemble-dialog-media {
	position: relative;
	aspect-ratio: 16 / 10;
	background: var(--ysa-ink-900);
}

.ysa-ensemble-dialog-img {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	-o-object-fit: cover;
	   object-fit: cover;
	-o-object-position: var(--ysa-pos-m, 50% 50%);
	   object-position: var(--ysa-pos-m, 50% 50%);
}

.ysa-ensemble-dialog-body {
	display: flex;
	flex-direction: column;
	gap: clamp(14px, 1.6vw, 22px);
	padding: clamp(24px, 3.4vw, 48px) clamp(20px, 3.4vw, 48px);
}

.ysa-ensemble-dialog-kicker {
	margin: 0;
}

/* Ohne Foto läge der Schließen-Knopf sonst über Kicker und Titel. */
.ysa-ensemble-dialog-inner:not(:has(.ysa-ensemble-dialog-media)) .ysa-ensemble-dialog-body {
	padding-top: 64px;
}

.ysa-ensemble-dialog-title {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(36px, 4.4vw, 64px);
	line-height: 1;
	color: var(--ysa-paper);
}

.ysa-ensemble-dialog-text {
	display: flex;
	flex-direction: column;
	gap: 1em;
	font-size: var(--ysa-text-lead);
	line-height: var(--ysa-lead-leading);
	color: var(--ysa-veil-85);
}

.ysa-ensemble-dialog-text p {
	margin: 0;
}

.ysa-ensemble-dialog-text a {
	color: var(--ysa-paper);
	padding-bottom: 2px;
	text-decoration: none;
	/* Rote Linie dauerhaft, beim Hover wischt eine Papier-Linie von links darüber (wie bei den Team-Links). */
	background-image:
		linear-gradient(var(--ysa-paper), var(--ysa-paper)),
		linear-gradient(var(--ysa-red-glow), var(--ysa-red-glow));
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 0 2px, 100% 2px;
	transition: background-size 250ms var(--ysa-ease-out);
	-webkit-box-decoration-break: clone;
	        box-decoration-break: clone;
}

.ysa-ensemble-dialog-text a:focus-visible {
	background-size: 100% 2px, 100% 2px;
}

@media (hover: hover) and (pointer: fine) {
	.ysa-ensemble-dialog-text a:hover {
		background-size: 100% 2px, 100% 2px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ysa-ensemble-dialog-text a {
		transition: none;
	}
}

.ysa-ensemble-dialog-cta {
	margin: clamp(4px, 1vw, 12px) 0 0;
}

/* Bewerben-Link aus der Kopfzeile als Button (Farben wie "YSA – Gefüllt"). */
.ysa-ensemble-dialog-cta a {
	display: inline-block;
	padding: 18px 34px;
	border-radius: var(--ysa-radius);
	background: var(--ysa-button-bg, var(--ysa-red));
	color: var(--ysa-button-text, var(--ysa-paper));
	font-size: clamp(12px, 1vw, 15px);
	font-weight: 700;
	line-height: normal;
	letter-spacing: var(--ysa-link-tracking);
	text-transform: uppercase;
	text-decoration: none;
	transition:
		background-color 150ms ease,
		color 150ms ease;
}

.ysa-ensemble-dialog-cta a:focus-visible {
	background: var(--ysa-button-bg-hover, var(--ysa-paper));
	color: var(--ysa-button-text-hover, var(--ysa-red));
}

@media (hover: hover) and (pointer: fine) {
	.ysa-ensemble-dialog-cta a:hover {
		background: var(--ysa-button-bg-hover, var(--ysa-paper));
		color: var(--ysa-button-text-hover, var(--ysa-red));
	}
}

.ysa-ensemble-dialog-close {
	z-index: 2;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: var(--ysa-radius);
	background: color-mix(in srgb, var(--ysa-ink-900) 78%, transparent);
	color: var(--ysa-paper);
	cursor: pointer;
	transition: background-color 150ms ease;
}

.ysa-ensemble-dialog-close:focus-visible {
	background: var(--ysa-red);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-ensemble-dialog-close:hover {
		background: var(--ysa-red);
	}
}

/* Bleibt beim Scrollen im Dialog sichtbar. */
dialog.ysa-ensemble-dialog > .ysa-ensemble-dialog-close {
	position: sticky;
	top: 10px;
	margin: 10px 10px 0 auto;
}

@media (min-width: 720px) {
	.ysa-ensemble-dialog-inner:has(.ysa-ensemble-dialog-media) {
		grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
	}

	.ysa-ensemble-dialog-media {
		grid-row: 1;
		aspect-ratio: auto;
		min-height: 100%;
	}

	.ysa-ensemble-dialog-img {
		-o-object-position: var(--ysa-pos-d, 50% 50%);
		   object-position: var(--ysa-pos-d, 50% 50%);
	}

	.ysa-ensemble-dialog-body {
		align-self: center;
	}
}

@media (prefers-reduced-motion: reduce) {
	dialog.ysa-ensemble-dialog[open] {
		animation: ysa-fade 200ms ease both;
	}
}

@media print {
	dialog.ysa-ensemble-dialog {
		display: none;
	}
}

/* -----------------------------------------------------------------------
 * Sektion 6 — Spielplan (helle Sektion)
 * --------------------------------------------------------------------- */
.ysa-spielplan {
	background: var(--ysa-paper);
	color: var(--ysa-ink-900);
	padding: var(--ysa-space-section) var(--ysa-space-side);
	display: flex;
	flex-direction: column;
	gap: clamp(22px, 3vw, 44px);
}

.ysa-spielplan-head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 16px;
}

.ysa-spielplan-title-wrap {
	display: flex;
	flex-direction: column;
	gap: var(--ysa-space-block);
}

.ysa-spielplan-title-wrap .ysa-kicker {
	color: var(--ysa-ink-900);
}

.ysa-spielplan-title {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(44px, 6.2vw, 112px);
	line-height: .86;
	color: var(--ysa-red);
}

.ysa-spielplan-venue {
	margin: 0;
	color: var(--ysa-red);
}

/*
 * Geteiltes Grid: .ysa-spielplan-rows definiert die drei Spalten EINMAL für
 * alle Zeilen; jede Zeile (eigener <a>-Link) hängt sich per `subgrid` in
 * genau diese Spalten ein. Ohne Subgrid hätte jede Zeile ihr eigenes,
 * unabhängiges Grid — dann bestimmt die unterschiedlich breite `auto`-Spalte
 * (Meta-Text "Tickets" vs. "Studiobühne" vs. "Eintritt frei") pro Zeile eine
 * andere Restbreite für die Datums-/Titel-Spalten, und die Titel rutschen
 * zeilenweise unterschiedlich weit ein.
 */
.ysa-spielplan-rows {
	display: grid;
	grid-template-columns: minmax(0, .5fr) minmax(0, 2fr) auto;
	column-gap: clamp(12px, 2vw, 40px);
}

.ysa-spielplan-empty {
	font-family: var(--ysa-font-body);
	color: var(--ysa-ink-900);
}

.ysa-spielplan-row {
	display: grid;
	grid-template-columns: subgrid;
	grid-column: 1 / -1;
	align-items: baseline;
	padding: clamp(16px, 2vw, 30px) clamp(8px, 1vw, 18px);
	border-top: 1.5px solid var(--ysa-red);
	color: inherit;
}

/*
 * GeneratePress setzt global "a:visited { color: … }" (Customizer-Einstellung,
 * fürs helle Design auf dunklen Sektionen gedacht). Das ist spezifischer als
 * unser "color: inherit" oben (Element+Pseudoklasse schlägt reine Klasse) und
 * überschreibt es sonst — Folge: nach dem Anklicken wird die Zeile hier auf
 * dem hellen Spielplan-Hintergrund weiß auf weiß. Muss vor Hover/Focus stehen,
 * damit die weiterhin greifen.
 */
.ysa-spielplan-row:visited {
	color: inherit;
}

.ysa-spielplan-row:last-child {
	border-bottom: 1.5px solid var(--ysa-red);
}



.ysa-spielplan-datum {
	font-family: var(--ysa-font-display);
	font-size: clamp(15px, 1.5vw, 26px);
}

.ysa-spielplan-titel {
	font-family: var(--ysa-font-display);
	text-transform: uppercase;
	font-size: clamp(20px, 2.7vw, 48px);
	line-height: 1;
}

.ysa-spielplan-meta {
	white-space: nowrap;
}

/*
 * Schmale Screens: Drei Spalten nebeneinander lassen bei 320px nur ~20px für
 * das Datum übrig (Datum bricht zeichenweise um). Deshalb zwei Spalten —
 * Datum links, Meta rechts in der ersten Zeile — und der Titel darunter über
 * die volle Breite. Das Subgrid bleibt erhalten, damit die Datumsspalte
 * über alle Zeilen gleich breit ist.
 */
@media (max-width: 560px) {
	.ysa-spielplan-rows {
		grid-template-columns: max-content minmax(0, 1fr);
	}

	.ysa-spielplan-row {
		row-gap: 6px;
		align-items: baseline;
	}

	.ysa-spielplan-datum {
		grid-column: 1;
		grid-row: 1;
		white-space: nowrap;
	}

	.ysa-spielplan-meta {
		grid-column: 2;
		grid-row: 1;
		justify-self: end;
	}

	.ysa-spielplan-titel {
		grid-column: 1 / -1;
		grid-row: 2;
		overflow-wrap: anywhere;
	}
}

/* -----------------------------------------------------------------------
 * Sektion 7 — Blick zurück (Bildband)
 * --------------------------------------------------------------------- */
.ysa-rueckblick {
	position: relative;
	min-height: clamp(380px, 62vh, 760px);
	min-height: clamp(380px, 62svh, 760px);
	display: grid;
	align-items: end;
	overflow: hidden;
	background: var(--ysa-ink-800);
}

/*
 * Schmal: 62vh bleibt unten unangetastet, während der Hero direkt darüber
 * bei schmalen Fenstern auf "min-height: 0" zurückfällt (siehe dort) und sich
 * dadurch auf seinen tatsächlichen Inhalt schrumpft — mit 62vh wirkt dieses
 * reine Bild+Titel-Band auf dem Handy dann größer als der Hero selbst.
 * Niedrigerer vh-Anteil bringt das Verhältnis zurück in Richtung Desktop
 * (dort ist der Hero deutlich höher als dieses Band).
 */
@media (max-width: 780px) {
	.ysa-rueckblick {
		min-height: clamp(340px, 55vh, 520px);
		min-height: clamp(340px, 55svh, 520px);
	}
}

.ysa-rueckblick-media.wp-block-cover {
	position: absolute;
	inset: 0;
	margin: 0;
	min-height: 0;
	padding: 0;
}

/*
 * Mit Foto kein Farbschleier (Blick zurück, Blick nach vorn): das Cover bringt einen eigenen Überzug mit (im
 * Editor per Cover-Werkzeug einstellbar), der das Bild grau-matt wirkte. Für
 * die Lesbarkeit des Titels bei Blick zurück sorgt der Verlauf der Sektion
 * (::after unten); das Vorn-Foto trägt keinen Text.
 * Ohne Foto bleibt die Fläche in der Überzugsfarbe als Platzhalter.
 */
.ysa-rueckblick-media:has(.wp-block-cover__image-background) > .wp-block-cover__background,
.ysa-vorn-media:has(.wp-block-cover__image-background) > .wp-block-cover__background {
	display: none;
}

.ysa-rueckblick::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to top,
		color-mix(in srgb, var(--ysa-ink-900) 94%, transparent) 0%,
		color-mix(in srgb, var(--ysa-ink-900) 30%, transparent) 60%,
		color-mix(in srgb, var(--ysa-ink-900) 15%, transparent) 100%
	);
	pointer-events: none;
}

.ysa-rueckblick-content {
	position: relative;
	z-index: 1;
	padding: clamp(28px, 4vw, 70px) var(--ysa-space-side);
	display: flex;
	flex-direction: column;
	gap: clamp(12px, 1.6vw, 22px);
}

/*
 * max-width in "ch" bewusst auf dem Titel selbst (nicht auf dem Wrapper
 * .ysa-rueckblick-content) — "ch" bezieht sich auf die Zeichenbreite der
 * eigenen Schriftgröße. Da die Titel-Schrift per clamp() mit der
 * Fensterbreite mitwächst, wuchs vorher (max-width:60ch auf dem Wrapper,
 * dessen Schriftgröße nicht mitskaliert) die Textgröße schneller als der
 * Container — je breiter das Fenster, desto mehr Zeichen sprengten die
 * Zeile, und der Umbruch wurde unvorhersehbar (mal 1, mal 4 Zeilen).
 * Mit "ch" direkt am Titel skaliert die Breite proportional zur
 * Schriftgröße mit, wodurch die Zeilenzahl über alle Breakpoints hinweg
 * stabil bleibt (angestrebt: zweizeilig).
 */
.ysa-rueckblick-title {
	margin: 0;
	max-width: 21ch;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(38px, 4.4vw, 76px);
	line-height: .9;
	color: var(--ysa-paper);
}

/*
 * Doku/Video/Galerie — bewusst KEIN eigener ::after-Verlauf/eigenes Bild:
 * Der Übergang zur Bildband-Sektion darüber soll nahtlos wirken ("optisch
 * angliedern"), deshalb hier exakt der Ton, in den deren Verlauf am unteren
 * Rand ausläuft (var(--ysa-ink-900), siehe ".ysa-rueckblick::after").
 */
.ysa-rueckblick-doku {
	background: var(--ysa-ink-900);
	/* Unten bewusst weniger als oben: die Zitate sollen mittig zwischen Medien und rotem Band stehen, nicht darüber hängen. */
	padding: 0 var(--ysa-space-side) calc(var(--ysa-space-section) * 0.6);
	display: flex;
	flex-direction: column;
	gap: clamp(24px, 3vw, 48px);
}

.ysa-rueckblick-doku-text {
	margin: 0;
	max-width: 62ch;
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-lead);
	line-height: var(--ysa-lead-leading);
	color: var(--ysa-veil-85);
}

.ysa-rueckblick-media-grid {
	display: grid;
	grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
	gap: var(--ysa-space-block);
	position: relative;
}

/*
 * Die Galerie wird über "position: absolute" (mit "grid-column"/"grid-row"
 * statt "inset" zur Platzierung, siehe unten) aus dem normalen Grid-Fluss
 * genommen: Absolut positionierte Grid-Items zählen nicht mehr zur
 * "auto"-Zeilenhöhe des Grids. Ohne diesen Trick bestimmte irgendwann die
 * Galerie selbst mit über die Zeilenhöhe — sobald ihre eigenen Fotos (in
 * ihrer natürlichen Bildbreite/-höhe) zusammen höher wurden als das Video,
 * wuchs die Zeile über die vom Video vorgegebene Höhe hinaus. Das Video
 * (mit festem "aspect-ratio") wuchs nicht mit, darunter blieb eine Lücke —
 * optisch wirkte die Galerie dann höher als das Video. Jetzt bestimmt
 * ausschließlich das Video (normal im Grid-Fluss, einziger Beitrag zur
 * Zeilenhöhe) die Höhe der Zeile, die Galerie füllt sie per "height: 100%"
 * exakt aus.
 */
.ysa-rueckblick-gallery.wp-block-gallery {
	position: absolute;
	grid-column: 2;
	grid-row: 1;
	width: 100%;
}

@media (max-width: 780px) {
	.ysa-rueckblick-media-grid {
		grid-template-columns: minmax(0, 1fr);
	}

	/* Gestapeltes Layout: Galerie wieder normal im Fluss, eigene Höhe. */
	.ysa-rueckblick-gallery.wp-block-gallery {
		position: static;
		grid-column: auto;
		grid-row: auto;
	}
}

/*
 * Gestapelt gibt es kein Video daneben, dessen Höhe die Galerie füllen müsste.
 * Die Kacheln bekommen deshalb eigene Seitenverhältnisse statt "height: 100%"
 * einer unbestimmten Zeilenhöhe — sonst blitzt die rote Fuge über und unter
 * der unteren Reihe durch.
 */
@media (max-width: 780px) {
	.ysa-rueckblick-gallery.wp-block-gallery {
		height: auto;
		grid-template-rows: none;
	}

	.ysa-rueckblick-gallery .wp-block-image {
		height: auto !important;
		aspect-ratio: 4 / 3;
	}

	.ysa-rueckblick-gallery .wp-block-image:first-child {
		aspect-ratio: 16 / 9;
	}

	/* Das Bild füllt die Kachel absolut: mit "height: 100%" in einer nur per Seitenverhältnis bestimmten Höhe bleibt es bei seinem eigenen Format stehen, und die rote Fuge scheint durch. */
	.ysa-rueckblick-gallery .wp-block-image img {
		position: absolute;
		inset: 0;
	}
}

/*
 * Pressestimmen — bewusst nur Typografie: weiß auf dem Schwarz der Sektion,
 * keine Karten, Schatten oder Bilder. Zitat in der Überschriftenschrift,
 * Quelle im Label-Stil der Kennzahlen, davor ein kurzer roter Strich.
 * Keine Trennlinien. Rot: Anführungszeichen und Strich. Die
 * Anführungszeichen kommen per CSS, damit der Zitattext im Editor sauber
 * bleibt.
 */
.ysa-zitate {
	display: grid;
	grid-template-columns: 1fr;
	/* Zusätzlich zum Flex-Gap der Sektion: löst die Zitate vom Medienraster. */
	margin-top: clamp(16px, 2.5vw, 40px);
	gap: clamp(28px, 3vw, 48px) var(--ysa-space-block);
}

@media (min-width: 900px) {
	.ysa-zitate {
		grid-template-columns: repeat(3, 1fr);
	}
}

.ysa-zitat.wp-block-quote {
	margin: 0;
	padding: 0;
	border: 0;
	display: flex;
	flex-direction: column;
	gap: clamp(12px, 1.4vw, 20px);
}

.ysa-zitat p {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(22px, 2.2vw, 36px);
	font-style: normal;
	line-height: 1.15;
	text-wrap: balance;
	color: var(--ysa-paper);
}

/* Die Überschriftenschrift (Anton) hat keine Anführungszeichen-Glyphen → Fließtextschrift. */
.ysa-zitat p::before,
.ysa-zitat p::after {
	font-family: var(--ysa-font-body);
	font-weight: 700;
	/* Größer als der Text und ohne Zeilenhöhen-Anteil (line-height: 0): roter Akzent statt Satzzeichen-Beiwerk. */
	font-size: 1.35em;
	line-height: 0;
	color: var(--ysa-red-glow);
}

.ysa-zitat p::before {
	content: "\201E";
	margin-right: 0.04em;
}

.ysa-zitat p::after {
	content: "\201C";
	margin-left: 0.04em;
}

.ysa-zitat cite {
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-sm);
	font-style: normal;
	font-weight: 600;
	letter-spacing: var(--ysa-label-tracking);
	text-transform: uppercase;
	color: var(--ysa-veil-85);
	/* Quelle auf eine gemeinsame Grundlinie: die Grid-Zellen strecken sich, die Quelle rutscht nach unten. */
	margin-top: auto;
	display: flex;
	align-items: center;
	gap: 0.75em;
}

/* Kurzer roter Strich verbindet Zitat und Quelle (Gedankenstrich-Geste, rein dekorativ). */
.ysa-zitat cite::before {
	content: "";
	flex: none;
	width: 1.75em;
	height: 2px;
	background: var(--ysa-red-glow);
}

.ysa-rueckblick-video.wp-block-embed {
	margin: 0;
}

.ysa-rueckblick-video .wp-block-embed__wrapper {
	aspect-ratio: 16 / 9;
}

.ysa-rueckblick-video iframe {
	width: 100%;
	height: 100%;
}

/*
 * Foto-Mosaik statt Gutenbergs eigenem Galerie-Layout: ".is-layout-flex"
 * lieferte hier nur winzige, unterschiedlich große Thumbnails mit viel
 * totem Raum drumherum und (bei zu wenig Höhe für die Bildunterschrift)
 * Scrollbalken in einzelnen Zellen. Eigenes Grid statt Gutenbergs Flex:
 * ein großes Foto oben, ein Streifen aus drei kleineren darunter — passt
 * zur "Bildband"-Idee der Sektion. Bewusst KEIN hochkantiges Ankerfoto
 * (Spalte statt Zeile): Alle vier Motive sind selbst querformatig, ein
 * schmales, hohes Feld hätte sie in einen senkrechten Streifen
 * gequetscht. Der 2px-Spalt zeigt die Hintergrundfarbe als rote Fuge
 * durch, dasselbe Trennstrich-Motiv wie bei Partner-Kacheln und
 * Spielplan-Zeilen.
 */
.ysa-rueckblick-gallery.wp-block-gallery {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-template-rows: 2fr 1fr;
	gap: 2px;
	background: var(--ysa-red);
	height: 100%;
}

/*
 * "min-height" nur für den leeren Platzhalter unten: Mit Fotos soll
 * ausschließlich das Video (über sein "aspect-ratio") die Zeilenhöhe
 * vorgeben (siehe Kommentar bei ".ysa-rueckblick-media-grid"). Stand das
 * hier auch für den befüllten Zustand, konnte die 280px-Mindesthöhe bei
 * schmaleren Breiten größer sein als die vom Video vorgegebene Zeile —
 * die Galerie füllte die (dadurch vergrößerte) Zeile komplett aus,
 * während unter dem Video (der nicht mitwächst, da sein "aspect-ratio"
 * die Höhe fix vorgibt) eine Lücke entstand. Optisch wirkte die Galerie
 * dann höher als das Video.
 */
.ysa-rueckblick-gallery.wp-block-gallery:empty {
	min-height: 280px;
}

/*
 * "width: 100% !important" ist hier kein Reflex, sondern die Antwort auf
 * einen Spezifitäts-Trick in Gutenbergs eigenem Gallery-CSS: Core setzt die
 * Kachelbreite über ".columns-default figure.wp-block-image:not(#individual-image)"
 * — das ":not(#id)" zählt als ID-Selektor und schlägt jede reine
 * Klassen-Kombination, unabhängig von der Ladereihenfolge. Ohne "!important"
 * bleiben die Kacheln auf Cores eigener 33%-Rechnung hängen (genau das war
 * der Bug: winzige Fotos mit viel totem Rand), egal wie das Grid daneben
 * konfiguriert ist.
 */
.ysa-rueckblick-gallery .wp-block-image {
	position: relative;
	margin: 0;
	overflow: hidden;
	width: 100% !important;
	height: 100% !important;
}

.ysa-rueckblick-gallery .wp-block-image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Erstes Foto = großes Ankerbild, spannt die volle Breite oben. */
.ysa-rueckblick-gallery .wp-block-image:first-child {
	grid-column: 1 / -1;
}

/*
 * Bildnachweis: dezenter Scrim + Kleintext statt der abgeschnittenen,
 * scrollenden Unterschrift aus Cores eigenem Galerie-CSS (genau das war der
 * zweite gemeldete Bug: winzige Bilder MIT Scrollbalken). Core blendet für
 * Bilder mit Unterschrift selbst schon ein weichgezeichnetes ::before ein
 * und stylt figcaption mit Innenabstand, zentriertem Text, weißer Farbe und
 * einer eigenen (scrollenden) Scrollbar — sein Selektor nutzt denselben
 * ":not(#id)"-Spezifitäts-Trick wie bei der Kachelbreite oben, deshalb auch
 * hier "!important" statt eines Spezifitäts-Wettrüstens. Der Scrim läuft
 * bewusst über ein eigenes "::after" (Core belegt "::before" bereits),
 * damit sich beide Pseudo-Elemente nicht denselben Box gegenseitig
 * überschreiben.
 */
.ysa-rueckblick-gallery .wp-block-image:has(figcaption)::before {
	content: none !important;
}

.ysa-rueckblick-gallery .wp-block-image:has(figcaption)::after {
	content: "";
	position: absolute;
	inset: auto 0 0 0;
	height: 60%;
	background: linear-gradient(to top, color-mix(in srgb, var(--ysa-ink-900) 88%, transparent), transparent);
	pointer-events: none;
}

.ysa-rueckblick-gallery figcaption.wp-element-caption {
	position: absolute !important;
	inset: auto 8px 6px auto !important;
	left: 8px !important;
	margin: 0 !important;
	padding: 0 !important;
	font-family: var(--ysa-font-body);
	font-size: 10px !important;
	font-weight: 700;
	letter-spacing: var(--ysa-label-tracking);
	text-transform: uppercase;
	text-align: left !important;
	text-shadow: none !important;
	color: var(--ysa-veil-85) !important;
	background: none !important;
	white-space: nowrap;
	overflow: hidden !important;
	text-overflow: ellipsis;
	max-height: none !important;
}

/* Noch ohne Fotos (Redaktion liefert sie nach): ruhige Fläche statt Leere. */
.ysa-rueckblick-gallery.wp-block-gallery:empty {
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--ysa-ink-800);
}

.ysa-rueckblick-gallery.wp-block-gallery:empty::before {
	content: "Fotos folgen in Kürze";
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-sm);
	font-weight: 700;
	letter-spacing: var(--ysa-kicker-tracking);
	text-transform: uppercase;
	color: var(--ysa-veil-70);
}

/* -----------------------------------------------------------------------
 * Sektion 8 — Partner (id="partner")
 * --------------------------------------------------------------------- */
/*
 * Papierweiß statt Dunkel: die meisten Logos sind für hellen Grund gestaltet.
 * Keine Kacheln — jeder Partner ist eine Zitat-Spalte: Foto der Geschäfts-
 * führung, Zitat mit Name/Funktion, darunter das (verlinkte) Logo.
 *
 * Anzahl bewusst flexibel: auto-fit-Raster mit gleich breiten Spalten, bei 4
 * oder 5 Partnern füllt sich die Zeile, darunter bricht es in gleich breite
 * Spalten um (3+2, 2+2+1, …). Im Editor Spalte (Gruppe) duplizieren/löschen.
 *
 * Foto einheitlich in Schwarzweiß (gleicht unterschiedliche Fotoqualität
 * aus), Farbe erst beim Hover/Fokus der Spalte. Logo mit "multiply", damit
 * Logos mit weißem (nicht transparentem) Hintergrund auf dem Papierton nicht
 * als weißer Kasten stehen.
 */
.ysa-partner {
	background: var(--ysa-paper);
	color: var(--ysa-ink-900);
	padding: var(--ysa-space-section) var(--ysa-space-side);
}

.ysa-partner :focus-visible {
	outline-color: var(--ysa-red);
}

.ysa-partner .ysa-kicker {
	color: var(--ysa-red);
}

/* ".ysa-partner" davor: schlägt die Margin-Nullung ".ysa-landing h2/p" (Element + Klasse) in der Spezifität. */
.ysa-partner .ysa-partner-title {
	margin: var(--ysa-space-block) 0 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	/* Größe und Zeilenhöhe wie "Unsere Ensembles" — gleiche Überschriften-Skala in allen Sektionen. */
	font-size: clamp(40px, 5vw, 88px);
	line-height: .88;
	max-width: 18ch;
	text-wrap: balance;
	color: var(--ysa-ink-900);
}

.ysa-partner .ysa-partner-intro {
	margin: clamp(10px, 1.4vw, 22px) 0 0;
	max-width: 56ch;
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-lead);
	line-height: var(--ysa-lead-leading);
	color: color-mix(in srgb, var(--ysa-ink-900) 78%, transparent);
}

.ysa-partner-grid {
	margin-top: clamp(40px, 5vw, 80px);
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
	gap: clamp(36px, 4vw, 64px) clamp(20px, 2.4vw, 40px);
}

.ysa-pcol {
	display: flex;
	flex-direction: column;
	gap: clamp(16px, 1.6vw, 24px);
	min-width: 0;
	/* Die Scroll-Animation macht die Spalte zum eigenen Stacking-Context; ohne eigenen Papier-Hintergrund hätte "multiply" beim Logo nichts zum Durchmischen. */
	background: var(--ysa-paper);
}

.ysa-pcol-photo.wp-block-image {
	margin: 0;
	aspect-ratio: 1;
	background: color-mix(in srgb, var(--ysa-ink-900) 8%, var(--ysa-paper));
	overflow: hidden;
}

.ysa-pcol-photo.wp-block-image img {
	display: block;
	width: 100%;
	height: 100%;
	-o-object-fit: cover;
	   object-fit: cover;
	/* Gesichter sitzen in Porträts im oberen Drittel: Ausschnitt nach oben schieben, damit sie im Quadrat nicht angeschnitten werden. */
	-o-object-position: 50% 22%;
	   object-position: 50% 22%;
	filter: grayscale(1) contrast(1.04);
	transition:
		filter 500ms var(--ysa-ease-out),
		scale 800ms var(--ysa-ease-out);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-pcol:hover .ysa-pcol-photo img {
		filter: grayscale(0);
	}
}

.ysa-pcol:focus-within .ysa-pcol-photo img {
	filter: grayscale(0);
}

.ysa-pcol-quote.wp-block-quote {
	margin: 0;
	padding: 0;
	border: 0;
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: clamp(14px, 1.4vw, 20px);
}

/* Ohne Foto (WordPress rendert leere Bild-Blöcke nicht) sitzt das Zitat unten über dem Namen, auf Höhe der Zitate der Nachbarspalten — nicht oben mit Loch dazwischen. */
.ysa-pcol:not(:has(.ysa-pcol-photo)) .ysa-pcol-quote.wp-block-quote {
	justify-content: flex-end;
}

.ysa-pcol-quote p {
	margin: 0;
	font-family: var(--ysa-font-body);
	/* Das Zitat trägt die Sektion: größer als Fließtext, volle Tintenfarbe (Name/Funktion sind die leiseren Ebenen). */
	font-size: clamp(16px, 1.4vw, 22px);
	font-style: normal;
	line-height: 1.5;
	text-wrap: pretty;
	color: var(--ysa-ink-900);
}

/* Anführungszeichen per CSS, damit der Zitattext im Editor sauber bleibt (wie bei den Pressestimmen). */
.ysa-pcol-quote p::before,
.ysa-pcol-quote p::after {
	font-weight: 700;
	color: var(--ysa-red);
}

.ysa-pcol-quote p::before {
	content: "\201E";
}

.ysa-pcol-quote p::after {
	content: "\201C";
}

/* Feste Mindesthöhe (Name + zwei Zeilen Funktion): Namen und Logos stehen in jeder Spalte auf einer Linie. */
.ysa-pcol-quote cite {
	margin-top: auto;
	min-height: 3.9rem;
	font-size: clamp(13px, .95vw, 14px);
	font-style: normal;
	line-height: 1.4;
	color: color-mix(in srgb, var(--ysa-ink-900) 68%, transparent);
}

/* Der Zeilenumbruch zwischen Name und Funktion (Umschalt+Enter im Editor) würde neben dem Block-Umbruch der Namenszeile eine Leerzeile erzeugen. */
.ysa-pcol-quote cite br {
	display: none;
}

.ysa-pcol-quote cite strong {
	display: block;
	margin-bottom: 3px;
	font-size: var(--ysa-text-sm);
	font-weight: 700;
	letter-spacing: var(--ysa-label-tracking);
	text-transform: uppercase;
	color: var(--ysa-ink-900);
}

/*
 * Logo-Zeile: Bild-Block (nur der unterstützt im Editor einen Link inkl.
 * "In neuem Tab öffnen" und Link-rel). Der Link füllt die ganze Zeile;
 * die rote Linie über der Zeile und der Pfeil kommen nur, wenn wirklich
 * verlinkt ist (":has(a)"), unverlinkte Logos bleiben ruhig.
 */
.ysa-pcol-logo.wp-block-image {
	position: relative;
	margin: 0;
	height: clamp(120px, 10vw, 168px);
	padding-top: 4px;
	display: flex;
	align-items: center;
	border-top: 1px solid color-mix(in srgb, var(--ysa-ink-900) 16%, transparent);
}

.ysa-pcol-logo.wp-block-image::after {
	content: "";
	position: absolute;
	top: -1px;
	left: 0;
	width: 100%;
	height: 3px;
	background: var(--ysa-red);
	transform: scaleX(0);
	transform-origin: left;
	transition: transform 500ms var(--ysa-ease-out);
}

.ysa-pcol-logo.wp-block-image a {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	width: 100%;
	height: 100%;
	color: inherit;
}

.ysa-pcol-logo.wp-block-image img {
	display: block;
	/* Optischer Ausgleich statt gleicher Höhe: Höhe = Kantenlänge / Seitenverhältnis^0,3 (--ysa-ar aus render.php, ohne Angabe 1). Exponent 0,5 wäre flächengleich, lässt hohe, flächige Logos (Sparkasse) aber zu groß wirken; 0 wäre gleich hoch, dann dominieren breite (WGL). Die Breite folgt dem Seitenverhältnis (max-width/max-height und object-fit fangen Extremformate ab). */
	--ysa-logo-side: clamp(84px, 7.6vw, 120px);
	width: auto;
	height: calc(var(--ysa-logo-side) / pow(var(--ysa-ar, 1), .3));
	max-height: 100%;
	min-width: 0;
	max-width: min(86%, 320px);
	-o-object-fit: contain;
	   object-fit: contain;
	-o-object-position: left center;
	   object-position: left center;
	mix-blend-mode: multiply;
	transition: translate 450ms var(--ysa-ease-out);
}

/* Pfeil "↗" als gezeichnete Maske in Markenrot (kein Unicode-Zeichen) */
.ysa-pcol-logo.wp-block-image a::after {
	content: "";
	flex: none;
	width: 22px;
	height: 22px;
	background: var(--ysa-red);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='square'%3E%3Cpath d='M7 17 17 7M8 7h9v9'/%3E%3C/svg%3E") center / contain no-repeat;
	        mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='square'%3E%3Cpath d='M7 17 17 7M8 7h9v9'/%3E%3C/svg%3E") center / contain no-repeat;
	opacity: 0;
	translate: -8px 0;
	transition:
		opacity 300ms var(--ysa-ease-out),
		translate 450ms var(--ysa-ease-out);
}

.ysa-pcol-logo.wp-block-image:has(a:is(:hover, :focus-visible))::after {
	transform: scaleX(1);
}

.ysa-pcol-logo.wp-block-image a:is(:hover, :focus-visible)::after {
	opacity: 1;
	translate: 0 0;
}

.ysa-pcol-logo.wp-block-image a:is(:hover, :focus-visible) img {
	translate: 4px 0;
}

/* Touch kennt kein Hover: Pfeil bleibt dauerhaft sichtbar, damit der Absprung erkennbar ist. */
@media (hover: none) {
	.ysa-pcol-logo.wp-block-image a::after {
		opacity: 1;
		translate: 0 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ysa-pcol-photo.wp-block-image img,
	.ysa-pcol-logo.wp-block-image::after,
	.ysa-pcol-logo.wp-block-image img,
	.ysa-pcol-logo.wp-block-image a::after {
		transition: none;
	}
}

/*
 * Schmal: fünf große Fotos untereinander wären ~3500px Scrollstrecke.
 * Stattdessen Foto klein neben Name/Funktion, Zitat und Logo darunter. Der
 * Zitat-Block wird dafür mit "display: contents" aufgelöst, damit Absatz und
 * Quelle einzeln im Raster liegen.
 */
@media (max-width: 560px) {
	.ysa-pcol {
		display: grid;
		grid-template-columns: 96px 1fr;
		grid-template-areas:
			"photo cite"
			"quote quote"
			"logo logo";
		gap: 16px;
		align-items: center;
	}

	.ysa-pcol-photo.wp-block-image {
		grid-area: photo;
		aspect-ratio: 1;
	}

	.ysa-pcol-quote.wp-block-quote {
		display: contents;
	}

	.ysa-pcol-quote p {
		grid-area: quote;
	}

	.ysa-pcol-quote cite {
		grid-area: cite;
		min-height: 0;
		margin: 0;
	}

	.ysa-pcol-logo.wp-block-image {
		grid-area: logo;
	}

	/* Ohne Foto (leere Bild-Blöcke rendert WordPress nicht): keine leere 96px-Spalte links, Name steht bündig. */
	.ysa-pcol:not(:has(.ysa-pcol-photo)) {
		grid-template-columns: 1fr;
		grid-template-areas:
			"cite"
			"quote"
			"logo";
	}
}

/* -----------------------------------------------------------------------
 * Sektion 8a — Kontakt & Team (id="team")
 * --------------------------------------------------------------------- */
/*
 * Dunkel (Tintenschwarz) zwischen dem Papierweiß der Partner und dem Rot der
 * CTA. Vier Gruppen mit Überschrift, darin ein Raster aus Personen-Karten.
 * "auto-fill" statt "auto-fit": eine einzelne Person (Intendanz,
 * Projektleitung) bleibt eine normale Spaltenbreite und stimmt mit den
 * Spalten der anderen Gruppen überein.
 *
 * Direktkontakt ist optional: Die Karte hat Foto, Name, Funktion und eine
 * Zuständigkeitszeile; der E-Mail-Link (.ysa-tcard-mail) sitzt unten und
 * entfällt einfach, wenn die Person nicht direkt angeschrieben werden soll —
 * das Raster bleibt trotzdem sauber. Foto wie bei den Partnern in Schwarzweiß,
 * Farbe bei Hover/Fokus. Ohne Foto steht eine dunkle Fläche als Platzhalter.
 */
.ysa-team {
	background: var(--ysa-ink-900);
	color: var(--ysa-paper);
	padding: var(--ysa-space-section) var(--ysa-space-side);
}

.ysa-team .ysa-team-title {
	margin: var(--ysa-space-block) 0 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(40px, 5vw, 88px);
	line-height: .88;
	max-width: 18ch;
	text-wrap: balance;
	color: var(--ysa-paper);
}

.ysa-team .ysa-team-intro {
	margin: clamp(10px, 1.4vw, 22px) 0 0;
	max-width: 56ch;
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-lead);
	line-height: var(--ysa-lead-leading);
	color: var(--ysa-veil-78);
}

.ysa-team .ysa-team-group {
	margin-top: clamp(44px, 5.5vw, 88px);
}

.ysa-team .ysa-team-group-title {
	margin: 0 0 clamp(22px, 2.6vw, 40px);
	padding-bottom: clamp(12px, 1.4vw, 18px);
	border-bottom: 1px solid var(--ysa-line-20);
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-md);
	font-weight: 700;
	letter-spacing: var(--ysa-link-tracking);
	text-transform: uppercase;
	color: var(--ysa-veil-70);
}

.ysa-team-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 260px));
	gap: clamp(32px, 3.6vw, 56px) clamp(20px, 2.4vw, 40px);
}

.ysa-tcard {
	display: flex;
	flex-direction: column;
	gap: clamp(14px, 1.4vw, 20px);
	min-width: 0;
}

.ysa-tcard-photo.wp-block-image {
	margin: 0;
	aspect-ratio: 1;
	background: var(--ysa-ink-800);
	overflow: hidden;
}

.ysa-tcard-photo.wp-block-image img {
	display: block;
	width: 100%;
	height: 100%;
	-o-object-fit: cover;
	   object-fit: cover;
	/* Gesichter sitzen in Porträts im oberen Drittel — wie bei den Partnern. */
	-o-object-position: 50% 22%;
	   object-position: 50% 22%;
	filter: grayscale(1) contrast(1.04);
	transition:
		filter 500ms var(--ysa-ease-out),
		scale 800ms var(--ysa-ease-out);
}

/* Leere Bild-Blöcke rendert WordPress nicht: dunkle Fläche hält Raster und Namenszeilen auf einer Linie. */
.ysa-tcard:not(:has(.ysa-tcard-photo))::before {
	content: "";
	aspect-ratio: 1;
	background: var(--ysa-ink-800);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-tcard:hover .ysa-tcard-photo img {
		filter: grayscale(0);
	}
}

.ysa-tcard:focus-within .ysa-tcard-photo img {
	filter: grayscale(0);
}

.ysa-tcard-body {
	flex: 1;
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.ysa-team .ysa-tcard-name {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(22px, 1.9vw, 30px);
	line-height: 1;
	color: var(--ysa-paper);
}

.ysa-team .ysa-tcard-role {
	margin: 0;
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-sm);
	font-weight: 700;
	letter-spacing: var(--ysa-label-tracking);
	line-height: 1.4;
	text-transform: uppercase;
	color: var(--ysa-red-glow);
}

.ysa-team .ysa-tcard-note {
	margin: 4px 0 0;
	font-family: var(--ysa-font-body);
	font-size: clamp(14px, 1vw, 15px);
	line-height: 1.5;
	text-wrap: pretty;
	color: var(--ysa-veil-78);
}

/* margin-top:auto schiebt E-Mail und Telefon in jeder Karte nach unten; fehlen beide, bleibt die Karte einfach kürzer. */
.ysa-team .ysa-tcard-contact {
	margin: auto 0 0;
	padding-top: 10px;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 14px;
}

.ysa-team .ysa-tcard-mail,
.ysa-team .ysa-tcard-phone {
	margin: 0;
	font-family: var(--ysa-font-body);
	font-size: var(--ysa-text-sm);
	font-weight: 700;
	letter-spacing: var(--ysa-link-tracking);
	text-transform: uppercase;
}

.ysa-team .ysa-tcard-mail a,
.ysa-team .ysa-tcard-phone a {
	color: var(--ysa-paper);
	padding-bottom: 5px;
	text-decoration: none;
	/* Rote Linie dauerhaft, eine zweite (Papier) wischt beim Hover von links darüber — wie bei den anderen Links. */
	background-image:
		linear-gradient(var(--ysa-paper), var(--ysa-paper)),
		linear-gradient(var(--ysa-red-glow), var(--ysa-red-glow));
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 0 2px, 100% 2px;
	transition: background-size 250ms var(--ysa-ease-out);
}

.ysa-team .ysa-tcard-mail a:focus-visible,
.ysa-team .ysa-tcard-phone a:focus-visible {
	background-size: 100% 2px, 100% 2px;
}

@media (hover: hover) and (pointer: fine) {
	.ysa-team .ysa-tcard-mail a:hover,
	.ysa-team .ysa-tcard-phone a:hover {
		background-size: 100% 2px, 100% 2px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ysa-tcard-photo.wp-block-image img,
	.ysa-team .ysa-tcard-mail a,
	.ysa-team .ysa-tcard-phone a {
		transition: none;
	}
}

/*
 * Breit: Gruppen mit nur einer Person (Intendanz, Projektleitung) stehen
 * paarweise nebeneinander statt je eine halbleere Zeile zu belegen. Gruppen mit
 * mehreren Personen laufen über die volle Breite. Rein datengetrieben (:has),
 * damit hinzugefügte oder gelöschte Gruppen nichts verschieben.
 */
@media (min-width: 900px) {
	.ysa-team {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		-moz-column-gap: clamp(32px, 4vw, 72px);
		     column-gap: clamp(32px, 4vw, 72px);
	}

	.ysa-team > * {
		grid-column: 1 / -1;
	}

	.ysa-team > .ysa-team-group:not(:has(.ysa-tcard + .ysa-tcard)) {
		grid-column: auto;
	}
}

/*
 * Gruppe ohne Überschrift ("Ohne Überschrift" in der Seitenleiste): keine
 * Überschrift, keine Linie. Folgt sie auf eine andere Gruppe, rückt sie auf den
 * Zeilenabstand des Rasters heran, damit mehrere solche Gruppen wie ein
 * durchgehendes Raster wirken.
 */
.ysa-team .ysa-team-group--plain {
	grid-column: 1 / -1;
}

.ysa-team .ysa-team-group + .ysa-team-group--plain {
	margin-top: clamp(32px, 3.6vw, 56px);
}

/* Schmal: Foto klein neben dem Text statt großer Quadrate untereinander. */
@media (max-width: 560px) {
	.ysa-team-grid {
		grid-template-columns: 1fr;
		gap: 0;
	}

	/* Trennlinie plus Luft: ohne sie laufen Mail-Link und nächster Name ineinander. */
	.ysa-tcard {
		display: grid;
		grid-template-columns: 96px 1fr;
		align-items: start;
		gap: 16px;
		padding-block: 24px;
		border-top: 1px solid var(--ysa-line-20);
	}

	.ysa-tcard:first-child {
		padding-top: 0;
		border-top: 0;
	}

	.ysa-tcard:last-child {
		padding-bottom: 0;
	}

	/* Platzhalter-Fläche bleibt auch ohne Foto, damit die Karten gleich aufgebaut sind. */
	.ysa-tcard:not(:has(.ysa-tcard-photo))::before {
		width: 96px;
	}
}

/* -----------------------------------------------------------------------
 * Sektion 8b — CTA
 * --------------------------------------------------------------------- */
.ysa-cta {
	background: var(--ysa-red);
	color: var(--ysa-paper);
	padding: var(--ysa-space-section) var(--ysa-space-side);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: clamp(18px, 2.6vw, 36px);
	text-align: center;
}

.ysa-cta-script {
	margin: 0;
	font-family: var(--ysa-font-script);
	font-size: clamp(34px, 5.2vw, 84px);
	line-height: 1;
}

.ysa-cta-title {
	margin: 0;
	font-family: var(--ysa-font-display);
	font-weight: var(--ysa-heading-weight);
	text-transform: var(--ysa-heading-transform);
	font-size: clamp(42px, 6.6vw, 124px);
	line-height: .84;
	max-width: 20ch;
}

.ysa-cta-actions.wp-block-buttons {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	justify-content: center;
	margin: 0;
}

/* -----------------------------------------------------------------------
 * Sektion 9 — Footer (site-weit)
 * --------------------------------------------------------------------- */
/*
 * "body .site-info" statt ".site-info": GeneratePress liefert per
 * Customizer-generiertem Dynamic-CSS eigene ".site-info{background-color:…}"-
 * und ".inside-site-info{padding-left/right:…}"-Regeln nach unserem
 * Theme-Stylesheet aus — bei gleicher Spezifität gewinnt sonst GP und der
 * Footer würde hell statt dunkel und mit starrem statt responsivem
 * Seitenabstand rendern. Ein zusätzliches Element in der Selektor-Kette
 * hebt die Spezifität minimal an, ohne "!important" zu brauchen.
 */
/* Farben aus dem Customizer (Farben → Footer), gespiegelt in --ysa-footer-*. */
body .site-info {
	background: var(--ysa-footer-bg, var(--ysa-ink-900));
	color: var(--ysa-footer-text, var(--ysa-paper));
	border-top: 1px solid var(--ysa-line-18);
}

body .site-info .inside-site-info {
	padding: clamp(22px, 3vw, 42px) var(--ysa-space-side);
	max-width: none;
}

.site-info .copyright-bar {
	display: block;
	width: 100%;
}

.ysa-footer {
	display: flex;
	flex-direction: column;
	gap: clamp(14px, 2.2vw, 22px);
	width: 100%;
}

.ysa-footer-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: clamp(12px, 2.4vw, 28px);
}

.ysa-footer-nav.ysa-footer-nav {
	margin: 0;
}

.ysa-footer-menu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: clamp(10px, 1.8vw, 22px);
	margin: 0;
	padding: 0;
	list-style: none;
}

.ysa-footer-menu li {
	margin: 0;
}

/* Schriftart und -stärke erben die Links von .site-info — Customizer: Typografie → "Footer". */
.ysa-footer-menu a {
	line-height: normal;
	text-decoration: none;
	padding-bottom: 3px;
}

/* ".site-info" davor: schlägt GPs ".site-info a"-Regel (Farben → Footer → Links). */
.site-info .ysa-footer-menu a,
.site-info .ysa-footer-social-link {
	color: color-mix(in srgb, var(--ysa-footer-link, var(--ysa-paper)) 82%, transparent);
}

.ysa-footer-social {
	display: flex;
	align-items: center;
	gap: 10px;
}

/*
 * Schmal: ".ysa-footer-row" ist "flex-wrap:wrap" — sobald das
 * Rechtliches-Menü nicht mehr neben den Social-Icons in eine Zeile passt,
 * rutschen diese als eigene Zeile herunter, bleiben dabei aber (wie das Menü
 * darüber) linksbündig. "width: 100%" erzwingt diese eigene Zeile
 * unabhängig vom verfügbaren Platz, "justify-content: center" zentriert die
 * beiden Icons darin.
 */
@media (max-width: 768px) {
	.ysa-footer-social {
		width: 100%;
		justify-content: center;
	}
}

.ysa-footer-social-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border: 1.5px solid var(--ysa-line-20);
	transition: color .15s ease, background-color .15s ease, border-color .15s ease;
}

.site-info .ysa-footer-social-link:focus-visible {
	color: var(--ysa-paper);
	background: var(--ysa-red);
	border-color: var(--ysa-red);
}

@media (hover: hover) and (pointer: fine) {
	.site-info .ysa-footer-social-link:hover {
		color: var(--ysa-paper);
		background: var(--ysa-red);
		border-color: var(--ysa-red);
	}
}

.ysa-footer-copyright {
	margin: 0;
	font-size: 12px;
	font-weight: 500;
	letter-spacing: .04em;
	line-height: normal;
	color: color-mix(in srgb, var(--ysa-footer-text, var(--ysa-paper)) 70%, transparent);
}

/* -----------------------------------------------------------------------
 * Touch — Klickflächen ab 44px, nur für grobe Zeiger (Touch/Stylus), damit
 * die Desktop-Optik unverändert bleibt.
 * --------------------------------------------------------------------- */
@media (pointer: coarse) {
	.ysa-footer-menu a,
	.ysa-ensembles-link a {
		display: inline-flex;
		align-items: center;
		min-height: 44px;
	}

	/* Nav-Links behalten ihr display (Mobile-Menü: block, Desktop: inline-block). */
	#masthead #primary-menu.main-nav .menu > li > a {
		min-height: 44px;
		align-content: center;
	}

	.ysa-footer-social-link {
		width: 44px;
		height: 44px;
	}
}

/* Kicker: weite Sperrung bricht bei 320px sonst unruhig um (Hero-Überzeile zweizeilig). */
@media (max-width: 480px) {
	:root {
		--ysa-kicker-tracking: .26em;
	}
}

/* -----------------------------------------------------------------------
 * Laufschrift — Pause-Button (WCAG 2.2.2) und Ruhezustände
 * --------------------------------------------------------------------- */
.ysa-marquee {
	position: relative;
}

/* Tastaturfokus im Text (Links) oder auf dem Button hält die Spur an. */
.ysa-marquee:focus-within .ysa-marquee-track,
.ysa-marquee.is-paused .ysa-marquee-track {
	animation-play-state: paused;
}

.ysa-marquee-toggle {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	padding: 0 12px;
	border: 0;
	border-radius: var(--ysa-radius);
	background: var(--ysa-red);
	color: var(--ysa-paper);
	cursor: pointer;
	box-shadow: -12px 0 14px -6px var(--ysa-red);
	transition:
		background-color 150ms ease,
		color 150ms ease,
		transform 160ms var(--ysa-ease-out);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-marquee-toggle:hover {
		background: var(--ysa-ink-900);
		color: var(--ysa-paper);
	}
}

.ysa-marquee-toggle:active {
	transform: scale(.97);
}

.ysa-marquee-toggle:focus-visible {
	outline-color: var(--ysa-ink-900);
	outline-offset: -4px;
}

.ysa-marquee-toggle .ysa-marquee-icon-play,
.ysa-marquee-toggle[aria-pressed="true"] .ysa-marquee-icon-pause {
	display: none;
}

.ysa-marquee-toggle[aria-pressed="true"] .ysa-marquee-icon-play {
	display: block;
}

/* Editor: keine Animation, also auch kein Button. */
.editor-styles-wrapper .ysa-marquee-toggle {
	display: none;
}

/*
 * Reduzierte Bewegung: Statt eines abgeschnittenen Standbilds den Text
 * umbrechen lassen — kein Button nötig, nichts bewegt sich.
 */
@media (prefers-reduced-motion: reduce) {
	.ysa-marquee-toggle {
		display: none;
	}

	.ysa-marquee-track {
		width: auto;
		padding: 0 var(--ysa-space-side);
	}

	.ysa-marquee-item {
		white-space: normal;
	}

	.ysa-marquee-item[aria-hidden="true"] {
		display: none;
	}
}

/* -----------------------------------------------------------------------
 * Bewegung
 * Reihenfolge der Entscheidungen: erst prüfen, ob etwas animieren soll
 * (Häufigkeit), dann Zweck, dann Werkzeug. Nur transform/opacity (plus
 * kleine Farbflächen); UI-Dauern bleiben unter 300ms. Reduzierte Bewegung
 * ersetzt Bewegung durch ein kurzes Einblenden — sie schaltet nicht ab.
 * --------------------------------------------------------------------- */

/* 1 · Buttons und Nav-CTA — Feedback beim Hover und Drücken */
.wp-block-button.is-style-ysa-filled .wp-block-button__link,
.wp-block-button.is-style-ysa-outline .wp-block-button__link,
#masthead #primary-menu.main-nav .menu > li.ysa-nav-cta > a {
	transition:
		background-color 150ms ease,
		color 150ms ease,
		border-color 150ms ease,
		transform 160ms var(--ysa-ease-out);
}

.wp-block-button.is-style-ysa-filled .wp-block-button__link:active,
.wp-block-button.is-style-ysa-outline .wp-block-button__link:active,
#masthead #primary-menu.main-nav .menu > li.ysa-nav-cta > a:active {
	transform: scale(.97);
}

/* 2 · Hero — ein einziger Auftritt: Script-Wisch, dann Subline und Buttons.
 * H1 und Kicker bewegen sich bewusst nicht (LCP, sofort lesbar).
 * Der Clip-Rahmen ist großzügig, damit der Text-Schatten nicht abgeschnitten wird. */
@keyframes ysa-script-wipe {
	from {
		clip-path: inset(-60% 100% -60% -10%);
	}

	to {
		clip-path: inset(-60% -10% -60% -10%);
	}
}

@keyframes ysa-rise {
	from {
		opacity: 0;
		transform: translateY(12px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes ysa-fade {
	from {
		opacity: 0;
	}

	to {
		opacity: 1;
	}
}

.ysa-hero-script {
	animation: ysa-script-wipe 700ms var(--ysa-ease-out) 250ms both;
}

.ysa-hero-subline {
	animation: ysa-rise 450ms var(--ysa-ease-out) 350ms both;
}

.ysa-hero-actions.wp-block-buttons {
	animation: ysa-rise 450ms var(--ysa-ease-out) 420ms both;
}

/* Im Editor bleibt alles ruhig sichtbar. */
.editor-styles-wrapper .ysa-hero-script,
.editor-styles-wrapper .ysa-hero-subline,
.editor-styles-wrapper .ysa-hero-actions.wp-block-buttons {
	animation: none;
}

/* 3 · Mobiles Menü — kommt aus dem Header, geht dorthin zurück.
 * Betroffen ist die <ul>, die GeneratePress per display:none/flex schaltet;
 * "display" wird deshalb diskret mitübergeben, damit auch der Ausstieg läuft. */
@media (max-width: 768px) {
	#masthead #primary-menu.main-nav .menu {
		transform-origin: top;
		transition:
			opacity 200ms var(--ysa-ease-drawer),
			transform 200ms var(--ysa-ease-drawer),
			display 200ms allow-discrete;
	}

	#masthead .main-navigation:not(.toggled) #primary-menu.main-nav .menu {
		opacity: 0;
		transform: translateY(-8px);
	}

	@starting-style {
		#masthead .main-navigation.toggled #primary-menu.main-nav .menu {
			opacity: 0;
			transform: translateY(-8px);
		}
	}
}

/* 4 · Spielplan-Zeilen — Rot wischt von links ein, der Titel rückt nach, plus
 * Press-Feedback wie bei Buttons/Nav-CTA (scale(.97), 160ms ease-out).
 * Die Fläche ist ein Hintergrundverlauf, dessen Breite animiert wird (kein
 * Layout-Sprung); Farbe wechselt zeitgleich, damit der Text nie unlesbar ist. */
.ysa-spielplan-row {
	background-image: linear-gradient(var(--ysa-red), var(--ysa-red));
	background-repeat: no-repeat;
	background-position: 0 0;
	background-size: 0 100%;
	transition:
		background-size 380ms var(--ysa-ease-out),
		color 220ms ease,
		transform 160ms var(--ysa-ease-out);
}

.ysa-spielplan-titel {
	transition: translate 380ms var(--ysa-ease-out);
}

.ysa-spielplan-row:focus-visible {
	background-size: 100% 100%;
	color: var(--ysa-paper);
}

.ysa-spielplan-row:focus-visible .ysa-spielplan-titel {
	translate: 10px 0;
}

@media (hover: hover) and (pointer: fine) {
	.ysa-spielplan-row:hover {
		background-size: 100% 100%;
		color: var(--ysa-paper);
	}

	.ysa-spielplan-row:hover .ysa-spielplan-titel {
		translate: 10px 0;
	}
}

@media (prefers-reduced-motion: reduce) {
	.ysa-spielplan-row,
	.ysa-spielplan-titel {
		transition: color 150ms ease;
	}

	.ysa-spielplan-row:hover .ysa-spielplan-titel,
	.ysa-spielplan-row:focus-visible .ysa-spielplan-titel {
		translate: none;
	}
}

.ysa-spielplan-row:active {
	transform: scale(.97);
}

/* 5 · Textlinks — ein Mechanismus (Unterstrich-Wipe) für alle, zwei
 * Intensitäten je nach Hover-Häufigkeit. Häufige Navigation (Header-Nav,
 * Logo, Footer-Nav) bleibt farblich ruhig — nur der Strich erscheint.
 * Seltener gehoverte Einzel-Links (Ensembles) bekommen zusätzlich
 * den Farbwechsel zu Weiß; die Farbe wird dabei explizit gesetzt statt sie
 * GeneratePress' globaler ".a:hover{color:var(--contrast)}"-Regel zu
 * überlassen, deren Ladereihenfolge zufällig gewinnen oder verlieren kann. */
#masthead #primary-menu.main-nav .menu > li > a,
#masthead .ysa-logo-lockup a,
.ysa-footer-menu a,
.ysa-ensembles-link a {
	background-image: linear-gradient(currentColor, currentColor);
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 0 1.5px;
	transition: background-size 200ms var(--ysa-ease-out);
}

.ysa-ensembles-link a {
	padding-bottom: 4px;
	transition:
		color 200ms ease,
		background-size 200ms var(--ysa-ease-out);
}

@media (hover: hover) and (pointer: fine) {
	#masthead #primary-menu.main-nav .menu > li > a:hover,
	#masthead .ysa-logo-lockup a:hover,
	.ysa-footer-menu a:hover {
		background-size: 100% 1.5px;
	}

	.ysa-ensembles-link a:hover {
		color: var(--ysa-paper);
		background-size: 100% 1.5px;
	}

	/* Hover-Farben nur, wenn im Customizer gesetzt — sonst bleibt die Farbe ruhig. */
	#masthead #primary-menu.main-nav .menu > li > a:hover {
		color: var(--ysa-nav-text-hover, var(--ysa-nav-text, var(--ysa-paper)));
	}

	.site-info .ysa-footer-menu a:hover {
		color: var(--ysa-footer-link-hover, color-mix(in srgb, var(--ysa-footer-link, var(--ysa-paper)) 82%, transparent));
	}
}

#masthead #primary-menu.main-nav .menu > li > a:focus-visible,
#masthead .ysa-logo-lockup a:focus-visible,
.ysa-footer-menu a:focus-visible {
	background-size: 100% 1.5px;
}

#masthead #primary-menu.main-nav .menu > li > a:focus-visible {
	color: var(--ysa-nav-text-hover, var(--ysa-nav-text, var(--ysa-paper)));
}

.site-info .ysa-footer-menu a:focus-visible {
	color: var(--ysa-footer-link-hover, color-mix(in srgb, var(--ysa-footer-link, var(--ysa-paper)) 82%, transparent));
}

.ysa-ensembles-link a:focus-visible {
	color: var(--ysa-paper);
	background-size: 100% 1.5px;
}

/* 6 · Ensemble-Karten — scroll-getriebener Versatz (nur wo unterstützt).
 * Die Animation hängt an der Scrollposition und läuft dadurch nie "von vorn",
 * auch nicht nach Anker-Sprüngen aus dem Menü. */
@keyframes ysa-rise-scroll {
	from {
		opacity: 0;
		transform: translateY(16px);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.ysa-ensemble-card {
			animation: ysa-rise-scroll linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 55%;
		}

		.ysa-ensemble-card:nth-child(2) {
			animation-range: entry 8% entry 63%;
		}

		.ysa-ensemble-card:nth-child(3) {
			animation-range: entry 16% entry 71%;
		}

		.ysa-ensemble-card:nth-child(4) {
			animation-range: entry 24% entry 79%;
		}

		.editor-styles-wrapper .ysa-ensemble-card {
			animation: none;
		}

		/* Partner-Spalten — gestaffelt wie die Ensemble-Karten (bis zu fünf Spalten). */
		.ysa-pcol {
			animation: ysa-rise-scroll linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 55%;
		}

		.ysa-pcol:nth-child(2) {
			animation-range: entry 8% entry 63%;
		}

		.ysa-pcol:nth-child(3) {
			animation-range: entry 16% entry 71%;
		}

		.ysa-pcol:nth-child(4) {
			animation-range: entry 24% entry 79%;
		}

		.ysa-pcol:nth-child(5) {
			animation-range: entry 32% entry 87%;
		}

		.editor-styles-wrapper .ysa-pcol {
			animation: none;
		}

		/* Team-Karten — gleiche Staffelung, pro Reihe bis zu vier Karten. */
		.ysa-tcard {
			animation: ysa-rise-scroll linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 55%;
		}

		.ysa-tcard:nth-child(2) {
			animation-range: entry 8% entry 63%;
		}

		.ysa-tcard:nth-child(3) {
			animation-range: entry 16% entry 71%;
		}

		.ysa-tcard:nth-child(4) {
			animation-range: entry 24% entry 79%;
		}

		.editor-styles-wrapper .ysa-tcard {
			animation: none;
		}
	}
}

/* Reduzierte Bewegung: gedämpfte Varianten statt Abschalten */
@media (prefers-reduced-motion: reduce) {
	.ysa-hero-script,
	.ysa-hero-subline,
	.ysa-hero-actions.wp-block-buttons {
		animation: ysa-fade 200ms ease both;
	}

	.wp-block-button.is-style-ysa-filled .wp-block-button__link:active,
	.wp-block-button.is-style-ysa-outline .wp-block-button__link:active,
	#masthead #primary-menu.main-nav .menu > li.ysa-nav-cta > a:active,
	.ysa-spielplan-row:active,
	.ysa-marquee-toggle:active {
		transform: none;
	}

}

@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
	#masthead .main-navigation:not(.toggled) #primary-menu.main-nav .menu {
		transform: none;
	}

	@starting-style {
		#masthead .main-navigation.toggled #primary-menu.main-nav .menu {
			transform: none;
		}
	}
}

/* -----------------------------------------------------------------------
 * Touch-Ziele (WCAG 2.5.8 / 44 px)
 *
 * Optik bleibt unverändert: Kleine Links bekommen eine unsichtbare
 * Trefferfläche per ::before (nur ::after ist bei den Ziel-Elementen
 * teilweise belegt). Größere Flächen (Button, Zeile) wachsen real.
 * --------------------------------------------------------------------- */
#masthead #primary-menu.main-nav .menu > li:not(.ysa-nav-cta) > a,
.ysa-ensembles-link a,
.site-info .ysa-footer-menu a,
.site-info .ysa-footer-social-link {
	position: relative;
}

#masthead #primary-menu.main-nav .menu > li:not(.ysa-nav-cta) > a::before,
.ysa-ensembles-link a::before,
.site-info .ysa-footer-menu a::before {
	content: "";
	position: absolute;
	inset: -12px -6px;
}

.site-info .ysa-footer-social-link::before {
	content: "";
	position: absolute;
	inset: -6px;
}

#masthead #primary-menu.main-nav .menu > li.ysa-nav-cta > a {
	padding-block: 14px;
}

.ysa-spielplan-row {
	min-height: 44px;
}

/* Mobil: Burger-Button und Menüpunkte im aufgeklappten Menü */
#masthead .menu-toggle {
	min-width: 44px;
	min-height: 44px;
}

@media (max-width: 768px) {
	#masthead .main-navigation.toggled #primary-menu.main-nav .menu > li > a {
		display: flex;
		align-items: center;
		min-height: 44px;
	}
}

/* Touch-Ziele, zweite Runde: Logo, Laufschrift-Links, Galerie-Lupe, Team-Mail */
#masthead .site-branding a,
.ysa-marquee-item a,
.ysa-team .ysa-tcard-mail a,
.ysa-team .ysa-tcard-phone a {
	position: relative;
}

#masthead .site-branding a::before,
.ysa-marquee-item a::before {
	content: "";
	position: absolute;
	inset: -5px 0;
}

.ysa-team .ysa-tcard-mail a::before,
.ysa-team .ysa-tcard-phone a::before {
	content: "";
	position: absolute;
	inset: -11px -6px;
}

/* Kein "position: relative" am Button: Core positioniert ihn absolut (und damit ::before); relative legte ihn in den Fluss der Galerie-Kachel und nahm dem Bild 20 px Höhe. */
.wp-block-image .lightbox-trigger::before {
	content: "";
	position: absolute;
	inset: -12px;
}

/* Footer-Menü: 18 px Textzeile + 2 × 13 px = 44 px */
.site-info .ysa-footer-menu a::before {
	inset: -13px -6px;
}

/* Überschriften mobil: Zeilenabstand .84–.9 ist für große Desktop-Titel gedacht, bei kleiner Schrift klebt er. */
@media (max-width: 780px) {
	.ysa-vorn-title,
	.ysa-ensembles-title,
	.ysa-spielplan-title,
	.ysa-rueckblick-title,
	.ysa-partner .ysa-partner-title,
	.ysa-team .ysa-team-title,
	.ysa-cta-title {
		line-height: 1.04;
	}
}

/* Druck: scroll-getriebene Einblendung darf Inhalt nicht versteckt lassen */
@media print {
	.ysa-ensemble-card,
	.ysa-pcol,
	.ysa-tcard {
		animation: none;
		opacity: 1;
		transform: none;
	}
}

/* -----------------------------------------------------------------------
 * 7 · Weitere scroll-getriebene Auftritte (gleiche Mechanik wie die Karten)
 *
 * Spielplan-Zeilen, Rückblick-Galerie und Zitate rutschen gestaffelt ein,
 * das Blick-nach-vorn-Foto öffnet sich wie ein Vorhang, und der Schriftzug
 * der Schluss-Sektion greift den Wisch aus dem Hero wieder auf.
 *
 * "translate" statt "transform": Die Zeilen und Galerie-Bilder haben eigenes
 * Transform-Feedback (:active, Hover), das eine fortlaufende Animation mit
 * "both" sonst dauerhaft überschreiben würde.
 * --------------------------------------------------------------------- */
@keyframes ysa-rise-scroll-t {
	from {
		opacity: 0;
		translate: 0 16px;
	}

	to {
		opacity: 1;
		translate: 0 0;
	}
}

@keyframes ysa-curtain-scroll {
	from {
		clip-path: inset(0 0 100% 0);
	}

	to {
		clip-path: inset(0);
	}
}

@supports (animation-timeline: view()) {
	@media (prefers-reduced-motion: no-preference) {
		.ysa-spielplan-row,
		.ysa-rueckblick-gallery > .wp-block-image,
		.ysa-zitat {
			animation: ysa-rise-scroll-t linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 55%;
		}

		.ysa-spielplan-row:nth-child(2),
		.ysa-rueckblick-gallery > .wp-block-image:nth-child(2),
		.ysa-zitat:nth-child(2) {
			animation-range: entry 8% entry 63%;
		}

		.ysa-spielplan-row:nth-child(3),
		.ysa-rueckblick-gallery > .wp-block-image:nth-child(3),
		.ysa-zitat:nth-child(3) {
			animation-range: entry 16% entry 71%;
		}

		.ysa-spielplan-row:nth-child(n + 4),
		.ysa-rueckblick-gallery > .wp-block-image:nth-child(n + 4) {
			animation-range: entry 24% entry 79%;
		}

		.ysa-vorn-media.wp-block-cover {
			animation: ysa-curtain-scroll linear both;
			animation-timeline: view();
			animation-range: entry 0% entry 60%;
		}

		.ysa-cta-script {
			animation: ysa-script-wipe linear both;
			animation-timeline: view();
			animation-range: entry 20% entry 70%;
		}

		/* Ensemble-Texte — Titel, dann Untertitel steigen nach der Karte auf.
		 * Die Karte hat overflow:hidden und ist damit selbst Scroll-Container: ein view() am Text
		 * hinge an ihr statt am Fenster (läuft nie). Deshalb benannte Timeline der Karte. */
		.ysa-ensemble-card {
			view-timeline: --ysa-card block;
		}

		.ysa-ensemble-title,
		.ysa-ensemble-subtitle {
			animation: ysa-rise-scroll-t linear both;
			animation-timeline: --ysa-card;
			/* Der Text sitzt am Kartenboden und wird erst am Ende des Eintritts sichtbar: Bereich reicht deshalb in "contain" hinein. */
			animation-range: entry 80% contain 25%;
		}

		.ysa-ensemble-subtitle {
			animation-range: entry 90% contain 35%;
		}

		.editor-styles-wrapper .ysa-ensemble-title,
		.editor-styles-wrapper .ysa-ensemble-subtitle,
		.editor-styles-wrapper .ysa-spielplan-row,
		.editor-styles-wrapper .ysa-rueckblick-gallery > .wp-block-image,
		.editor-styles-wrapper .ysa-zitat,
		.editor-styles-wrapper .ysa-vorn-media.wp-block-cover,
		.editor-styles-wrapper .ysa-cta-script {
			animation: none;
		}
	}
}

@media print {
	.ysa-ensemble-title,
	.ysa-ensemble-subtitle,
	.ysa-spielplan-row,
	.ysa-rueckblick-gallery > .wp-block-image,
	.ysa-zitat,
	.ysa-vorn-media.wp-block-cover,
	.ysa-cta-script {
		animation: none;
		opacity: 1;
		translate: none;
		clip-path: none;
	}
}

/* Galerie: Zoom bedeutet auf dieser Seite "klickbar" (wie bei den Ensemble-Karten).
 * Team- und Partner-Fotos zoomen bewusst nicht, sie sind nicht verlinkt. */
.ysa-rueckblick-gallery > .wp-block-image {
	overflow: hidden;
}

.ysa-rueckblick-gallery > .wp-block-image img {
	transition: transform 500ms var(--ysa-ease-out);
}

@media (hover: hover) and (pointer: fine) {
	.ysa-rueckblick-gallery > .wp-block-image:hover img {
		transform: scale(1.03);
	}
}

@media (prefers-reduced-motion: reduce) {
	.ysa-rueckblick-gallery > .wp-block-image img {
		transition: none;
	}

	.ysa-rueckblick-gallery > .wp-block-image:hover img {
		transform: none;
	}
}

/*
 * Touch kennt kein Hover, die Farbe käme nie: Fotos bleiben dort fast in Farbe
 * (30 % Entsättigung gleicht unterschiedliche Fotoqualität weiter etwas aus).
 * Für volle Farbe auf 0 setzen. Gilt für Partner- und Team-Fotos.
 */
@media (hover: none) {
	.ysa-pcol-photo.wp-block-image img,
	.ysa-tcard-photo.wp-block-image img {
		filter: grayscale(.3) contrast(1.04);
	}
}

/*
 * Bildnachweis „© Name“ (inc/copyright.php): klein und dezent rechts unten im
 * Bild, ausgerichtet am nächsten positionierten Elternelement. Die halbtransparente
 * Hinterlegung hält die Schrift auf hellen wie dunklen Fotos und Logos lesbar.
 */
.ysa-tcard-photo.wp-block-image,
.ysa-pcol-photo.wp-block-image,
.ysa-rueckblick-gallery .wp-block-image {
	position: relative;
}

.ysa-copyright {
	position: absolute;
	right: 0;
	bottom: 0;
	z-index: 3;
	max-width: 100%;
	padding: 2px 7px;
	overflow: hidden;
	font-family: var(--ysa-font-body, inherit);
	font-size: 10px;
	font-weight: 400;
	line-height: 1.4;
	letter-spacing: .02em;
	white-space: nowrap;
	text-overflow: ellipsis;
	text-transform: none;
	color: rgb(255 255 255 / .85);
	background: color-mix(in srgb, var(--ysa-ink-900) 70%, transparent);
	pointer-events: none;
	-webkit-user-select: none;
	   -moz-user-select: none;
	        user-select: none;
}

@media print {
	.ysa-copyright {
		color: #000;
		background: none;
	}
}

/* Borlabs-Content-Blocker (YouTube): Button-Rot #ff0000 + weiße Schrift hat nur
   Kontrast 3,99:1 (WCAG AA verlangt 4,5:1). Markenrot erreicht > 5:1. */
body div.brlbs-cmpnt-container.brlbs-cmpnt-content-blocker .brlbs-cmpnt-cb-youtube .brlbs-cmpnt-cb-btn {
	background: #c8242a !important;
	color: #fff !important;
}

body div.brlbs-cmpnt-container.brlbs-cmpnt-content-blocker .brlbs-cmpnt-cb-youtube .brlbs-cmpnt-cb-btn:hover {
	background: #fff !important;
	color: #c8242a !important;
}
