/*
Theme Name: Klima vor acht
Theme URI: https://klimavoracht.de/
Author: Klima vor acht
Description: A lean block theme for KLIMAvoracht.
Requires at least: 6.7
Requires PHP: 8.1
Version: 0.2.161
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Tags: full-site-editing, accessibility-ready, block-patterns
*/

:root {
	--kv-border: rgba(5, 43, 142, 0.16);
	/*
	 * Root gutter. Must stay in sync with theme.json
	 * `styles.spacing.padding` (left/right): WordPress applies that value
	 * as padding on the body element, which insets the whole site shell.
	 * The full-width bars (header, footer, breaking news) and the section
	 * breakouts re-expand through this gutter by the full-bleed breakout
	 * (`margin-inline: calc(50% - 50vw)` + `width: 100vw`), which reaches
	 * the exact window edges at every viewport width (html/body
	 * overflow-x: clip is the safety net against a horizontal scrollbar).
	 */
	--kv-root-gutter: clamp(1rem, 3vw, 3rem);
}

/*
 * Global horizontal-overflow guard: full-width elements (the hero, the
 * breaking-news bar, the section breakouts) must never create a horizontal
 * scrollbar. `clip` on both the root and body also keeps Chromium from
 * counting the (clipped) marquee track overflow in document.scrollWidth.
 */
html,
body {
	/* Named-Anker (z. B. #faq) landen unter dem sticky Site-Header (152px)
	 * statt dahinter versteckt: scroll-padding-top räumt den Header-Höhe +
	 * 24px Ausgleich (gleich dem etablierten --kv-presse-sticky-offset). */
	overflow-x: clip;
	scroll-padding-top: 176px;
	/* Ankerlinks (Intro-Sprünge auf /presse/, #faq usw.) gleiten statt zu
	 * springen; unter prefers-reduced-motion erzwingt die globale
	 * reduce-Regel unten wieder den instant jump. */
	scroll-behavior: smooth;
}

body {
	background: var(--wp--preset--color--paper);
}

/*
 * Textlinks (KERN-UX-Konvention): Interaktions-Links mit Textinhalt tragen
 * eine permanente Unterstreichung statt der dünnen Browser-Standardlinie.
 * Im Ruhezustand 0.0625rem (1px) Dicke und Offset 0.1em; bei Hover/Fokus
 * wird nur die Linie dicker (3px). Farbe und Fokus-Ring übernimmt weiterhin
 * der Kontext. Komponenten, die keine Textlinks sind (Kartentitel, Buttons,
 * Navigation, Icon-Links, Bilder), nehmen sich die Unterstreichung weiterhin
 * selbst über text-decoration: none. */
a {
	text-decoration: underline;
	text-decoration-thickness: 0.0625rem;
	text-underline-offset: 0.1em;
}

a:hover,
a:focus-visible {
	text-decoration-thickness: 3px;
}

/* Bild-Links (z. B. post-featured-image in den Archiven): keine
 * Unterstreichung, das Bild selbst ist die Affordanz. */
a:has(> img) {
	text-decoration: none;
}

:where(a, button, input, textarea, select):focus-visible {
	outline: 3px solid var(--wp--preset--color--signal);
	outline-offset: 4px;
}
/* Core injects the skip link (`a.skip-link.screen-reader-text`) as the
 * first tab stop on every page. Core's own `:focus` rule un-clips it, but
 * with the default browser-ish grey; restyle it in brand colors so the
 * keyboard affordance ("Zum Inhalt springen") is clearly visible on focus.
 * The un-clipping itself stays core's job (`.skip-link:focus`). */
	.skip-link.screen-reader-text:focus-visible,
	.skip-link.screen-reader-text:focus {
		background: var(--wp--preset--color--ink);
		color: var(--wp--preset--color--paper-25);
		text-decoration: none;
		padding: 1.125rem 1.5rem 1.125rem 2rem;
		border-radius: 0 0 0.75rem 0.75rem;
		outline: 3px solid var(--wp--preset--color--signal);
		outline-offset: 3px;
	}

.wp-site-blocks {
	box-sizing: border-box;
	max-width: 1440px;
	margin: 0 auto;
	min-height: 100vh;
	width: 100%;
}

/* Keep any full-width block inside the 1440px shell from escaping it. */
.wp-site-blocks > .alignfull,
.wp-site-blocks .alignfull {
	max-width: 100%;
}

/*
 * No vertical margins between the top-level page sections. Core layout emits
 * `:where(.wp-site-blocks) > * { margin-block-start: 1.25rem }` (blockGap);
 * zero the margins of the direct children of the site shell only, so the gap
 * between items inside a section (paragraphs, headings) stays untouched.
 */
.wp-site-blocks > * {
	margin-block-end: 0;
	margin-block-start: 0;
}

/*
 * Front-page sections: the home sections are direct children of the main
 * landmark (plain `wp:group`), so core's `> * + *` blockGap rule (theme.json
 * `styles.spacing.blockGap` = 1.25rem) adds a 20px margin between the
 * full-width sections. Zero the gap at the section level only: the section
 * backgrounds butt flush against each other, while the spacing between
 * headings/paragraphs *inside* a section keeps the flow gap. The selectors
 * also cover pages whose post-content still embeds these section classes.
 * Aufgeräumt 17.08.08: die Legacy-Selektoren `main > .kv-home-section` /
 * `.kv-home-cta` und `.wp-block-post-content > .kv-home-section` /
 * `.kv-home-cta` sind entfernt (Seite 63 "Home" mit den alt-ClassName gelöscht,
 * nirgends mehr gerendert); die `.kv-hero`-Teile der Regel bleiben aktiv.
 */
main > .kv-hero,
main > .kv-section,
.wp-block-post-content > .kv-hero,
.wp-block-post-content > .kv-section {
	margin-block-start: 0;
}

/*
 * Header and footer are direct children of the site shell. The shell itself
 * is centered in the viewport (max-width 1440px, margin auto) and sits
 * inside the body's root gutter (theme.json styles.spacing.padding). This
 * is the same full-bleed breakout as .kv-section (und vor der 17.08.08-
 * Aufräumaktion auch .kv-home-section):
 * `width: 100vw` widens the bar to the exact window edges, and
 * `margin-inline: calc(50% - 50vw)` re-centers it on the containing block
 * (the centered 1440px shell / main landmark), so the background reaches
 * the window edges at every viewport width. Because the containing block
 * is itself centered, half its width minus half the viewport is exactly
 * the shell's left offset, cancelling it out edge to edge. Previously a
 * gutter-constant breakout was used (`margin-inline: calc(var(--kv-root-gutter)
 * * -1)`, `width: calc(100% + 2 * var(--kv-root-gutter))`); it broke the
 * centering at >1440px: the width was capped at 1440px but the negative
 * left margin was not compensated on the right, shifting header/footer
 * 48px (the 3rem gutter cap) off-centre at 1920px.
 */
.kv-site-header,
.kv-site-footer {
	box-sizing: border-box;
	margin-inline: calc(50% - 50vw);
	max-width: none;
	width: 100vw;
}

/* Sticky-Anker: Der `position: sticky`-Anker liegt NICHT auf dem Header
 * selbst, sondern auf dessen `div.wp-block-template-part`-Wrapper. Grund:
 * der Header ist das einzige Kind seines Template-Part-Wrappers, dessen Höhe
 * exakt der Header-Höhe entspricht (152px). `position: sticky` kann sich nur
 * innerhalb seines Containing Blocks (des Parent) bewegen – wäre der Anker
 * auf dem Header, hätte er keinen Sticky-Raum und würde normal mitscrollen.
 * Auf dem Wrapper (Parent 254: `.wp-site-blocks`, volle Seitenhöhe) bleibt
 * ausreichend Raum, um den Header am Viewport-Oberrand zu verankern. Der
 * Header selbst trägt nur noch das Ein-/Ausblenden per `transform`, damit
 * die `.kv-site-header--hidden`-Klasse (JS) ihn sauber vertikal heraus-
 * schiebt. `position: relative` hält den Header als Containing Block für den
 * absolut positionierten `::after`-Divider (Trennlinie unten). */
.wp-block-template-part:has(.kv-site-header) {
	position: sticky;
	top: var(--wp-admin--admin-bar--height, 0);
	z-index: 1000;
}

.kv-site-header {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
	/* translateY(0) ist der Ruhezustand; die JS toggelt
	 * .kv-site-header--hidden, um die ganze Bar per transform über den
	 * oberen Viewport-Rand zu schieben (reduce-motion global entschärft). */
	position: relative;
	transform: translateY(0);
	transition: transform 0.3s ease;
	will-change: transform;
}

/* Trennlinie unter dem Header (2px, siehe Auftraggeber): bewusst NICHT
 * voll-bleed — die Linie ist auf die 1136px-Inhaltsbreite gedeckelt und
 * zentriert, während die ink-Fläche des Headers weiterhin 100vw voll-bleed
 * bleibt. Die Linie liegt als ::after-Pseudo absolut am Header-Unterrand
 * (position: relative am Header erzeugt den Containing Block). Unterhalb
 * von 1136px Viewport ist
 * min(100vw, 1136px) = 100vw, die Linie spannt also schmal weiterhin die
 * volle Header-Breite; ab 1136px deckelt sie bei 1136px mittig. */
.kv-site-header::after {
	background: rgba(252, 248, 236, 0.22);
	bottom: 0;
	content: "";
	height: 2px;
	left: 50%;
	pointer-events: none;
	position: absolute;
	transform: translateX(-50%);
	width: min(100vw, 1136px);
}

/* Hidden state: slides the entire header up past the top viewport edge.
 * The global @media (prefers-reduced-motion: reduce) rule sets
 * transition-duration to 0.01ms, covering transform, so reduced-motion
 * users get no slide animation. */
.kv-site-header.kv-site-header--hidden {
	transform: translateY(calc(-100%));
}

/* Mobile-Overlay der Core-Navigation (<920px): Das Modal ist `position:
 * fixed` und muss am Viewport hängen. `transform` (auch der Identitäts-
 * wert translateY(0)) und `will-change: transform` auf dem Header machen
 * ihn aber zum Containing Block für fixed positionierte Nachfahren; das
 * Vollbild-Modal wird dadurch auf die Header-Box (~160px) gestaucht und
 * der Rest des Menüs liegt hinter dem Seiteninhalt. Solange das Modal
 * geöffnet ist (`html.has-modal-open`, setzt Core aufs <html>-Element),
 * werden transform und will-change deshalb neutralisiert. Der Header
 * steckt in diesem Zustand ohnehin per JS im sichtbaren Zustand
 * (translateY(0) ist identisch zu none), die Slide-Animation beim
 * Schließen bleibt unberührt. */
html.has-modal-open .kv-site-header {
	transform: none;
	will-change: auto;
}

.kv-site-header.has-ink-background-color {
	background-color: var(--wp--preset--color--ink) !important;
}

/*
 * The 1136px shell that holds both header rows. It used to be a flex row
 * itself; since the navbar V1 layout it is a plain column container.
 */
.kv-header-top {
	box-sizing: border-box;
	margin: 0 auto;
	max-width: 1136px !important;
	/* Kept as containing block for any positioned header internals; the
	 * 1136px shell itself is a plain column with the two stacked rows. */
	position: relative;
	/* Top padding plus breathing room below the second header row (nav +
	 * donate button). The clamp inline padding keeps the logo and nav clear
	 * of the shell edges on every viewport; only the inline-axis padding is
	 * overridden below, top/bottom paddings are untouched. The space lives
	 * inside the dark-ink header block, so the section margins between the
	 * site sections stay 0 (see the .wp-site-blocks > * rule above). */
	padding: clamp(0.625rem, 1.6vw, 1.125rem) 0 clamp(1.25rem, 2vw, 1.5rem);
	padding-inline: 1rem;
	width: 100%;
}

/* Row 2: brand lockup, primary navigation and donate button. The row itself
 * is not justified (items stack left); the navigation's auto left margin
 * (rule below) absorbs the free space so nav + donate run flush right after
 * the logo. Children and nav items align to the top. */
.kv-header-nav {
	align-items: flex-start;
	box-sizing: border-box;
	gap: clamp(1rem, 2vw, 1.5rem);
	margin-top: clamp(0.375rem, 1vw, 0.625rem);
	min-height: 56px;
	padding: 0;
	width: 100%;
}

/*
 * Row 2 uses the flex auto-margin mechanism instead of a justify-content
 * split: the navigation's auto left margin absorbs every pixel of free
 * space between the logo and the nav, so the nav *and* the donate button
 * that follows it run flush right while the row itself stays left-aligned.
 * The core flex reset `.is-layout-flex > :is(*, div)` forces margin: 0 on
 * raw flex children, so the selector needs the extra class to win the
 * cascade (same pattern as the tools rule in row 1).
 */
.kv-header-nav .wp-block-navigation {
	margin-left: auto;
}

/*
 * The brand lockup (kv8-logo.svg, inlined in parts/header.html because
 * template parts are pure block markup without PHP) renders at 250px per
 * navbar V1. The intrinsic 768.47 × 97.7 viewBox gives a ~32px logo height.
 * Since the 08.08. correction the lockup lives in the second header row
 * (.kv-header-nav, the row that also holds the primary navigation and the
 * donate button), so the shell's own flow places it at the row start and
 * the navigation's auto left margin pushes nav + donate flush right.
 * From 920px up the lockup is lifted with a -12px top margin so its top
 * edge optically reaches for the row above; below 920px it keeps its plain
 * in-flow placement, because a negative margin there would pull the brand
 * against the full-width mobile search row. */
.kv-site-header .kv-header-logo {
	display: inline-flex;
	line-height: 0;
	text-decoration: none;
}

.kv-site-header .kv-header-logo svg {
	display: block;
	height: auto;
	width: 250px;
}

@media (min-width: 920px) {
	/* User correction (08.08.): with the lockup relocated to the second
	 * header row, the old -46px lift (which had reached for the header's
	 * top edge from row 1) is replaced by a -12px lift, enough to let the
	 * logo optically touch the row above without eating into the search
	 * row. position: relative is kept as the harmless anchor for any
	 * positioned header internals. The 920px cutoff keeps the negative
	 * margin away from the mobile layout, where the brand must stay in
	 * flow (see the comment above). */
	.kv-site-header .kv-header-logo {
		margin-top: -12px;
		position: relative;
	}

	/*
	 * Row 1 (bar): content flush right and 0.4rem breathing room below the
	 * search + language row. Since the logo moved out of the bar, the tools
	 * group is the bar's only flex child; the core flex layout emits the
	 * `space-between` justification both via the
	 * `is-content-justification-space-between` class and via the generated
	 * `.wp-container-core-group-is-layout-…` rule, and the two-class
	 * selector outbids both (0,2,0 vs 0,1,0) regardless of stylesheet
	 * order. Scoped to ≥920px on purpose: below 920px the `.kv-header-bar
	 * .kv-header-tools { margin-left: auto }` rule below already anchors
	 * the tools flush right, and the extra bottom padding would shift the
	 * nav row (verified mobile/tablet layout would regress).
	 */
	.kv-header-bar.is-content-justification-space-between {
		justify-content: end;
	}

	.kv-header-bar {
		padding-bottom: 0.4rem;
	}
}

.kv-site-header .wp-block-navigation-item__content {
	color: var(--wp--preset--color--paper);
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem); /* 15–17px, fluid (Fluid-Typo) */
	font-weight: 600;
	text-decoration: none;
}

/* Korrektur 10.08. (Desktop): Das Spenden-Label des Header-Buttons darf im
 * .kv-header-nav (1136px-Zeile aus Logo, Navigation und Button) nicht in
 * einzelne Zeilen brechen; das white-space: nowrap hält "Spenden" immer
 * auf einer Zeile. */
.kv-site-header .kv-header-nav .wp-block-button__link {
	white-space: nowrap;
}

/* Hover/Fokus der Top-Level-Nav-Links auf der ink/paper-Fläche: Der
 * nicht-farbabhängige Hover-Indikator ist die Unterstreichung (Regel unten);
 * zusätzlich wechselt der Background auf dunkelblau-75 #3F62AD (paper-Text
 * bleibt unverändert und erreicht dort ≈ 4,9:1 AA). Bewusst KEIN
 * Textfarbwechsel mehr. #3F62AD ist als "Dunkelblau 75" in theme.json
 * registriert (Figma-Design-System) und wird hier über die CSS-Variable
 * verwendet. Bewusst über den Kind-Selektor (`__container > item > __content`)
 * nur auf die oberste Ebene gescoped — Megapanel-Einträge bleiben unberührt. */
.kv-site-header .wp-block-navigation__container > .wp-block-navigation-item
	> .wp-block-navigation-item__content:hover,
.kv-site-header .wp-block-navigation__container > .wp-block-navigation-item
	> .wp-block-navigation-item__content:focus-visible {
	background: var(--wp--preset--color--dunkelblau-75);
}

/* Hover-/Fokus-Farbe allein genügt laut WCAG nicht. Top-Level-Items der
 * Header-Navigation bekommen deshalb zusätzlich eine sichtbare Unterstreichung
 * in currentColor (signal). Bewusst über den Kind-Selektor (`__container >
 * .wp-block-navigation-item > __content`) auf die oberste Ebene gescoped:
 * Die bereits unterstrichenen Mega-Panel-Einträge (`.kv-mega-nav …`) und die
 * Dropdown-Untermenü-Einträge bleiben hierdurch vollständig unberührt. */
.kv-site-header .wp-block-navigation__container > .wp-block-navigation-item
	> .wp-block-navigation-item__content:hover,
.kv-site-header .wp-block-navigation__container > .wp-block-navigation-item
	> .wp-block-navigation-item__content:focus-visible {
	text-decoration: underline;
	text-underline-offset: 0.25em;
	text-decoration-thickness: 2px;
}

.kv-header-tools {
	align-items: center;
	gap: clamp(0.75rem, 1.6vw, 1.25rem);
}

/* Keeps the search + language group flush right inside the bar. The core
 * flex reset `.is-layout-flex > :is(*, div)` forces margin: 0 on raw flex
 * children, so the selector needs the extra class to win the cascade. */
.kv-header-bar .kv-header-tools {
	margin-left: auto;
}

.kv-site-header .wp-block-search__inside-wrapper {
	border: 1px solid var(--wp--preset--color--paper);
	background: var(--wp--preset--color--paper);
	border-radius: 4px;
	height: 38px;
	padding: 0;
	width: 220px !important;
}

.kv-site-header .wp-block-search__input {
	background: var(--wp--preset--color--paper);
	border: 0;
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	font-size: 0.8rem;
	height: 36px;
	min-width: 0;
	padding: 0 0.6rem;
	width: 100%;
}

.kv-site-header .wp-block-search__button {
	background: var(--wp--preset--color--paper);
	border: 0;
	border-left: 1px solid rgba(5, 43, 142, 0.2);
	border-radius: 0 3px 3px 0;
	height: 36px;
	color: var(--wp--preset--color--ink);
	margin: 0;
	padding: 0;
	width: 34px;
}

/* Core CSS ships `.wp-block-search__input:focus { outline: none }` with
 * higher specificity than the theme-wide :focus-visible outline, which
 * leaves the search input without any focus ring. Re-assert the ring for
 * the keyboard-only state, scoped per header variant. */
.kv-site-header .wp-block-search__input:focus-visible {
	outline: 3px solid var(--wp--preset--color--signal);
	outline-offset: 4px;
}

.kv-header-inverted .kv-site-header .wp-block-search__input:focus-visible {
	outline-color: var(--wp--preset--color--ink);
}

/*
 * ---------------------------------------------------------------------------
 * Hero — front page
 * ---------------------------------------------------------------------------
 * The hero section is image-dominated: the 2880×1439 source spans the full
 * 1440px section width at its natural ratio (719.5px tall at 1440px), so the
 * .kv-section paddings (120/152) used by the content sections do not apply
 * here. Per the 08.08. layout correction the ink text card is a 943px
 * overlay, anchored to the image's bottom edge so that it hangs 40px past
 * the lower border into whatever section follows (bottom: -40px).
 */

.kv-hero {
	box-sizing: border-box;
	/*
	 * The hero is the full-width section on the pattern-composed front page:
	 * a 100vw-wide full-bleed band at every viewport. `width: 100vw` reaches
	 * the exact window edges, and `margin-inline: calc(50% - 50vw)` re-centers
	 * it on the (centered) containing block — the site shell / main landmark —
	 * so the background never runs past the window at any width (html/body
	 * overflow-x: clip is the safety net against a horizontal scrollbar).
	 */
	margin-inline: calc(50% - 50vw);
	max-width: none;
	padding: 0;
	position: relative;
	width: 100vw;
}

.kv-hero .wp-block-image {
	margin: 0;
}

/*
 * Core applies an `is-layout-flow` block-gap margin to sibling blocks
 * (`> * + *`): the image would get a 20px margin that leaves a gap above
 * the hero, and a margin-top on the absolutely positioned overlay would
 * shift its non-auto `bottom` anchor. No flow spacing is wanted here.
 */
.kv-hero > * {
	margin-block-end: 0;
	margin-block-start: 0;
}

.kv-hero__image,
.kv-hero__image img {
	display: block;
	height: auto;
	max-width: 100%;
	width: 100%;
}

/*
 * The card's lower edge sits 40px + 4rem below the image (bottom:
 * calc(-40px - 4rem) — the 4rem nudge of 05.09. after the hero photo was
 * cropped top/bottom), so it overlaps whatever follows (breaking news / the
 * home sections). It gets
 * z-index: 2: in the root stacking context positive-z positioned boxes paint
 * above the following in-flow sections, whose backgrounds must therefore
 * never cover the overhang. Keep following sections un-positioned / auto
 * stacked (default) so this stays true.
 */
.kv-hero__overlay {
	background-color: var(--wp--preset--color--ink);
	border-radius: 24px;
	bottom: calc(-40px - 4rem);
	box-sizing: border-box;
	color: var(--wp--preset--color--paper-25);
	left: 50%;
	max-width: calc(100vw - 2rem);
	padding: 40px;
	position: absolute;
	text-align: center;
	transform: translateX(-50%);
	width: 943px;
	z-index: 2;
}

/* 05.09.: after the hero photo was cropped and the ink card moved down by
 * 4rem (bottom: calc(-40px - 4rem)), its overhang eats into the following
 * section. The "Unser Ansatz" opening gets the same 4rem of top margin so
 * the heading keeps its clearance below the card. Desktop-only: at ≤782px
 * the card is in-flow (see the mobile hero rule) and never overlaps the
 * next section, so it needs no compensation. */
@media (min-width: 783px) {
	.kv-hero + .kv-approach {
		margin-block-start: 4rem;
	}
}

/* Korrektur 08.08.: centre the hero card content. The overlay text (h1,
 * both paragraphs, the button label — all inline content) inherits the
 * `text-align: center` above; the buttons wrapper is a block-level flex
 * container, so its items are centred with `justify-content` instead of
 * text alignment. Box geometry (943px, bottom -40px, radius 24, padding
 * 40) is untouched. */
.kv-hero__overlay .wp-block-buttons {
	justify-content: center;
}

/*
 * Hero CTA: warm-white primary button on the ink overlay card.
 * Figma "Color Themes" runs btn-primary on the dunkelblau (ink) surface as a
 * light button (paper / paper-25 variants with ink text); the header ghost and
 * footer buttons keep their own measures, so this stays scoped to the hero.
 * Figma btn-primary: radius 8px, padding 16px/12px -> here 1rem/0.75rem.
 * The theme-wide signal focus outline sits on the ink overlay, where it is
 * clearly visible; hover/focus wechseln global auf #FFF-Fill mit ink-Text.
 */
.kv-hero__overlay .wp-block-button.is-style-hero-primary .wp-block-button__link {
	background: var(--wp--preset--color--paper);
	border-radius: 8px;
	color: var(--wp--preset--color--ink);
	padding: 0.75rem 1rem;
}

.kv-hero__overlay .wp-block-button.is-style-hero-primary .wp-block-button__link:hover,
.kv-hero__overlay .wp-block-button.is-style-hero-primary .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

/*
 * p-large – Intro-Absätze mit der `large`-Preset-Größe (12.08. "Global B"):
 * seit 17.08. fluid über clamp(1.125rem, 2.1vw, 1.5rem), also 18–24px;
 * die exakten 24px von früher sind ab ~1143px Viewport wieder erreicht.
 * Die Zeilenhöhe bleibt 1.417 (Figma-Paar "24/34"). Die Core-Klasse
 * .has-large-font-size würde sonst per !important den größeren Clamp des
 * Presets durchsetzen (22–34px); deshalb trägt die Größe hier selbst
 * !important, unter den !important-Deklarationen gewinnt der
 * spezifischere p.-Selektor (0,1,1 gegen 0,1,0). Der `p.`-Präfix hält die
 * Regel strikt auf Absätze beschränkt: Headings (h1–h6
 * .has-large-font-size, eigene Heading-Zeilenhöhe) und die
 * Blog-Kartentitel (.kv-aktuelles__card-title, div mit line-height 1.15)
 * bleiben bei ihrem responsive skalierenden Preset unberührt.
 */
p.has-large-font-size {
	font-size: clamp(1.125rem, 2.1vw, 1.5rem) !important;
	line-height: 1.417;
}

/*
 * p-medium – Fließabsätze mit dem Medium-Format (14.08. "17/24",
 * Zeilenhöhe 1.412; 24/17 = 1.412): seit 17.08. fluid über
 * clamp(0.9375rem, 1.5vw, 1.0625rem), also 15–17px; ab ~1136px Viewport
 * sind die früheren festen 17px wieder exakt erreicht. Der Fallback ist
 * exakt derselbe Clamp wie das Medium-Format des übrigen Stylesheets und
 * damit mit der Utility-Klasse wirkungsgleich (idempotent). Weil das
 * theme.json-Preset flacher skaliert (1.3vw, 17px erst ab ~1308px), trägt
 * die Regel trotzdem !important: unter den !important-Deklarationen
 * gewinnt der spezifischere p.-Selektor (0,1,1 gegen 0,1,0) und der
 * Absatz rendert zuverlässig den 15–17px-Range. Der `p.`-Präfix
 * beschränkt die Regel auf Absätze: das h3 in `presse-kontakt` (ebenfalls
 * has-medium-font-size) behält Preset-Schriftgröße und
 * Heading-Zeilenhöhe 1.05.
 */
p.has-medium-font-size {
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem) !important;
	line-height: 1.412;
}

/* Aufgeräumt 17.08.08: das Legacy-Karten-Raster `.kv-home-cards` (Baustein
 * der alten, gelöschten Home-Sektionen, Seite 63) ist entfernt — im
 * Frontend wird keine `.kv-home-cards`-Instanz mehr gerendert. Der
 * generische `.kv-card-*`-Block darunter bleibt unverändert bestehen. */
.kv-card-grid {gap: clamp(1rem, 2.5vw, 2rem);
	align-items: stretch;
	grid-auto-rows: 1fr;
}

.kv-card-grid > .kv-card {
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	align-self: stretch;
	height: auto;
	min-height: 100%;
}

.kv-card > .wp-block-buttons {
	margin-top: auto;
}

.kv-card--outlined {
	border: 1px solid var(--wp--preset--color--mist);
}

/*
 * Aufgeräumt 17.08.08: der komplette Legacy-Block `kv-home-section` /
 * `kv-home-cta` / `kv-home-section--leaf|dark|blue` ist entfernt. Er wurde
 * für die alten DB-Dummy-Sektionen gebaut (Seite 63 "Home", mit ihr gelöscht);
 * die Startseite (27) nutzt seit dem Umbau `.kv-section` + die Kontext-Klassen
 * `.kv-approach`/`.kv-wirkung`/`.kv-angebote`/`.kv-aktuelles`/`.kv-darum` —
 * kein Frontend-DOM und keine DB rendert mehr eine
 * `.kv-home-*`-Klasse. Mitentfernt: die verschachtelten `kv-card`-Regeln
 * (`.kv-home-section--blue .kv-card*` und die beiden
 * `.has-ink-background-color .kv-card`-Regeln) — `.kv-card` wird in keinem
 * Pattern/Template und in keiner gerenderten Seite mehr benutzt (verifiziert
 * über alle Seiten-DOMs am 17.08.08), die Regeln waren damit ebenfalls tot.
 */

/* Footer — Figma "footer Default". Dark ink shell capped at 1440px by the
 * shared rule above; the alignwide children carry the 1136px content width. */
.kv-site-footer {
	background: var(--wp--preset--color--ink);
	border-top: 1px solid var(--kv-border);
	color: var(--wp--preset--color--paper);
}

.kv-footer-main {
	align-items: flex-start;
	padding-bottom: 3rem;
	padding-top: 4.5rem;
}

.kv-footer-newsletter h2 {
	color: var(--wp--preset--color--paper);
	font-size: clamp(1.15rem, 2vw, 1.45rem);
	line-height: 1.2;
	margin: 0 0 1rem;
}

.kv-newsletter-form {
	display: flex;
	max-width: 28rem;
}

/* 17.08. iOS-Zoomschutz: Die Inputs bleiben bei gesetzter font-size nie
 * unter 1rem (16px), iOS zoomt sonst beim Fokussieren auf < 16px-Schrift
 * automatisch herein. Die Clamp (16–18px) muss NACH dem font:-Shorthand
 * stehen, sonst setzt das Shorthand sie zurück. Basisklasse, wirkt über die
 * gemeinsame Klasse auch auf das Seiten-Formular (.kv-newsletter-page-form). */
.kv-newsletter-form input {
	background: var(--wp--preset--color--ink);
	border: 1px solid var(--wp--preset--color--paper);
	border-radius: 6px 0 0 6px;
	box-sizing: border-box;
	color: var(--wp--preset--color--paper);
	font: inherit;
	font-size: clamp(1rem, 1.6vw, 1.125rem);
	min-height: 2.75rem;
	padding: 0.35rem 0.75rem;
	width: 100%;
}

.kv-newsletter-form input::placeholder {
	color: rgba(252, 248, 236, 0.5);
}

.kv-newsletter-form button {
	align-items: center;
	background: var(--wp--preset--color--paper);
	border: 1px solid var(--wp--preset--color--paper);
	border-radius: 0 6px 6px 0;
	color: var(--wp--preset--color--ink);
	cursor: pointer;
	display: inline-flex;
	font-weight: 600;
	gap: 0.5rem;
	letter-spacing: 0.02em;
	padding: 0 1.1rem;
	white-space: nowrap;
}

/* Newsletter-Button-Label: feste 17px laut User-Vorgabe (17.08.) –
 * bewusste Ausnahme von der Fluid-Konvention, analog p-medium. */
.kv-newsletter-form .kv-newsletter-button-label {
	font-size: 17px;
}

.kv-newsletter-form button svg {
	flex-shrink: 0;
}

/* 12.08. Hover-Korrektur: der Button verhält sich als Variante
 * primary-paper (die Systemregel gilt nicht für das native <button>
 * der Form, daher die eigene Regel): Ruhe paper/ink (11.35:1 AAA),
 * Hover/Focus wechselt auf reinen weißen Fill #FFF mit ink-Text
 * (12.08. User-Spec, wie die übrige weiße Button-Familie);
 * Ruhe bleibt paper/ink (11.35:1 AAA), Hover ink auf #FFF 19.9:1 AAA
 * (Geometrie/Fusion mit dem Eingabefeld bleibt). 28.08.: Regel wieder-
 * hergestellt — sie war am 24.08. (8c36f0e, Newsletter-Umbau) beim
 * Einfuegen des Honeypot-Kommentars herausgefallen, der Kommentar stand
 * seither ohne Regel da.) */
.kv-newsletter-form button:hover,
.kv-newsletter-form button:focus-visible {
	background: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

/* Honeypot (Spamschutz, inc/newsletter.php): für Menschen unsichtbar, für
 * Bots ein Lockmittel – füllt ein Bot das Feld aus, verwirft der Server
 * die Anmeldung still. Absolute Position, keine display:none (auch das
 * wäre ein Hinweis für Bots). */
.kv-newsletter-hp {
	left: -9999px;
	position: absolute;
}

/* Status-Meldung nach der Anmeldung (REST-Antwort, role="status").
 * Basis (Seiten-Formular auf paper): ink-Text; der Footer (ink-Hintergrund)
 * überschreibt weiter unten auf paper. */
.kv-newsletter-status {
	color: var(--wp--preset--color--ink);
	font-size: 0.875rem;
	line-height: 1.45;
	margin: 0.75rem 0 0;
	max-width: 28rem;
	padding: 0.5rem 0.75rem;
}

.kv-newsletter-status:focus {
	outline: 2px solid var(--wp--preset--color--signal);
	outline-offset: 2px;
}

.kv-newsletter-status--error {
	background: var(--wp--preset--color--signal);
	border-radius: 6px;
	color: var(--wp--preset--color--ink);
}

.kv-site-footer .kv-newsletter-status {
	color: var(--wp--preset--color--paper);
}

/* Während der Anfrage: Button als "beschäftigt" markiert; nach erfolgreicher
 * Anmeldung (DOT abgeschickt) verschwindet das Formular, die
 * Status-Meldung bleibt sichtbar. */
.kv-newsletter-form.is-pending button {
	cursor: wait;
	opacity: 0.7;
}

.kv-newsletter-form.is-done {
	display: none;
}

/* Bestätigungs-Banner auf der Newsletter-Seite (?status=confirmed) nach dem
 * Klick auf den Double-Opt-in-Link (inc/newsletter.php).
 * Erfolgsfläche im Türkis-Branding (leaf, wie kv-post-cta--tuerkis und der
 * kv-header-tuerkis-Hintergrund): signal (gelborange) wirkt warnend und
 * bleibt den Fehler-/Hinweis-Flächen vorbehalten. ink auf leaf = 6.91:1 AA. */
.kv-newsletter-confirmed {
	background: var(--wp--preset--color--leaf);
	border-radius: 6px;
	color: var(--wp--preset--color--ink);
	margin-bottom: 1.5rem;
	padding: 0.75rem 1rem;
}
/* Newsletter-Archiv: Abstand zur Intro-Zeile der Seite ("…Hier kannst du
 * frühere Ausgaben nachlesen.") – 2rem statt der Default-Distanz (User-
 * Vorgabe 23.08: mind. 1rem, besser 2). Greift auf der /newsletter/-Seite,
 * wo Archiv-Liste bzw. Leer-Zustand nach dem letzten Inhaltsblock stehen. */
.kv-presse-list.kv-newsletter-archive,
.kv-newsletter-archive-empty {
	margin-top: 2rem;
}

/* Newsletter-Archiv (nach Titel-über-Datum-Tausch 05.09.): Der geteilte
 * kv-presse-entry__title trägt margin-block-end: 12px für den Abstand zur
 * Aktionszeile der Presse-Liste; hier sitzt stattdessen die Datumszeile
 * direkt unter dem Titel. Auf 0.25rem (4 px) verengt – dieselbe enge
 * Datum↔Titel-Paarung, die auf der Presse-Seite gilt (Datum-MB 4px). */
.kv-newsletter-archive .kv-presse-entry__title {
	margin-block-end: 0.25rem;
}

/* Newsletter-Archiv: Abstand zwischen den Einträgen. Der geteilte
 * kv-presse-entry trägt margin-bottom: 2.5rem für die Presse-Listen mit
 * Aktionszeile; das Archiv hat nur Titel + Datum und wirkt damit zu
 * luftig. Auf 1rem verengt (User-Vorgabe 05.09.; Hairline-Trenner je
 * Eintrag bleibt). */
.kv-newsletter-archive .kv-presse-entry {
	margin-bottom: 1rem;
}

.kv-footer-hint {
	line-height: 1.55;
	margin: 0.75rem 0 0;
	max-width: 28rem;
	opacity: 0.82;
}

.kv-footer-contact {
	align-items: flex-end;
	text-align: right;
}

.kv-footer-contact .wp-block-navigation-item__content {
	color: var(--wp--preset--color--paper);
	font-size: clamp(0.875rem, 1.5vw, 1rem);
	text-decoration: none;
}

.kv-footer-contact .wp-block-navigation-item__content:hover,
.kv-footer-contact .wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--signal);
}

/* Footer "Schreib uns!": ghost on the ink footer, alias on secondary-paper.
 * 12.08. globale Hover-Regel: Ruhe wie secondary-paper (transparent,
 * paper Border/Text auf ink, 11.35:1 AAA); Hover/Focus → #FFF-Fill mit
 * ink-Text (19.9:1 AAA), die #FFF-Border wird vom Fill überdeckt. Der
 * frühere paper-25-Fill-Hover ist ersetzt; Kompakt-Padding (3px) bleibt. */
.wp-block-button.is-style-footer-outline .wp-block-button__link {
	background: transparent;
	border: 1px solid var(--wp--preset--color--paper);
	color: var(--wp--preset--color--paper);
	padding: 0.5rem 1rem;
}

.wp-block-button.is-style-footer-outline .wp-block-button__link:hover,
.wp-block-button.is-style-footer-outline .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

.kv-footer-bottom {
	align-items: center;
	padding-bottom: 3.5rem;
}

/* Custom social icon row: monochrome 20px icons in paper-25. On the 1136px
 * bottom row the ul sits right of the copyright notice. */
.kv-footer-social {
	align-items: center;
	display: inline-flex;
	flex-wrap: wrap;
	gap: 1.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.kv-footer-social li {
	align-items: center;
	display: inline-flex;
	margin: 0;
	padding: 0;
}

.kv-footer-social .kv-footer-social-link {
	align-items: center;
	color: var(--wp--preset--color--paper-25);
	display: inline-flex;
	line-height: 0;
	text-decoration: none;
}

.kv-footer-social .kv-footer-social-link svg {
	display: block;
}

.kv-footer-social .kv-footer-social-link:hover,
.kv-footer-social .kv-footer-social-link:focus-visible {
	color: var(--wp--preset--color--signal);
}

/* dogado wordmark in the copyright line ("Powered by"): inlined SVG with
 * the yellow mark at brand #FEC600 and the wordmark paths in currentColor,
 * so they inherit paper on the ink footer and signal on hover/focus —
 * same treatment as the footer social icons. Display height is 18px;
 * width stays auto to keep the aspect ratio. margin-bottom 2px and
 * padding-left 4px nudge the mark slightly above the text baseline and
 * keep a small gap to the "Powered by" label. */
.kv-footer-dogado-link {
	align-items: center;
	display: inline-flex;
	text-decoration: none;
	vertical-align: middle;
}

.kv-footer-dogado-link .kv-footer-dogado-logo {
	display: block;
	height: 18px;
	width: auto;
	margin-bottom: 2px;
	padding-left: 4px;
}

.kv-footer-dogado-link:hover .kv-footer-dogado-logo,
.kv-footer-dogado-link:focus-visible .kv-footer-dogado-logo {
	opacity: 0.75;
}

/* Visible focus ring on the dark footer: same signal outline as the
 * theme-wide :focus-visible rule. */
.kv-footer-dogado-link:focus-visible {
	outline: 3px solid var(--wp--preset--color--signal);
	outline-offset: 4px;
}

.kv-site-footer a {
	color: var(--wp--preset--color--paper);
}

.kv-site-footer a:hover,
.kv-site-footer a:focus-visible {
	color: var(--wp--preset--color--signal);
}

.kv-site-footer .wp-block-heading {
	color: var(--wp--preset--color--paper);
}

/* Visually hidden label for the newsletter field (WCAG 1.3.1). */
.kv-site-footer .screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

@media (max-width: 782px) {
	.kv-header-top {
		flex-wrap: wrap !important;
	}

	.kv-card-grid {
		grid-template-columns: 1fr !important;
	}

	.kv-newsletter-form {
		max-width: none;
	}

	.kv-footer-newsletter {
		width: 100%;
	}

	.kv-footer-contact {
		align-items: flex-start;
		margin-top: 2rem;
		text-align: left;
	}

	.kv-footer-bottom {
		align-items: flex-start;
		flex-direction: column-reverse;
		gap: 1rem;
		padding-bottom: 0.5rem;
	}

	/* Mobile hero: the card leaves the anchored overlay and flows directly
	 * after the image with a negative top margin, so its top lip still
	 * overlaps the picture by 40px and the card runs on into the section
	 * below. `bottom: auto` cancels the desktop bottom anchor, which would
	 * otherwise shift the in-flow card by 40px. */
	.kv-hero__overlay {
		bottom: auto;
		left: auto;
		margin-inline: auto;
		margin-top: -2.5rem;
		position: relative;
		top: auto;
		transform: none;
		width: calc(100vw - 2rem);
		max-width: 943px;
	}

	/* Korrektur 10.08. (Schreibweise 08.09.): der Hashtag (#PrimetimeFuersKlima, 20 Zeichen)
	 * läuft im Huge-Clamp (min 2.5rem) auf schmalen Screens über zwei
	 * Zeilen und dominiert die Karte. Die mobile Obergrenze bleibt die
	 * Huge-Obergrenze (2.5rem), der Hashtag fällt auf kleinen Screens
	 * aber auf ~1.625rem zurück und passt ab ~360px auf eine Zeile. Der
	 * Selektorsuffix .has-huge-font-size hält die Korrektur gegen die
	 * Core-Klasse (0,3,0 vs 0,2,0). */
	.kv-hero__overlay .wp-block-heading.has-huge-font-size {
		font-size: clamp(1.625rem, 7vw, 2.5rem) !important;
	}
}

/*
 * Korrektur 10.08. (Footer, Auftraggeber): Zwischen 480 und 782px liegen die
 * drei Footer-Einträge (Impressum, Datenschutzerklärung, "Schreib uns!")
 * nebeneinander in einer Zeile statt als Linkliste linksbündig; darunter
 * (≤479px) kehrt die gestapelte, linksbündige Liste aus der 782px-Regel
 * zurück. Die Zeilen-Umschaltung gilt der `.kv-footer-contact`-Spalte und
 * ihrer Navigation: beide bekommen flex-direction: row, die Core-generierte
 * Vertikal-Layoutklasse (0,1,0) verliert gegen die Zwei-Klassen-Selektoren.
 * Bei 480px passen die drei Einträge (ca. 396px inkl. Lücken) in die
 * 448px-Inhaltsbreite.
 */
@media (min-width: 480px) and (max-width: 782px) {
	.kv-footer-contact {
		align-items: center;
		flex-direction: row;
		gap: 1.5rem;
		text-align: left;
	}

	.kv-footer-contact .wp-block-navigation {
		flex-direction: row;
		gap: 1.25rem;
	}
}

/*
 * Korrektur 10.08. (Footer-Newsletter, Auftraggeber): Ab 411px wird die
 * E-Mail-Zeile neben dem Button zu schmal (bei 360px nur noch ~134px).
 * Unterhalb von 410px — demselben Breakpoint, wo Copyright und Social-
 * Icons in zwei Zeilen übergehen — stapeln sich Eingabefeld und Button
 * auf zwei volle Zeilen (Input radius 6px allseitig, Button ebenso und
 * zentriert über die volle Breite).
 */
@media (max-width: 410px) {
	.kv-newsletter-form {
		align-items: stretch;
		flex-wrap: wrap;
		gap: 0.75rem;
	}

	.kv-newsletter-form input {
		border-radius: 6px;
	}

	.kv-newsletter-form button {
		align-content: center;
		align-items: center;
		border-radius: 6px;
		justify-content: center;
		min-height: 2.75rem;
		padding: 0.75rem 1.1rem;
		width: 100%;
	}
}

/*
 * Korrektur 10.08. (Footer, Auftraggeber): unter 480px ist die
 * `.kv-footer-contact`-Spalte linksbündig — der Seitenrand links (16px) und
 * die Einträge (Impressum, Datenschutzerklärung, "Schreib uns!") beginnen
 * auf derselben Kante. Die Core-Navigation gibt ihr Rechtfertigung per
 * items-justified-right vor; die Korrektur sitzt deshalb auf der Liste
 * (`.wp-block-navigation__container`), nicht auf dem Nav-Wrapper: sonst
 * wandert der erste Eintrag rechtsbündig gegen das Ende seiner Zelle (in der
 * Spalte 89px statt 16px linker Abstand).
 */
@media (max-width: 479px) {
	.kv-footer-contact {
		align-items: flex-start;
		text-align: left;
	}

	/* Die Core-Navigation steht als vertikales Flex (is-vertical) mit
	 * items-justified-right, also align-items: flex-end auf der Spalte:
	 * der erste Eintrag rückt gegen das rechte Ende seiner 148px-Zelle
	 * (89px statt 16px linker Abstand). Die Korrektur setzt beide Achsen
	 * auf flex-start, damit alle Einträge auf der 16px-Kante beginnen. */
	.kv-footer-contact .wp-block-navigation {
		align-items: flex-start;
	}
}

.kv-display {
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-weight: 700;
	letter-spacing: -0.025em;
}

.wp-block-navigation-item__content,
.wp-block-button__link {
	transition: background-color 160ms ease, color 160ms ease;
}

/*
 * ---------------------------------------------------------------------------
 * Button-System — 4 Farbvarianten × primary/secondary
 * ---------------------------------------------------------------------------
 * Design-System-Vorgabe ("Color Themes", Figma): vier Farbvarianten
 *   ink #052B8E | paper #FCF8EC | signal #FFC04E | leaf #2ADCBA
 * jede als primary (gefüllt: BG = Variantenfarbe, Text kontrastierend) und
 * secondary (Ghost/Outline: transparenter BG, 1.5px Border + Text in
 * Variantenfarbe). Registriert in functions.php (8 System-Styles + Legacy)
 * und damit im Editor je core/button auswählbar; die Regeln hier gelten
 * Frontend UND Editor (style.css ist als editor-style registriert).
 *
 * Geometrie: Radius 8px; Padding Primary 0.75rem/1rem (12/16px), Secondary
 * 0.5rem/1rem (8/16px) — die Figma-Export-Werte von btn-primary (41px hoch)
 * und btn-secondary (32–33px hoch). Die theme.json-Globalwerte (Radius 6,
 * Padding 0.75/1.15rem) gelten nur noch für Buttons ohne Style-Klasse.
 *
 * Hover-Matrix (User-Spec seit 12.08.): Seit 12.08. (User-Spec) gilt der
 * reine weiße #FFF-Hover (mit ink-Text, 19.9:1 AAA) NUR für die
 * weißen/Paper-Buttons (primary-paper, hero-primary, secondary-paper inkl.
 * header-ghost/footer-outline-Aliase). Farbige Varianten (ink/signal/leaf
 * als primary oder secondary sowie die Legacy-Aliase) behalten ihre
 * Hover-Tönungen (dunkelblau-75 #3F62AD, gelborange-75 #FFD183,
 * tuerkis-75 #7AE6CB, ink-Fill mit paper-25-Text bzw. die 75er-Ghost-
 * Tönungen). Global übernommen wurde nur das Padding: Primary 12px,
 * Secondary 8px.
 * Neuer Hover der weißen Familie (primary-paper, hero-primary,
 * secondary-paper inkl. header-ghost/footer-outline, ebenso der Hero-CTA):
 *   #FFF-Fill, ink-Text. Ghost-Varianten ziehen dabei auch die Border auf
 *   #FFF, weil der weiße Fill den Stroke überdeckt und der Frame im Hover
 *   keinen sichtbaren Stroke zeigt (Breite 1.5px bleibt, kein Reflow).
 * Farbige Varianten behalten ihre 75er-Hover-Tönungen wie oben (kein #FFF);
 * bei den Ghost-Varianten (secondary-signal/-leaf) bleibt der BG
 * transparent, es tönen sich nur Border und Text.
 * Nur der Button-FILL wechselt; die Fokus-Outline-Regeln (:focus-visible,
 * signal/ink) bleiben bestehen.
 *
 * Legacy-/Ad-hoc-Aliase (Kompatibilität, alte Markup-Klassen funktionieren
 * weiter; neue Regeln sind das System):
 *   is-style-primary    ≡ primary-signal (theme.json-Default; weiter genutzt
 *                        von resource-card.php — behält Global-Geometrie;
 *                        ohne eigenen Hover-Block, nur Ruhe-Regel signal/ink)
 *   is-style-secondary  ≡ primary-leaf (Legacy war gefüllt leaf/paper; weiter
 *                        genutzt von article-card.php / cta-banner.php)
 *   is-style-hero-primary ≡ primary-paper (Hero-CTA, Alias-Gruppe unten)
 *   is-style-angebote-signal ≡ primary-signal (08.08.-Korrektur: Textfarbe
 *                        ink wie die Systemvariante, ersetzt blue #317FE3 —
 *                        die visuelle Änderung am zweiten Angebote-Button ist
 *                        gewollt; Details im Angebote-Abschnitt)
 *   is-style-header-ghost / is-style-footer-outline ≡ secondary-paper auf
 *                        dunklem Grund — 12.08. globale Hover-Regel: Ruhe
 *                        paper Border/Text, Hover/Focus wechselt auf #FFF-Fill
 *                        mit ink-Text (#FFF-Border, vom Fill überdeckt;
 *                        eigene kompakte Padding-Regeln im Header-/Footer-
 *                        Teil unverändert)
 * Mapping-Tabelle alt→neu und Kontrast-Bewertung: siehe Task-Abschlussbericht.
 */

/* Fluid-Typo: Alle Font-Sizes ab 1rem bzw. 17px laufen über clamp(min, vw, max).
 * Die Untergrenze liegt bei ca. 83–88 % des bisherigen Werts, bevorzugt als
 * vw-Formel; das Maximum entspricht dem bisherigen Wert, damit der Desktop ab
 * 1136px Viewport pixelidentisch bleibt. Ausnahmen bleiben fest: alles unter
 * 1rem (Kicker, Tags, Mikrotext, etwa das small-Preset 0.875rem), em-Angaben
 * und inherit. */

/* System-Geometrie in zwei Gruppen (12.08. User-Spec): Primary-Buttons
 * 12px vertikal (0.75rem, Figma 41px-Bauhöhe), Secondary-Buttons 8px
 * vertikal (0.5rem, Figma 32–33px-Bauhöhe); horizontal beide 16px (1rem). */
.wp-block-button.is-style-primary-ink .wp-block-button__link,
.wp-block-button.is-style-primary-paper .wp-block-button__link,
.wp-block-button.is-style-primary-signal .wp-block-button__link,
.wp-block-button.is-style-primary-leaf .wp-block-button__link,
.wp-block-button.is-style-hero-primary .wp-block-button__link,
.wp-block-button.is-style-angebote-signal .wp-block-button__link {
	border-radius: 8px;
	padding: 0.75rem 1rem;
}

/* Primary-Buttons: maximale Schriftgröße 24 px (Anforderung, 17.08.).
 * Die Core-Utility .has-*-font-size würde sonst per !important das
 * Preset-Clamp durchsetzen (z. B. huge bis 67 px); deshalb trägt die
 * Regel hier selbst !important – unter den !important-Deklarationen
 * gewinnt die spezifischere Selektorgruppe (0,3,0 gegen 0,1,0). Der
 * Clamp startet bei 0.9375rem (15 px), bevorzugt 1.5vw (≈ 17 px bei
 * 1136 px Viewport, ≈ 21,6 px bei 1440 px Viewport) und deckelt hart
 * bei 1.5rem (24 px, ab 1600 px Viewport). Legacy is-style-primary
 * ist eingeschlossen (Alias auf primary-signal, resource-card.php
 * und inc/slider.php). */
.wp-block-button.is-style-primary-ink .wp-block-button__link,
.wp-block-button.is-style-primary-paper .wp-block-button__link,
.wp-block-button.is-style-primary-signal .wp-block-button__link,
.wp-block-button.is-style-primary-leaf .wp-block-button__link,
.wp-block-button.is-style-hero-primary .wp-block-button__link,
.wp-block-button.is-style-angebote-signal .wp-block-button__link,
.wp-block-button.is-style-primary .wp-block-button__link {
	font-size: clamp(0.9375rem, 1.5vw, 1.5rem) !important;
}

.wp-block-button.is-style-secondary-ink .wp-block-button__link,
.wp-block-button.is-style-secondary-paper .wp-block-button__link,
.wp-block-button.is-style-secondary-signal .wp-block-button__link,
.wp-block-button.is-style-secondary-leaf .wp-block-button__link {
	border-radius: 8px;
	padding: 0.5rem 1rem;
}

/* --- primary-ink: dunkelblau gefüllt, für helle/signale Flächen.
 * Hover dunkelblau-75 #3F62AD, Text paper-25 (5.80:1 AA) — wie vor dem
 * 12.08.-Lauf; Ruhe bleibt ink-Fill/paper-25-Text. */
.wp-block-button.is-style-primary-ink .wp-block-button__link {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

.wp-block-button.is-style-primary-ink .wp-block-button__link:hover,
.wp-block-button.is-style-primary-ink .wp-block-button__link:focus-visible {
	background: #3F62AD;
	color: var(--wp--preset--color--paper-25);
}

/* --- primary-paper: warmweiß gefüllt, für dunkle Flächen (Hero-Overlay,
 * ink-Sektionen). 12.08. globale Hover-Regel: Hover/Focus → #FFF-Fill,
 * Text bleibt ink — der frühere paper-25-Hover (#FEFDFA) ist ersetzt.
 * Alias: is-style-hero-primary (Hero-CTA) rendert dadurch identisch und
 * bleibt funktional. */
.wp-block-button.is-style-primary-paper .wp-block-button__link,
.wp-block-button.is-style-hero-primary .wp-block-button__link {
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
}

.wp-block-button.is-style-primary-paper .wp-block-button__link:hover,
.wp-block-button.is-style-primary-paper .wp-block-button__link:focus-visible,
.wp-block-button.is-style-hero-primary .wp-block-button__link:hover,
.wp-block-button.is-style-hero-primary .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

/* --- primary-signal: gelborange gefüllt. Die Textfarbe ist IMMER ink
 * (Ruhe UND Hover/Focus): ink auf signal = 7.40:1 (AAA), ink auf
 * gelborange-75 #FFD183 = 8.44:1 (AAA). Alias:
 * is-style-angebote-signal ≡ primary-signal (08.08.-Korrektur: dessen Text
 * ist jetzt ebenfalls ink, vorher blue #317FE3 — visuelle Änderung am
 * zweiten Angebote-Button gewollt, siehe Angebote-Abschnitt). */
.wp-block-button.is-style-primary-signal .wp-block-button__link {
	background: var(--wp--preset--color--signal);
	color: var(--wp--preset--color--ink);
}

.wp-block-button.is-style-primary-signal .wp-block-button__link:hover,
.wp-block-button.is-style-primary-signal .wp-block-button__link:focus-visible {
	background: #FFD183;
	color: var(--wp--preset--color--ink);
}

/* --- primary-leaf: türkis gefüllt. Ruhe leaf/ink = 6.91:1 (AA),
 * Hover tuerkis-75 #7AE6CB / ink = 8.04:1 (AAA). */
.wp-block-button.is-style-primary-leaf .wp-block-button__link {
	background: var(--wp--preset--color--leaf);
	color: var(--wp--preset--color--ink);
}

.wp-block-button.is-style-primary-leaf .wp-block-button__link:hover,
.wp-block-button.is-style-primary-leaf .wp-block-button__link:focus-visible {
	background: #7AE6CB;
	color: var(--wp--preset--color--ink);
}

/* --- secondary-ink: Ghost auf hellen Flächen (transparent, ink Border +
 * Text). Hover = Primary-Auftritt: ink-Fill, paper-25-Text (11.85:1 AAA);
 * Ruhe bleibt transparent/ink. */
.wp-block-button.is-style-secondary-ink .wp-block-button__link {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--ink);
	color: var(--wp--preset--color--ink);
}

.wp-block-button.is-style-secondary-ink .wp-block-button__link:hover,
.wp-block-button.is-style-secondary-ink .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

/* --- secondary-paper: Ghost auf dunklen Flächen (transparent, paper Border
 * + Text). 12.08. globale Hover-Regel: Hover/Focus → #FFF-Fill,
 * #FFF-Border, ink-Text (19.9:1 AAA) — der frühere Primary-Auftritt
 * paper-25-Fill/ink ist ersetzt. Ruhe bleibt transparent/paper. Nur für
 * dunkle Flächen gedacht (header-ghost/footer-outline auf ink); auf heller
 * Fläche ist secondary-ink die richtige Variante. */
.wp-block-button.is-style-secondary-paper .wp-block-button__link {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--paper);
	color: var(--wp--preset--color--paper);
}

.wp-block-button.is-style-secondary-paper .wp-block-button__link:hover,
.wp-block-button.is-style-secondary-paper .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

/* --- secondary-signal: Ghost auf dunklen Flächen (transparent, signal
 * Border + Text). Hover-Ghost-Tönung: Border/Text gelborange-75 #FFD183,
 * BG bleibt transparent; Ruhe bleibt transparent/signal. */
.wp-block-button.is-style-secondary-signal .wp-block-button__link {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--signal);
	color: var(--wp--preset--color--signal);
}

.wp-block-button.is-style-secondary-signal .wp-block-button__link:hover,
.wp-block-button.is-style-secondary-signal .wp-block-button__link:focus-visible {
	border-color: #FFD183;
	color: #FFD183;
}

/* --- secondary-leaf: Ghost auf dunklen Flächen (transparent, leaf Border +
 * Text). Hover-Ghost-Tönung: Border/Text tuerkis-75 #7AE6CB, BG bleibt
 * transparent; Ruhe bleibt transparent/leaf. */
.wp-block-button.is-style-secondary-leaf .wp-block-button__link {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--leaf);
	color: var(--wp--preset--color--leaf);
}

.wp-block-button.is-style-secondary-leaf .wp-block-button__link:hover,
.wp-block-button.is-style-secondary-leaf .wp-block-button__link:focus-visible {
	border-color: #7AE6CB;
	color: #7AE6CB;
}

/* --- Legacy-Aliase (Kompatibilität, siehe Mapping oben). --- */

/* is-style-primary: theme.json-Default signal/ink. Bewusst OHNE System-
 * Geometrie, damit content, der diese Klasse schon verwendet (z. B.
 * resource-card.php), exakt so weiter rendert wie bisher. Ohne eigenen
 * Hover-Block: es greift nur die Ruhe-Regel signal/ink — wie vor dem
 * 12.08.-Lauf. Die Geometrie-Ausnahme betrifft nur Radius/Padding, die
 * 24-px-Schrift-Cap oben gilt trotzdem (is-style-primary ist in der
 * Cap-Gruppe eingeschlossen). */
.wp-block-button.is-style-primary .wp-block-button__link {
	background: var(--wp--preset--color--signal);
	color: var(--wp--preset--color--ink);
}

/* is-style-secondary: Legacy war ein gefüllter Leaf-Button (leaf/paper in
 * Ruhe, ink/paper bei Hover). Wird von article-card.php und cta-banner.php
 * weitergenutzt; Hover = ink-Fill mit paper-Text (wie vor dem 12.08.-Lauf). */
.wp-block-button.is-style-secondary .wp-block-button__link {
	background: var(--wp--preset--color--leaf);
	color: var(--wp--preset--color--paper);
}

.wp-block-button.is-style-secondary .wp-block-button__link:hover,
.wp-block-button.is-style-secondary .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
}

/* is-style-angebote-signal: Alias auf primary-signal (08.08.-Korrektur:
 * Textfarbe ink statt blue — vorher "blau auf signal" 2.45:1 als
 * User-Mandat; ersetzt zugunsten der System-Signalvariante, Details im
 * Angebote-Abschnitt). Hover gelborange-75 #FFD183, Text ink — wie vor dem
 * 12.08.-Lauf. */
.wp-block-button.is-style-angebote-signal .wp-block-button__link {
	background: var(--wp--preset--color--signal);
	border-radius: 8px;
	color: var(--wp--preset--color--ink);
}

.wp-block-button.is-style-angebote-signal .wp-block-button__link:hover,
.wp-block-button.is-style-angebote-signal .wp-block-button__link:focus-visible {
	background: #FFD183;
	color: var(--wp--preset--color--ink);
}

/*
 * Header donate button: ghost style on the ink header. Alias on
 * secondary-paper, 12.08. globale Hover-Regel: Ruhe paper (#FCF8EC)
 * Outline und paper Text; Hover/Focus → #FFF-Fill, #FFF-Border (vom Fill
 * überdeckt), ink-Text (19.9:1 AAA). Der frühere paper-25-Fill-Hover ist
 * ersetzt; auf dem ink-Header bestehen beide Zustände AAA (paper/ink
 * 11.35:1, ink/#FFF 19.9:1). Scoped to its own style class, other buttons
 * keep their defaults. Kompakt-Padding (3px) bleibt.
 */
.wp-block-button.is-style-header-ghost .wp-block-button__link {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--paper);
	color: var(--wp--preset--color--paper);
}

.wp-block-button.is-style-header-ghost .wp-block-button__link:hover,
.wp-block-button.is-style-header-ghost .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

/*
 * ---------------------------------------------------------------------------
 * Compact chrome controls (header + footer)
 * ---------------------------------------------------------------------------
 * The header and footer controls get a fixed 3px top/bottom padding. This
 * overrides the theme.json button default (0.7rem top/bottom) only for these
 * concrete elements; hero and content buttons keep their own measures. Font
 * sizes are untouched, and left/right padding stays as defined per element
 * above. The combined rule sits after all component rules, so it wins the
 * cascade for the top/bottom pair.
 */
.kv-site-header .wp-block-search__input,
.kv-site-header .wp-block-button.is-style-header-ghost .wp-block-button__link,
.kv-newsletter-form input,
.kv-newsletter-form button,
.wp-block-button.is-style-footer-outline .wp-block-button__link {
	padding-bottom: 3px;
	padding-top: 3px;
}

/*
 * ---------------------------------------------------------------------------
 * kv-section: full-bleed background shell + centered inner content wrapper
 * ---------------------------------------------------------------------------
 * Reusable wrapper for the page content sections built by the pattern tasks
 * (hero, card grids, CTA, …).
 *
 * `.kv-section` is the background SHELL: a full-bleed band `width: 100vw`
 * re-centered on its (centered) containing block by
 * `margin-inline: calc(50% - 50vw)`, so the section background and borders
 * reach the exact window edges at every viewport (html/body overflow-x: clip
 * is the safety net against a horizontal scrollbar). It carries zero padding
 * of its own and holds the `has-*` color/text utility classes. Pattern,
 * renderer and DB markup will wrap their content in `.kv-section__inner`
 * (later plan tasks).
 *
 * `.kv-section__inner` is the content wrapper: centered with
 * `margin-inline: auto`, `max-width: 1440px` and (border-box) 152px side
 * padding at ≥1440px → a 1136px content column, matching `layout.wideSize`.
 * It holds the horizontal + vertical `clamp()` padding. The breaking-news bar,
 * header and footer are not content sections and keep their own sizing.
 * A plain utility class was chosen over a core/group block style: the former
 * is directly usable in pattern markup without extra registration.
 *
 * Width correction (08.08.): sections built with this class live inside the
 * 752px post-content column. The explicit full-bleed width plus the
 * centered negative margin break the section out of that column to the full
 * window width, so the section background and borders run edge to edge
 * instead of stopping at the content column.
 * Note on margins: auto margins resolve to 0 when the element is wider than
 * its containing block, so a plain `margin-inline: auto` would pin the
 * section to the left of the column and overflow on the right. The computed
 * half-width difference is used instead; it is negative whenever the
 * containing block is narrower than the target width, which is exactly the
 * breakout case, and 0 when the parent is already the full target width.
 * (`.kv-section__inner` keeps `margin-inline: auto` because it is a plain
 * centered column inside the already-broken-out 100vw shell.)
 */
.kv-section {
	box-sizing: border-box;
	margin-inline: calc(50% - 50vw);
	max-width: none;
	padding: 0;
	width: 100vw;
}

.kv-section__inner {
	box-sizing: border-box;
	margin-inline: auto;
	max-width: 1440px;
	padding: clamp(3rem, 8vw, 5rem) clamp(1rem, 10.5vw, 9.5rem);
	width: 100%;
}

@media (min-width: 1440px) {
	.kv-section__inner {
		padding: 80px 152px;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Unser Ansatz — home section
 * ---------------------------------------------------------------------------
 * The intro heading plus the three approach panels. Geometry from the Figma
 * "A - Startseite" export: the `how` row is 1136px wide and holds three
 * panels with 80px gaps, the row is 278px tall. Since 08.09. the panels carry
 * the .kv-panel--card variant (paper-25 surface, 16px radius, 2rem padding),
 * like the card panels elsewhere; the row geometry below stays untouched.
 * The grid keeps 3 columns while the
 * .kv-section padding leaves enough room and collapses to one column on
 * small viewports.
 * The "Darum gibt es KLIMA° vor acht" section shares these rules through the
 * grouped .kv-darum selectors, so both sections keep the identical geometry.
 *
 * 08.08. correction: the panel stack is top-aligned (justify-content
 * flex-start) instead of centered, so the three panel titles share one
 * baseline row. The customer asked for top alignment on the "Unser Ansatz"
 * panels; since the darum panels share the same .kv-panel rule they switch
 * consistently, keeping both rows pixel-identical.
 */
.kv-approach .kv-approach-panels,
.kv-darum .kv-darum__panels {
	align-items: stretch;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	column-gap: 80px;
}

/* Core emits `is-layout-flow` on the panels row at render time; its
 * `> * + *` rule would add a 20px block-gap margin on the 2nd and 3rd grid
 * items, shifting them down inside their stretched rows and shortening their
 * boxes. The three panels sit on one grid row, so the flow gap must be zero
 * here. */
.kv-approach-panels > * + *,
.kv-darum__panels > * + * {
	margin-block-start: 0;
}

.kv-approach .kv-panel,
.kv-darum .kv-panel {
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	min-height: 278px;
	text-align: center;
}

/* Korrektur 28.08. (Auftraggeber): mehr vertikale Luft in der
 * Ansatz-Sektion. 1) Oben: Der Hero-Overlay (bottom: -40px) hängt 40px in
 * die Sektion hinein; das 80px-Standard-Top-Padding des inner ließ dadurch
 * nur 40px Sicht-Abstand zur H2. 120px Padding stellen ~80px freie Fläche
 * unter der Overlay-Kante her. 2) Nach dem Intro-Absatz ("… Wie wir dort
 * hin kommen?") klaffte nur der 20px-Flow-Gap zur Panel-Reihe; auf die
 * Panels hin wirkt der Absatz als Lead, die Distanz darf Sektions-Luft
 * haben. Selektor (0,3,0) schlägt den Core-Flow-Gap ohne !important. */
.kv-approach .kv-section__inner {
	padding-block-start: clamp(5rem, 10vw, 7.5rem);
}

.kv-approach .kv-section__inner > .kv-approach-panels {
	margin-block-start: clamp(2.5rem, 5vw, 4rem);
}

/*
 * .kv-panel — generic single content block reused by the remaining content
 * sections (how panels, CTA/offer panels of the later pattern tasks). The
 * generic rule is layout-only: stacked content with no box decoration.
 * Sections that need a real card surface (the offer panels of task 11 measure
 * radius 16px in the export) apply the .kv-panel--card variant on top — since
 * 08.09. the "Unser Ansatz" panels use it as well.
 */
.kv-panel {
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
}

.kv-panel--card {
	background: var(--wp--preset--color--paper-25);
	border-radius: 16px;
	padding: 2rem;
}

@media (max-width: 782px) {
	.kv-approach .kv-approach-panels,
	.kv-darum .kv-darum__panels {
		grid-template-columns: 1fr;
		row-gap: 3rem;
	}

	.kv-approach .kv-panel,
	.kv-darum .kv-panel {
		min-height: 0;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Darum gibt es KLIMA° vor acht — home section
 * ---------------------------------------------------------------------------
 * Die drei Abschluss-Links der Darum-Panels sind seit 12.08. keine Textlinks
 * mehr, sondern Ghost-Buttons der Systemvariante is-style-secondary-ink
 * (ink Border und ink Text in Ruhe, Hover/Focus = Primary-Auftritt mit
 * ink-Fill und paper-25 Text, dieselbe Variante wie im article-card-Pattern).
 * Die Buttons liegen im Markup direkt nach den Panel-Paragraphen.
 *
 * Die Textlink-Regel unten bleibt als Fallback für redaktionelle Textlinks
 * in den Panels erhalten. Auf die Button-Links schlägt sie nicht durch: Die
 * Systemregel .wp-block-button.is-style-secondary-ink .wp-block-button__link
 * ist spezifischer und gewinnt die Farb- und Border-Deklarationen; nur die
 * 2px-Unterstreichung wird per Ausnahme neutralisiert (Vorbild: die
 * .kv-panel-section-Ausnahme weiter unten).
 *
 * Die Panels sind zentrierter Text auf Paper-Hintergrund. text-align: center
 * setzt bereits die gemeinsame Panel-Regel (.kv-approach/.kv-darum .kv-panel);
 * die Button-Zeile wird zusätzlich über justify-content zentriert (Vorbild
 * .kv-panel--center .wp-block-buttons). Über margin-block-start: auto klebt
 * die Button-Zeile am Panel-Boden, so stehen die drei Buttons auch bei
 * unterschiedlich langen Panel-Paragraphen in einer gemeinsamen unteren Linie.
 * padding-block-start: 1rem garantiert zusätzlich eine feste Lücke von 1rem
 * zwischen Paragraph und Button-Zeile, auch wenn kein freier Raum übrig ist
 * (Panel 1) und auf Mobile (dort löst margin-block-start: auto zu 0 auf).
 */
.kv-darum .kv-panel a {
	color: var(--wp--preset--color--ink);
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 0.18em;
}

.kv-darum .kv-panel a:hover,
.kv-darum .kv-panel a:focus-visible {
	text-decoration-thickness: 3px;
}

.kv-darum .kv-panel .wp-block-buttons {
	justify-content: center;
	margin-block-start: auto;
	padding-block-start: 1rem;
}

.kv-darum .kv-panel .wp-block-button__link {
	text-decoration: none;
}

/*
 * ---------------------------------------------------------------------------
 * Panel-Gruppen (generisch)
 * ---------------------------------------------------------------------------
 * Generische Regeln für das Panel-Gruppen-System (Panel-"Karte", "Panel
 * Kompakt" und ihre Sektionen, vgl. Plan "panel-gruppen"). Die Kartenfläche
 * selbst existiert bereits oberhalb in diesem File (.kv-panel--card:
 * paper-25-Fill, 16px Radius, 2rem Padding) und wird hier nicht neu
 * angelegt, nur über die Panel-Patterns referenziert.
 */
.kv-panel--card > * + * {
	margin-block-start: 1.5rem;
}

/* Button-Zeile in Karten-Panels unten bündig: margin-block-start: auto
 * klebt die Button-Zeile an die Panel-Unterkante, so stehen die Buttons
 * auch bei unterschiedlich langen Panel-Paragraphen in einer gemeinsamen
 * unteren Linie (Vorbild .kv-darum .kv-panel .wp-block-buttons). Das
 * Panel selbst ist bereits eine Flex-Column (.kv-panel), die Zeile folgt
 * im DOM auf den Paragraph; Grid-Stretch sorgt für gleiche Panel-Höhen
 * in der Zeile. padding-block-start: 1rem garantiert die Mindestlücke
 * zum Paragraph. Inline-Buttons in Panels verteilen (Kundenwunsch 16.08.):
 * stehen mehrere Buttons nebeneinander, werden sie auf die Zeile verteilt;
 * einzelne Buttons bleiben links (space-between mit einem Kind = flex-start). */
.kv-panel-section .kv-panel .wp-block-buttons {
	justify-content: space-between;
	margin-block-start: auto;
	padding-block-start: 1rem;
}

/* Zentrierte Panels: Einstieg über die Zusatzklasse "kv-panel--center"
 * (Panel > Erweitert > Zusätzliche CSS-Klasse). Zentriert Überschrift,
 * Fließtext und die Buttons des Panels. */
.kv-panel--center {
	align-items: center;
	text-align: center;
}

.kv-panel--center .wp-block-buttons {
	justify-content: center;
}

/* Textlinks in Panel-Sektionen: verallgemeinerte .kv-darum-Behandlung
 * (ink, 2px Unterstreichung, Offset 0.18em), damit auch Kompakt-Panels
 * außerhalb der Darum-Sektion ihre Abschluss-Links als Textlink erhalten.
 * Der Button-Link im Karten-Panel bekommt die Unterstreichung der
 * Textlink-Regel per Ausnahme wieder genommen (der Button hat selbst seine
 * Button-Optik aus dem Button-System). */
.kv-panel-section .kv-panel a {
	color: var(--wp--preset--color--ink);
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 0.18em;
}

.kv-panel-section .kv-panel a:hover,
.kv-panel-section .kv-panel a:focus-visible {
	text-decoration-thickness: 3px;
}

/* Textlinks im dunklen Sektionsfluss (global, seit 06.09.): Content-Links auf
 * ink-Flächen durften nie auf das UA-Default-Blau (#0000EE) zurückfallen —
 * das Muster der dunklen Flächen (Nav-Submenüs, Footer, vormals nur über
 * body.page-id-33/Panel-Sektion geregelt): paper-25 im Ruhezustand
 * (11,85:1 AAA auf ink #052B8E), signal als Hover-/Fokus-Akzent. Bewusst
 * nur die drei Fluss-Selektoren (Direkt-Link, Link im Absatz, Link im
 * Listeneintrag des .kv-section__inner): Karten-Links sitzen in .kv-panel
 * bzw. .kv-panel--card und behalten über die Panel-Regel oben ihr ink auf
 * paper-25-Fläche. Buttons sind nicht erfasst (eigene Optik aus dem
 * Button-System); klassierte Utility-Links schlagen mit !important ohnehin.
 * Die alten body.page-id-33-scoped Link-Regeln (25.08.) sind damit ersetzt. */
.kv-section.has-ink-background-color .kv-section__inner > a,
.kv-section.has-ink-background-color .kv-section__inner p a,
.kv-section.has-ink-background-color .kv-section__inner li a {
	color: var(--wp--preset--color--paper-25);
}

.kv-section.has-ink-background-color .kv-section__inner > a:hover,
.kv-section.has-ink-background-color .kv-section__inner > a:focus-visible,
.kv-section.has-ink-background-color .kv-section__inner p a:hover,
.kv-section.has-ink-background-color .kv-section__inner p a:focus-visible,
.kv-section.has-ink-background-color .kv-section__inner li a:hover,
.kv-section.has-ink-background-color .kv-section__inner li a:focus-visible {
	color: var(--wp--preset--color--signal);
}

.kv-panel-section .kv-panel .wp-block-button__link {
	text-decoration: none;
}

/* Gruppengeometrie (Task 2, Version 0.1.52): Die Panel-Gruppe ist eine
 * core/group mit nativem Grid-Layout ({"type":"grid","columnCount":3}, siehe
 * patterns/panel-gruppe.php). Core schreibt die Spaltenzahl als
 * Block-Support-Style (grid-template-columns: repeat(N, minmax(0, 1fr))) in
 * den wp_head NACH der Theme-style.css; deshalb bekommt nur das Mobile-Um-
 * stapeln auf 1 Spalte ein !important (Vorbild .kv-card-grid, style.css:663).
 * Die 40px-Spaltenlücke deckt sich mit .kv-angebote/.kv-aktuelles; die
 * Zeilenlücke skaliert über einen Clamp und wird wie die Sektions-Paddings
 * viewport-abhängig komprimiert. */
.kv-panel-section .kv-panel-group {
	column-gap: 40px;
	row-gap: clamp(2rem, 4vw, 3rem);
}

/* Core gibt dem Grid zur Laufzeit is-layout-flow mit; dessen `> * + *`-Regel
 * (1.25rem Margin) würde die Panels ab dem zweiten in den eigenen Grid-Zeilen
 * verschieben. Die drei Panels sitzen auf einer Grid-Zeile, also muss der
 * Flow-Abstand hier 0 sein (Vorbild .kv-angebote__grid, style.css:1412). */
.kv-panel-group > * + * {
	margin-block-start: 0;
}

@media (max-width: 782px) {
	.kv-panel-group {
		grid-template-columns: 1fr !important;
	}
}

/*
 * Wirkungsseite – Intro-Zeile (Auftrag 30.08.): Bild links, Intro-Absatz
 * rechts. Die max-Breiten spiegeln die Figma-Vorgabe (Bild 460,4130859375 px,
 * Text 635,5869140625 px); zusammen mit dem 40px-Spaltenabstand fuellen sie
 * exakt die 1136px-Innenbreite von `.kv-section__inner` (wideSize). Engere
 * Viewports schrumpfen ueber die Flex-Basis, unter 782px stapelt die Zeile.
 * Das Bildtraegt 24px Radius (wie die Testimonial-Fotos), der
 * Marken-Hashtag im Intro die leaf-Tuerkis der Wortmarke.
 */
.kv-wirkung-intro {
	align-items: flex-start;
	column-gap: 40px;
	display: flex;
	row-gap: clamp(1.5rem, 3vw, 2.5rem);
}

.kv-wirkung-intro__image {
	flex: 0 1 460.4130859375px;
	margin: 0;
	max-width: 460.4130859375px;
}

/* Bild-rechts-Variante (Auftrag 13.09., Materialien-Seite Podcastkoffer):
 * Markup-Reihenfolge __copy -> __image legt das Bild ohne Zusatz-CSS rechts;
 * die Modified-Klasse dokumentiert die Spiegelung nur. Mobile (max-width:
 * 782px) stapelt die Basis-Regel mit flex-direction column — Copy steht
 * dort zuerst, das Bild darunter (bewusst so, Titel/Text vor Produktbild). */

.kv-wirkung-intro__image img {
	border-radius: 24px;
	height: auto;
	width: 100%;
}

.kv-wirkung-intro__copy {
	flex: 0 1 635.5869140625px;
	max-width: 635.5869140625px;
}

/* Abstand Intro-Zeile -> Panel-Reihe: der reine Core-Flow-Gap (20px)
 * trennt den Einleitungssatz zu knapp von den Karten. Der Selektor
 * (0,3,0) schlägt die Core-Flow-Gap ohne !important (Muster
 * .kv-approach-panels, Zeile 1537). */
.kv-panel-section .kv-section__inner > .kv-panel-group:not(:first-child) {
	margin-block-start: clamp(1.5rem, 3vw, 2.5rem);
}

/* Karten auf dunkler Sektionsflaeche: Der Sektions-Text (paper) gilt bis in
 * die paper-25-Karten durch; dort ist ink die lesbare Farbe (Vorbild der
 * Link-Ausnahme fuer .kv-panel-section.has-ink-background-color). */
.kv-panel-section.has-ink-background-color .kv-panel--card {
	color: var(--wp--preset--color--ink);
}

/* Marken-Hashtag (Auftraggeber 30.08.; Farb-Vorgabe 08.09.): keine farbliche
 * Hervorhebung mehr – der Hashtag übernimmt die Textfarbe der Umgebung;
 * nur die leichte Betonung (600) bleibt. Die Klasse bleibt als Haken für
 * den render_block-Swap bzw. gezielte Typo-Korrekturen erhalten. */
.kv-hashtag {
	font-weight: 600;
}

/* Erfolge-Sektion (Auftrag 30.08.): Der Testimonials-Block sitzt in der
 * hellen Erfolge-Sektion und bringt seine eigene .kv-section__inner-Huelle
 * mit; ohne Korrektur addieren sich beide Innenabstaende (80 + 80). Der
 * aeussere Inner traegt den Vertikal-Rhythmus, der innere wird flach –
 * der Slider-Abstand kommt aus dem Flow-Gap plus der .kv-slider__slider-
 * Regel. */
.kv-wirkung-erfolge .kv-testimonials .kv-section__inner {
	padding-block: 0;
}

@media (max-width: 782px) {
	.kv-wirkung-intro {
		flex-direction: column;
	}

	.kv-wirkung-intro__image,
	.kv-wirkung-intro__copy {
		flex-basis: auto;
		max-width: 100%;
		width: 100%;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Unsere Angebote — home section
 * ---------------------------------------------------------------------------
 * Geometry from the Figma export "content-offer" (canvas "Page 1"): the
 * section row is 1136px wide and splits into a 367px intro column and a
 * 729px offer column with a 40px gap (367 + 40 + 729 = 1136, the wide size
 * the .kv-section padding leaves at ≥1440px). The offer column stacks the
 * two `offer-single` cards vertically, each 729px wide and 294px tall, with
 * a 40px gap; the cards keep the 120px top/bottom padding of the section,
 * so the first card top edge sits at the section's inner top edge.
 * Section surface (08.08. user spec): warmweiss `paper` (#FCF8EC) through
 * the has-paper-background-color utility on the section element; the ink
 * cards (ink surface, paper-25 text, 11.85:1) and their tuerkis buttons
 * (leaf fill, ink text, 6.91:1) stay untouched.
 */
.kv-angebote__grid {
	align-items: start;
	display: grid;
	grid-template-columns: minmax(0, 367px) minmax(0, 729px);
	column-gap: 40px;
}

/* Core emits `is-layout-flow` on the grid at render time; its `> * + *`
 * rule would add a 1.25rem block-gap margin on the second grid item,
 * shifting the offer column down inside its row. Both items sit on one grid
 * row, so the flow gap must be zero here. */
.kv-angebote__grid > * + * {
	margin-block-start: 0;
}

.kv-angebote__offer {
	display: grid;
	gap: 40px;
	grid-template-columns: minmax(0, 1fr);
}

/* Core grants `.is-layout-flow` (margin-block: 1.25rem) to every group
 * containing flow content, including the offer cards and the offer column
 * itself. Grid children already carry their margin-block-start, and the
 * 20px top margin on the second card would inflate the 40px gap to 60px,
 * so fix it to zero. All other gap spacing comes from grid gap. */
.kv-angebote__offer > * + * {
	margin-block-start: 0;
}

/* The two offer cards: ink surface with warm-white text (classes
 * has-ink-background-color / has-paper-25-color), 16px radius and 40px
 * padding from the export, inner stack spacing 24px. The color pair
 * reaches 11.85:1 contrast (WCAG AAA). */
.kv-offer-card {
	border-radius: 16px;
	padding: 40px;
}

.kv-offer-card > * + * {
	margin-block-start: 1.5rem;
}

/* 08.08. Hover-Korrektur: der erste Karten-Button ("Zu den Ressourcen")
 * trägt jetzt im Pattern die Systemklasse is-style-primary-leaf (vorher
 * Legacy is-style-secondary + Sektions-Override) — die Systemregel liefert
 * damit leaf/ink in Ruhe (6.91:1 AA) und den TUERKIS-75-Hover #7AE6CB/ink
 * (8.04:1 AAA), Radius 8 und System-Geometrie. Der frühere scoped
 * Override (Invert-Hover ink/paper-25) ist entfernt. */

/* 08.08. correction — the second offer card button ("Jetzt aktiv werden",
 * box "Für die Öffentlichkeit") uses the is-style-angebote-signal variant.
 * 08.08. Korrektur: die Textfarbe ist ink #052B8E in ALLEN Zuständen
 * (Ruhe UND Hover/Focus), identisch zur Systemvariante primary-signal —
 * der frühere design-mandated Blau-Text (#317FE3, 2.45:1 auf signal) ist
 * gewollt ersetzt. ink auf signal misst 7.40:1 (WCAG AAA). Hover wechselt
 * den Fill auf das User-Design-Token "gelborange 75": #FFD183 (ink auf
 * #FFD183 8.44:1 AAA). Focus behält den theme-globalen signal-Fokus-Ring
 * aus :focus-visible (3px, 4px Offset; er sitzt auf der ink-Karte um den
 * Button, bei 7.4:1 sichtbar). */
.kv-angebote .wp-block-button.is-style-angebote-signal .wp-block-button__link {
	background: var(--wp--preset--color--signal);
	border-radius: 8px;
	color: var(--wp--preset--color--ink);
}

.kv-angebote .wp-block-button.is-style-angebote-signal .wp-block-button__link:hover,
.kv-angebote .wp-block-button.is-style-angebote-signal .wp-block-button__link:focus-visible {
	background: #FFD183;
	color: var(--wp--preset--color--ink);
}

@media (max-width: 782px) {
	.kv-angebote__grid {
		grid-template-columns: 1fr;
		row-gap: 2.5rem;
	}

	.kv-offer-card {
		padding: 1.5rem 1.25rem;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Aktuelles — home section
 * ---------------------------------------------------------------------------
 * The blog teaser from the Figma "secion-blog-teaser" frame (canvas "A -
 * Startseite"): a dark section (08.08. user spec: ink #052B8E with paper-25
 * section text, 11.85:1 WCAG AAA — via the has-ink-background-color /
 * has-paper-25-color utilities on the section element; compare the
 * wirkung-slider section) stacking the intro, a row of three
 * `blog-teaser-single` cards and a closing banner. The teaser row is 1136px
 * wide with 40px gaps; each card is 352 x 594 (3 * 352 + 2 * 40 = 1136) with
 * a 16px radius from the export. Cards stack the 352 x 198 image whose
 * `category-tag` (82 x 25, signal surface, ink text) is pinned to the
 * bottom-right corner of the picture (transform 257/161 within Frame 12),
 * then the info block: 34px title (fontSize "large"), 24px teaser (fontSize
 * "normal", max 230 characters in the export) and a `btn-secondary`
 * (cornerRadius 8). Cards stay white with ink text (explicit overrides below
 * because the section text colour is now light).
 */
.kv-aktuelles__grid {
	display: grid;
	gap: 40px;
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Core grants `.is-layout-flow` to the grid row and the cards: the row's
 * `> * + *` rule would add a 20px top margin on the 2nd and 3rd grid items
 * (they sit on one grid row, so grid gap owns the spacing), and the cards'
 * own block margin would shift content inside them. Zero both here. */
.kv-aktuelles__grid > * + * {
	margin-block-start: 0;
}

/* Card surface: white with ink text, so the teasers stay dark on light
 * inside the (now ink) section. The title/teaser inherit the card colour;
 * the category tag and card button set their own colours. */
.kv-aktuelles__card {
	background: var(--wp--preset--color--white);
	border-radius: 16px;
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.kv-aktuelles__card > * + * {
	margin-block-start: 0;
}

.kv-aktuelles__media {
	margin: 0;
	position: relative;
}

.kv-aktuelles__image {
	aspect-ratio: 352 / 198;
	display: block;
	height: auto;
	object-fit: cover;
	width: 100%;
}

/* Category tag: 82 x 25, signal surface with ink text, pinned to the
 * bottom-right corner of the image (x 257 / y 161 in the 352 x 198 export
 * frame, i.e. ~13px from the right and ~12px from the bottom edge). */
.kv-aktuelles__tag {
	background: var(--wp--preset--color--signal);
	border-radius: 4px;
	color: var(--wp--preset--color--ink);
	font-size: inherit;
	font-weight: 700;
	line-height: 1;
	padding: 0.45rem 0.6rem;
	position: absolute;
	right: 0.75rem;
	bottom: 0.75rem;
	text-transform: uppercase;
}

.kv-aktuelles__card-body {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	padding: 2.5rem;
}

.kv-aktuelles__card-body > * + * {
	margin-block-start: 1rem;
}

.kv-aktuelles__card-title {
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.15;
	margin: 0;
}

.kv-aktuelles__card-text {
	color: var(--wp--preset--color--ink);
	margin: 0;
	padding-bottom: 1.5rem;
}

/* Card button (08.08. user spec "blau auf warmweiss", the same reading as
 * the breaking-news "blue on gold"): warmweiss `paper` fill with `blue`
 * (#317FE3) text on the raw card links (blog-posts block). Der frühere
 * Banner-Button nutzte dieselbe Regel (is-style-secondary); 13.08. macht den
 * Banner-Button zur System-Primary primary-paper (siehe Closing-Banner
 * unten), der is-style-secondary-Selektor bleibt für Alt-Inhalte erhalten.
 * blue/paper measures 3.75:1 — WCAG AA for large
 * text only, normal-text AA (4.5:1) is missed; implemented as specified and
 * reported in the task review with an alternative (ink/paper 11.35:1 AAA).
 * Hover/focus stay kontraststark: `paper-25` fill with `ink` text (11.85:1
 * AAA) for a clearly visible state change; the theme-wide signal focus
 * outline remains (7.4:1 on the ink section). */
.kv-aktuelles .wp-block-button.is-style-secondary .wp-block-button__link,
.kv-aktuelles__card-button {
	background: var(--wp--preset--color--paper);
	border-radius: 8px;
	color: var(--wp--preset--color--blue);
}

.kv-aktuelles .wp-block-button.is-style-secondary .wp-block-button__link:hover,
.kv-aktuelles .wp-block-button.is-style-secondary .wp-block-button__link:focus-visible,
.kv-aktuelles__card-button:hover,
.kv-aktuelles__card-button:focus-visible {
	background: var(--wp--preset--color--paper-25);
	color: var(--wp--preset--color--ink);
}

.kv-aktuelles__card-button {
	align-self: flex-start;
	display: inline-block;
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 700;
	margin-block-start: auto;
	padding: 0.75rem 1rem;
	text-decoration: none;
}

/* Closing banner (Figma Frame 71): the "Du möchtest mehr sehen?" h3 prompt
 * plus the "Hier geht's zu weiteren Inhalten" button below it. Figma sah
 * dort ein `btn-secondary` vor; 13.08. User-Spec-Override: der Banner-Button
 * ist jetzt die System-Primary primary-paper (warmweiss-Fill, ink-Text,
 * Hover #FFF-Fill/ink — 11.85:1 bzw. 19.9:1 AAA), gesteuert direkt über die
 * Button-System-Regeln oben; die blue/paper-Gruppe darüber bleibt nur noch
 * als Legacy-Fallback für Alt-Inhalte (is-style-secondary / card-button).
 * Banner decision (18.08. user spec): the banner keeps the section's
 * transparent ink surface — an own dark background would no longer stand
 * out — and now belongs to the END of the teaser section instead of being
 * set apart as its own framed block: the 1px paper-25 separator line and
 * the top padding are gone, the banner sits 60px directly below the card
 * grid (fixed 60px on every viewport, same rationale as the section's
 * padding-bottom), so the prompt reads as the closing row of the section
 * without a competing surface.
 * Korrektur 08.08.: the heading replaces the old `.banner-text` paragraph
 * (rule removed). Core headings carry UA margins, which would enlarge the
 * 20px flex gap; zero them so the flex gap alone spaces heading and
 * buttons. The h3 keeps the `large` size preset and inherits the section's
 * `paper-25` text colour (11.85:1 WCAG AAA on ink). */
.kv-aktuelles__banner {
	align-items: flex-start;
	display: flex;
	flex-direction: column;
	gap: 1.25rem;
	margin-block-start: 3.75rem; /* 60px */
}

.kv-aktuelles__banner .wp-block-heading {
	margin: 0;
}

/* Die Buttons-Zeile sitzt in der Flex-Column des Banners, deren
 * align-items: flex-start die Zeile auf Buttonbreite einzieht – ein
 * justify-content: center in der Zeile selbst bleibt dann wirkungslos,
 * weil die Zeile so breit ist wie ihr Kind. align-self: stretch gibt der
 * Zeile die volle Bannerbreite zurück; justify-content: center (hier auch
 * per CSS gesetzt, damit es ohne Editor-Layout-Attribut greift) zentriert
 * den Button darunter. Die Überschrift bleibt links. */
.kv-aktuelles__banner .wp-block-buttons {
	align-self: stretch;
	justify-content: center;
}

@media (max-width: 782px) {
	.kv-aktuelles__grid {
		grid-template-columns: 1fr;
	}

	.kv-aktuelles__card-body {
		padding: 1.5rem 1.25rem;
	}
}

/*
 * .kv-article-card — the standalone Article Card pattern, aligned to the
 * blog-teaser-single design (image 352 x 198, signal category tag at the
 * bottom-right of the image, large title, normal teaser, secondary button).
 * It reuses the .kv-aktuelles__card surface rules so the preview in the
 * pattern picker matches the home section's cards.
 */
.kv-article-card {
	background: var(--wp--preset--color--white);
	border-radius: 16px;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.kv-article-card__media {
	margin: 0;
	position: relative;
}

.kv-article-card__image img {
	aspect-ratio: 352 / 198;
	display: block;
	height: auto;
	object-fit: cover;
	width: 100%;
}

.kv-article-card__tag {
	background: var(--wp--preset--color--signal);
	/* Radius 8px wie im Button-System (.wp-block-button__link), damit das
	 * Badge mit seiner Hover-Fläche wie ein gefüllter Button wirkt. */
	border-radius: 8px;
	line-height: 1;
	margin: 0;
	padding: 0.45rem 0.6rem;
	position: absolute;
	right: 0.75rem;
	bottom: 0.75rem;
}

.kv-article-card .kv-article-card__title {
	line-height: 1.15;
	margin: 0;
	padding: 2.5rem 2.5rem 0;
}

/* Datum direkt unter dem Kartentitel (Blog-Übersicht /aktuelles/): die
 * Standard-Schrift "17/24" nach Auftraggeber-Vorgabe - fluid 15-17px (die
 * Fluid-Typo-Konvention clamp(0.9375rem, 1.5vw, 1.0625rem), Maximum 17px
 * erreicht ab ~1136px Viewport) auf fester 24px-Zeilenhöhe, Gewicht 400 in
 * Source Sans 3. Das Datum ist linksbündig zum Titel (exakt dieselbe
 * Innenkante wie `kv-article-card__title`) und sitzt direkt unter ihm: die
 * 0.25rem-Oberkante hält es bewusst eng am Titel, der Abstand zum Auszug
 * bleibt über dessen bestehende 1rem-Padding-Oberkante erhalten. Die
 * Textfarbe erbt das `wp:post-date`-Element (time) von der Karte (ink). */
.kv-article-card .kv-article-card__date {
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem); /* 15-17px, fluid (17/24) */
	line-height: 24px;
	margin: 0;
	padding: 0.25rem 2.5rem 0;
}

.kv-article-card .kv-article-card__text {
	margin: 0;
	padding: 1rem 2.5rem 0;
}

.kv-article-card > .wp-block-buttons {
	margin-block-start: auto;
	padding: 1.25rem 2.5rem 2.5rem;
}

@media (max-width: 782px) {
	.kv-article-card .kv-article-card__title {
		padding: 1.5rem 1.25rem 0;
	}

	.kv-article-card .kv-article-card__date {
		padding: 0.25rem 1.25rem 0;
	}

	.kv-article-card .kv-article-card__text {
		padding: 0.75rem 1.25rem 0;
	}

	.kv-article-card > .wp-block-buttons {
		padding: 1rem 1.25rem 1.5rem;
	}

	.kv-blog-posts-card > .kv-blog-posts-card__actions {
		padding: 1rem 1.25rem 1.5rem;
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		transition-duration: 0.01ms !important;
		/* scroll-behavior vererbt nicht; die site-weite smooth-Regel auf
		 * html/body muss hier explizit auf auto zurückgesetzt werden,
		 * damit Ankersprünge instant landen. */
		scroll-behavior: auto !important;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Header — Figma navbar V1
 * ---------------------------------------------------------------------------
 * The tools row holds the search field plus a static DE|EN switcher with a
 * single vertical divider (`paper-25`) between the two language links.
 * Dropdown behaviour (toggle on click/focus, Escape to close, touch support)
 * is provided by the core navigation block through the Gutenberg interactive
 * API — these rules only style it.
 */

.kv-header-lang__separator {
	background: var(--wp--preset--color--paper-25);
	display: inline-block;
	flex: 0 0 auto;
	height: 1rem;
	width: 1px;
}

.kv-header-lang {
	align-items: center;
	display: inline-flex;
	gap: 0.625rem;
}

.kv-header-lang__link {
	color: var(--wp--preset--color--paper);
	font-size: 0.8rem;
	font-weight: 100; /* Nicht-aktive Sprache: ultra-dünn */
	letter-spacing: 0.08em;
	line-height: 1.4;
	text-decoration: none;
	text-transform: uppercase;
}

/* Aktuelle Sprache hervorgeben: fett, die andere bleibt dünn. */
.kv-header-lang__link.is-active {
	font-weight: 700;
}

/* Language-Switcher folgt demselben Background-Change-Modell (konsistent zu
 * ink/paper/tuerkis): Hover/Fokus = Background dunkelblau-75 #3F62AD, Text
 * paper bleibt, keine Textfarb-Änderung. Unterstreichung s. Top-Level-Regel. */
.kv-header-lang__link:hover,
.kv-header-lang__link:focus-visible {
	background: var(--wp--preset--color--dunkelblau-75);
}

.kv-header-nav .wp-block-navigation {
	align-items: flex-start;
	/* The core navigation reads this variable for the top-level menu row, so
	 * the item texts share one top line instead of being vertically centered. */
	--navigation-layout-align: flex-start;
}

.kv-header-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem); /* 15–17px, fluid (Fluid-Typo) */
}

@media (min-width: 920px) {
	/* Dropdown items are 56px tall, chevron 15x15 directly below the label.
	 * The label starts at the item top, so all first-level item texts sit on
	 * one line even though the items themselves stay 56px tall.
	 *
	 * Breakpoint-Umstellung 10.08. (Auftraggeber): Der Wechsel Inline ↔
	 * Overlay-Menü passiert seit diesem Fix bei 920px statt bei den 600px
	 * des Core-Navigation-Blocks. Die Desktop-Dropdown-Geometrie dieser Sektion
	 * (56px-Items, Chevron, ink-Panel rechtsbündig) gilt deshalb erst ab
	 * 920px; zwischen 600 und 920px läuft die Navigation als Overlay und die
	 * Core-Modal-Regeln (statische, gestapelte Submenüs) gelten ungestört. */
	.kv-site-header .kv-header-nav .wp-block-navigation-item.has-child {
		flex-direction: column;
		justify-content: flex-start;
		min-height: 56px;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-icon,
	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-icon svg {
		height: 15px;
		width: 15px;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-icon {
		margin: 0 0 0;
	}

	/* Submenu panel: same dark-ink panel and paper-25 item text as the
	 * top-level navbar items. Core navigation styles dropdowns with a white
	 * background and near-black text unless the nav block carries explicit
	 * color attributes (ours does not); both overrides are scoped to the
	 * header nav so the mobile overlay (<920px) and the footer navigation
	 * keep their defaults. The panel is right-aligned with its trigger and
	 * capped at the viewport width so dropdowns cannot cause horizontal
	 * scrolling. */
	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-container {
		background-color: var(--wp--preset--color--ink);
		border: 0;
		box-shadow: 0 1.25rem 2.5rem rgba(3, 14, 52, 0.45);
		color: var(--wp--preset--color--paper-25);
		gap: 0.125rem;
		left: auto;
		max-width: min(20rem, calc(100vw - 2.5rem));
		min-width: 17rem;
		padding: 0.625rem 0;
		right: 0;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content {
		color: var(--wp--preset--color--paper-25);
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content:hover {
		color: var(--wp--preset--color--signal);
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content:focus-visible {
		color: var(--wp--preset--color--signal);
		outline: 3px solid var(--wp--preset--color--signal);
		outline-offset: 4px;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-container
		> .wp-block-navigation-item:not(:last-child) {
		border-bottom: 1px solid rgba(252, 248, 236, 0.1);
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__submenu-container
		> .wp-block-navigation-item
		> .wp-block-navigation-item__content {
		padding: 0.6rem 1.25rem;
	}
}

/* ---------------------------------------------------------------------------
 * Mega-Menüs (Redesign 20.08.) — Primär-Navigation.
 *
 * Alle drei Top-Level-Dropdowns der Primär-Navigation ("Ressourcen",
 * "Aktiv werden", "Über uns") öffnen ab 920px als Vollflächen-Mega-Menü
 * statt als schmaler rechteckiger Ink-Panel-Dropdown:
 *
 * - Vollflächiger, viewportbreiter Hintergrund in Signal (#FFC04E) mit
 *   ink-Text (#052B8E, 7.4:1 AAA) — bewusst im Kontrast zum dunklen Ink-
 *   Header. Der Header ist selbst vollbreit (`.kv-site-header`) und trägt
 *   via `will-change: transform` (Sticky-Template-Part) einen Transform,
 *   der für `position: fixed`-Nachfahren einen eigenen Containing-Block
 *   bildet. Das nutzen wir: Das Panel wird `position: fixed` (an den
 *   Header gebunden und mitscrollend), sodass die Vollflächen-Dimension
 *   deterministisch am Header anliegt, unabhängig von der schmalen
 *   Positionierungs-Basis des `li` in der rechtsbündigen Navbar.
 * - Ein `::before` des Panels (absolut gegen das zentrierte, auf 1136px
 *   gedeckelte  `ul`) spannt die Signal-Fläche über die volle Viewportbreite
 *   (`left:50%; width:100vw; transform:translateX(-50%)` — das klassische
 *   Viewport-Zentrier-Trick, gültig, weil der Offset-Parent horizontal
 *   zentriert ist). Der `ul`-Kasten selbst bleibt auf die 1136px-Content-
 *   Spalte gedeckelt und zentriert, sodass Titel und Raster exakt mit dem
 *   restlichen Header fluchten.
 * - Menüname (Titel) links oben im Panel über `::after` pro Menu.
 * - 2-spaltiges Raster (CSS-Grid) für alle Einträge. Alle Items sind flache,
 *   direkte Grid-Kinder; der 3-Ebenen-Eintrag ("Profilbild erstellen") trägt
 *   die Klasse `kv-lvl3` und belegt so die 6. Zelle unten rechts, direkt
 *   unter seinem Gruppen-Eintrag "Verbreite unsere Vision" im selben Column.
 *   Damit bleibt das Raster stets ausgewogen (3×2, kein Leer-Quadrant, kein
 *   Leerraum unterhalb eines kürzeren Labels).
 * - Pfeil-Präfixe: kurzer Pfeil vor jedem Eintrag der 2. Ebene, längerer
 *   Pfeil (+ kleine Einkerbung) vor dem 3-Ebenen-Eintrag `kv-lvl3`.
 *
 * Scoping: Alles hängt am Klasse `.kv-mega-nav` des Navigations-Blocks;
 * klassengebundene Panel-Selektoren (`li.kv-mega-ressourcen/aktiv/ueber >
 * .wp-block-navigation__submenu-container`) treffen NUR die drei Mega-
 * Panels. Der Mobile-Overlay (< 920px) und die Footer-Navigation bleiben
 * unberührt.
 *
 * Bedienung: Öffnen/Schließen übernimmt weiterhin der Core-Navigation-
 * Mechanismus (`:hover`/`:focus-within` des Top-Level-Items togglet
 * `visibility`/`opacity` des Panels) — es wird nicht klick-exklusiv und
 * nicht dauerhaft offen. Escape, Chevron-Toggle und `:focus-within` der
 * Top-Level-Items bleiben wie gehabt.
 *
 * Hover/Fokus auf Signal: Normal ink. Hover/Fokus nutzen als klare
 * Affordanz eine ink-Unterstreichung (+ ink-Outline im Fokus). Die im
 * Invert-Header verwendete dunkelblau-75 (#3F62AD) erreicht auf Signal
 * nur 3.62:1 (scheitert am 4.5:1-AA für Fließtext); ink bleibt auf Signal
 * bei 7.4:1 (AAA), daher Text immer ink und die Interaktionsmarkierung als
 * Unterstreichung/Ring in ink statt über eine hellere Farbe. Ein sichtbarer
 * `:focus-visible`-Ring in ink kontrastiert auf Signal (7.4:1).
 * ------------------------------------------------------------------------- */
/* Unter 920px rendert der Core-Overlay das Top-Level-Label selbst; der
 * Titel-Anker im Panel wäre dort eine Doppelung und bleibt ausgeblendet
 * (die Desktop-Regel im Media-Block unten hebt das Hide wieder auf). */
.kv-site-header .kv-mega-nav li.wp-block-navigation-item.kv-mega-title {
	display: none;
}

@media (min-width: 920px) {
	/* --- Panels: Vollflächen-Dropdown an den Header gebunden -------- */
	.kv-mega-nav li.kv-mega-ressourcen > .wp-block-navigation__submenu-container,
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container,
	.kv-mega-nav li.kv-mega-ueber > .wp-block-navigation__submenu-container {
		background-color: transparent; /* Signal liegt über ::before, s. u. */
		bottom: auto;                  /* Höhe aus dem Inhalt (Raster) */
		box-sizing: border-box;
		border: 0;
		box-shadow: none;
		display: grid;                 /* 2-spaltiges Raster, s. u. */
		gap: 0.25rem 2.5rem;
		grid-auto-flow: row;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		height: auto;                  /* s. o.: sonst kollabiert der Kasten */
		left: 0;
		right: 0;
		margin: 0;
		max-width: none;
		/* Das Panel selbst ist vollbreit (`width:100vw` mit `left/right:0`),
		 * sodass der komplette sichtbare Signal-Bereich zur Hover-Verankerung
		 * zählt (kein Schließen mehr an den äußeren Rändern außerhalb der
		 * 1136px-Content-Spalte). Der Inhalt bleibt über das spiegelsymmetrische
		 * horizontale Padding an die 1136px-Spalte des Headers gebunden:
		 * `(100vw - 1136px) / 2` zentriert, plus 1.5rem innerer Abstand. Das
		 * löst an 1440px zu 152px + 24px = 176px auf, identisch zum vorherigen
		 * `clamp(1rem, 2vw, 1.5rem)` auf dem 1136px-Kasten. */
		padding: 1rem max(1.5rem, calc((100vw - 1136px) / 2 + 1.5rem)) 1.5rem;
		position: fixed;
		top: 8rem;                      /* knapp unter der Navbar-Zeile */
		width: 100vw;
		z-index: 5;
	}

	/* Barrierefreiheit & Öffnen-ohne-Bestätigung:
	 *
	 * Das Panel öffnet ausschließlich
	 *   (a) per `:hover` auf Geräten mit echtem Hover (Desktop/Maus) und
	 *   (b) per expliziter Aktivierung via `.is-open` — gesetzt vom Chevron-
	 *       Toggle (Touch/Tablet) bzw. von mega-menu-keyboard.js bei ArrowDown
	 *       auf dem Top-Level-Link (Desktop-Tastatur).
	 *
	 * Reine Tastatur-Fokussierung (Tab) des Top-Level-Links öffnet das Panel
	 * bewusst NICHT mehr (kein `:focus-within` / `:has(:focus-visible)` mehr).
	 * Solange das Panel `visibility: hidden` ist, sind seine Einträge aus der
	 * Tab-Reihenfolge genommen — Tab springt also direkt zum nächsten
	 * Navbar-Item statt in das Panel. Erst die explizite Bestätigung (z. B.
	 * ArrowDown) macht das Panel sichtbar und damit tabbar.
	 *
	 * Die `.is-open`-Regel steht bewusst AUBERHALB der Medium-Abfragen:
	 * Ein per ArrowDown geöffnetes Desktop-Panel muss sichtbar bleiben, solange
	 * der Fokus INNEN liegt, auch wenn die Maus (kein `:hover` mehr anliegt)
	 * das `li` verlassen hat. Auf Touch-Geräten gilt sie genauso für den
	 * Chevron-Toggle. */
	.kv-mega-nav li.kv-mega-ressourcen > .wp-block-navigation__submenu-container.is-open,
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container.is-open,
	.kv-mega-nav li.kv-mega-ueber > .wp-block-navigation__submenu-container.is-open {
		opacity: 1;
		visibility: visible;
	}

	@media (hover: hover) {
		/* Nur Maus-Hover öffnet das Panel. `:focus-within` wird weggelassen,
		 * damit reine Tastatur-Fokussierung das Panel nicht sichtbar macht.
		 * Ein von ArrowDown / Chevron geöffnetes Panel hält `.is-open`
		 * (gemeinsame Regel oben) die Sichtbarkeit. */
		.kv-mega-nav li.kv-mega-ressourcen:hover > .wp-block-navigation__submenu-container,
		.kv-mega-nav li.kv-mega-aktiv:hover > .wp-block-navigation__submenu-container,
		.kv-mega-nav li.kv-mega-ueber:hover > .wp-block-navigation__submenu-container {
			opacity: 1;
			visibility: visible;
		}
	}

	@media (hover: none) {
		/* Grobzeigige Geräte (Tablet/Touch): KEIN `:hover`-Öffnen. Ein nach
		 * dem Antippen verbleibendes `li:hover` darf das Panel nicht festhalten.
		 * Öffnen/Schließen steuert hier der Chevron-Toggle über die `.is-open`-
		 * Klasse (gemeinsame Regel oben): Beim Antippen setzt Core `.is-open`
		 * (Panel sichtbar), beim erneuten Antippen wird es entfernt — und weil
		 * kein `:hover` das Panel offen hält, fällt es zuverlässig auf
		 * `visibility: hidden` zurück. */
	}

	/* Vollflächiger Signal-Hintergrund: absoluter Pseudo-Layer gegen das
	 * (horizontal bereits zentrierte) `ul`; `left:50%; width:100vw;
	 * translateX(-50%)` spannt exakt die volle Viewportbreite. */
	.kv-mega-nav li.kv-mega-ressourcen > .wp-block-navigation__submenu-container::before,
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container::before,
	.kv-mega-nav li.kv-mega-ueber > .wp-block-navigation__submenu-container::before {
		background-color: var(--wp--preset--color--signal);
		content: "";
		left: 50%;
		position: absolute;
		right: auto;
		top: 0;
		bottom: 0;
		transform: translateX(-50%);
		width: 100vw;
		max-width: 100vw;
		z-index: -1;
	}

	/* --- Menütitel (oben links im Panel) ------------------------------ */
	/* Der Titel ist jetzt ein echter Link (`li.kv-mega-title` als erste
	 * Raster-Zeile, von parts/header.html) und damit klickbar auf die
	 * Ziel-Seite (/ressourcen/, /aktiv-werden/, /ueber-uns/). Er spannt
	 * beide Spalten; die Einträge rücken automatisch darunter. Look wie der
	 * bisherige ::after-Titel: ink auf Signal (7.4:1 AAA), 17px, Caps mit
	 * Letter-Spacing. Die Spezifität (0,5,2) hält die Regel über den
	 * Eintrag-Regeln unten (Gewichtung/Padding), Hover-Unterstreichung und
	 * Fokus-Ring erben die Titel-Zeile von denselben. */
	.kv-mega-nav li[class*="kv-mega-"] > .wp-block-navigation__submenu-container > li.kv-mega-title {
		display: block; /* gegen das Overlay-Hide oben; die höhere Spezifität (0,5,2) gewinnt */
		grid-column: 1 / -1;
	}

	.kv-mega-nav li[class*="kv-mega-"] > .wp-block-navigation__submenu-container > li.kv-mega-title > .wp-block-navigation-item__content {
		color: var(--wp--preset--color--ink); /* 7.4:1 AAA auf Signal */
		font-size: 1.0625rem; /* 17px */
		font-weight: 700;
		letter-spacing: 0.08em;
		padding: 0.25rem 0 0.75rem;
		text-transform: uppercase;
	}

	/* --- Einträge: ink auf Signal, Hover/Fokus ink + Unterstreichung --- */
	.kv-mega-nav li.kv-mega-ressourcen > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content,
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content,
	.kv-mega-nav li.kv-mega-ueber > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content {
		align-items: center;
		color: var(--wp--preset--color--ink); /* 7.4:1 AAA auf Signal */
		display: inline-flex;
		font-weight: 600;
		padding: 0.625rem 0.25rem;
		text-decoration: none;
		text-underline-offset: 0.25em;
	}

	.kv-mega-nav li.kv-mega-ressourcen > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content:hover,
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content:hover,
	.kv-mega-nav li.kv-mega-ueber > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content:hover {
		color: var(--wp--preset--color--ink);
		text-decoration: underline;
	}

	.kv-mega-nav li.kv-mega-ressourcen > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content:focus-visible,
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content:focus-visible,
	.kv-mega-nav li.kv-mega-ueber > .wp-block-navigation__submenu-container
		.wp-block-navigation-item__content:focus-visible {
		color: var(--wp--preset--color--ink);
		outline: 3px solid var(--wp--preset--color--ink);
		outline-offset: 3px;
		text-decoration: underline;
	}

	/* --- Pfeil-Präfixe (kurz = Ebene 2) ------------------------------- */
	/* Die flachen Zellen des "Aktiv werden"-Panels sind alle direkte Grid-
	 * Kinder; nur der 3-Ebenen-Eintrag "Profilbild erstellen" trägt die Klasse
	 * `kv-lvl3` und bekommt stattdessen den langen Pfeil (Regel unten). Die
	 * `:not([class*="kv-lvl3"])` greift deshalb zusätzlich zu der bestehenden
	 * `:not([class*="kv-mega-"])`-Bedingung (die die Panel-Klassen ausschließt). */
	.kv-mega-nav li.kv-mega-ressourcen > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item:not([class*="kv-mega-"]):not([class*="kv-lvl3"]) > .wp-block-navigation-item__content::before,
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item:not([class*="kv-mega-"]):not([class*="kv-lvl3"]) > .wp-block-navigation-item__content::before,
	.kv-mega-nav li.kv-mega-ueber > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item:not([class*="kv-mega-"]):not([class*="kv-lvl3"]) > .wp-block-navigation-item__content::before {
		content: "";
		display: inline-block;
		width: 0.55rem;
		height: 0.5rem;
		margin-right: 0.5rem;
		background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2012%2010%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%23052B8E%22%20stroke-width%3D%222%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M0.5%205h6%22%2F%3E%3Cpath%20d%3D%22M6.5%200.5L11%205l-4.5%204.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
		background-repeat: no-repeat;
		background-position: left center;
		background-size: 0.55rem 0.5rem;
	}

	/* --- 3. Ebene = eigene flache Raster-Zelle ("Profilbild erstellen") - */
	/* Seit der Flachlegung ist jeder Eintrag des "Aktiv werden"-Panels ein
	 * direktes Grid-Kind. "Profilbild erstellen" trägt die Klasse `kv-lvl3`
	 * und belegt als 6. Zelle die letzte Raster-Position unten rechts, direkt
	 * unter "Verbreite unsere Vision" (also kein Leer-Quadrant und kein
	 * 42px-Leerraum mehr). Die Ausrichtung zeigt alle Zellen an der
	 * Oberkante, damit ein Label nie vertikal hängt, wenn die Zeilen-
	 * Pendants kürzer/länger sind. Bewusst auf `li.kv-mega-aktiv` gescoped,
	 * damit Ressourcen/Über uns (alle flachen Ebene-2-Items ohne `kv-lvl3`)
	 * unberührt bleiben. */
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item {
		align-items: flex-start;
	}

	/* Längerer Pfeil vor dem 3-Ebene-Eintrag ("Profilbild erstellen") als
	 * visueller Hinweis auf die Unter-Ebene; der Kurzpfeil greift dort nicht,
	 * denn die Kurzpfeil-Regel schließt `[class*="kv-lvl3"]` aus. */
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item.kv-lvl3
		> .wp-block-navigation-item__content::before {
		content: "";
		display: inline-block;
		width: 0.9rem;
		height: 0.41rem;
		margin-right: 0.75rem;
		background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2022%2010%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%23052B8E%22%20stroke-width%3D%222.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M1%205h16%22%2F%3E%3Cpath%20d%3D%22M17%200.5L21.5%205l-4.5%204.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
		background-repeat: no-repeat;
		background-position: left center;
		background-size: 0.9rem 0.41rem;
	}

	/* Klare Einkerbung für "Profilbild erstellen", damit es als Unter-
	 * Eintrag von "Verbreite unsere Vision" im selben Column lesbar bleibt
	 * (zusätzlich zum langen Pfeil). `2.5rem` (40px) ist bewusst LARGER als
	 * die `20px`-Padding der flachen Ebene-2-Items, sodass der Text des
	 * 3-Ebenen-Eintrags merklich rechts von seinen 2-Ebenen-Geschwistern
	 * und seinem Parent beginnt. */
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item.kv-lvl3
		> .wp-block-navigation-item__content {
		padding-left: 2.5rem;
	}

	/* --- Trenner zwischen den Einträgen (flaches Raster) ---------------- */
	.kv-mega-nav li.kv-mega-ressourcen > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item:not(:last-child),
	.kv-mega-nav li.kv-mega-aktiv > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item:not(:last-child),
	.kv-mega-nav li.kv-mega-ueber > .wp-block-navigation__submenu-container
		> .wp-block-navigation-item:not(:last-child) {
		border-bottom: 0; /* flaches Raster ohne Trennlinien */
	}
}

@media (max-width: 600px) {
	.kv-header-bar {
		flex-wrap: wrap !important;
		gap: 0.75rem;
	}

	.kv-header-tools {
		flex-wrap: wrap !important;
		width: 100%;
	}

	.kv-header-tools .wp-block-search {
		flex: 1 1 100%;
		order: 1;
	}

	.kv-site-header .kv-header-tools .wp-block-search__inside-wrapper {
		width: 100% !important;
	}

	.kv-header-lang {
		margin-top: 0.25rem;
		order: 2;
	}

	.kv-site-header .kv-header-logo svg {
		width: 200px;
	}
}

/*
 * Navigation-Breakpoint 920px (Umsetzung 10.08., Auftraggeber-Vorgabe).
 *
 * Der Core-Navigation-Block wechselt mit `overlayMenu:"mobile"`
 * (parts/header.html) intern bei 600px zwischen Inline-Menü (≥600px) und
 * Overlay-Toggle (<600px). Das Theme verschiebt diese Schwelle per
 * scoped CSS auf 920px, ohne Core-Dateien oder das Block-Markup zu
 * berühren:
 *
 * - <920px (dieser Block): Der Inline-Container des Core-Blocks
 *   (`.wp-block-navigation__responsive-container`) wird ausgeschaltet,
 *   der Toggle-Button (`.wp-block-navigation__responsive-container-open`)
 *   wird sichtbar. Im offenen Zustand greift unverändert das Core-Modal
 *   (fixed full-screen, `has-modal-open`/`is-menu-open`, Escape schließt,
 *   `html.has-modal-open` sperrt den Seiten-Scroll) — dieselbe Mechanik,
 *   die bereits unter 600px läuft. Die Regeln sind mit
 *   `:not(.is-menu-open)` gebaut, damit der offene Modal-Zustand nie mit
 *   der Closed-Ansicht kollidiert.
 * - ≥920px (folgender Block): Defensiv-Pin des Desktop-Zustands — Core
 *   liefert ihn seit ≥600px ohnehin, die Regeln machen die Schwelle
 *   explizit und sichern sie gegen die Media-Query-Spezifität ab. Der
 *   Toggle bleibt unsichtbar, der Container steht statisch im Flow.
 *
 * Spezifität: Die Selectoren übertreffen die Core-Regeln aus
 * `wp-block-library/navigation` (z. B. `:not(.hidden-by-default):not(.is-menu-open)`
 * mit 0,3,0) und gewinnen die Kaskade unabhängig von der Einbindungsreihen-
 * folge (Gutenberg-Stylesheet lädt vor style.css). Die 782px-/600px-Regeln
 * für Logo, Rows und Footer und die `@media (min-width: 920px)`-Logo-Regeln
 * (margin-top -12px) bleiben unangetastet.
 */
@media (max-width: 919px) {
	.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open {
		display: flex;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container-open {
		display: flex;
	}

	/* Korrektur 10.08.: Das Core-Icon des Mobile-Toggles rendert bei 24px
	 * nur zwei Balken (Nav-Icon "small"). Der Toggle bekommt ein 3-Balken-
	 * Icon aus currentColor (Steuerung über das bereits wiederverwendete
	 * ::before), damit der Burger wie ein klassisches Hamburger-Menü
	 * aussieht. Die drei Balken liegen bei top 5/12/19 mit 2px Dicke in
	 * der Box; Fokus-Ring und aria-label des Core-Buttons bleiben
	 * unangetastet. Auf dem invertierten (hellen) Header ist currentColor
	 * ink, auf dem dunklen Header paper — keine Varianten-Regeln nötig.
	 * Die expliziten Maße sind nötig, weil ::before absolut positioniert
	 * ist (nichts Inline mehr) und der Toggle sonst auf 0×0 kollabiert. */
	.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container-open {
		height: 24px;
		position: relative;
		width: 24px;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container-open::before {
		background: currentColor;
		box-shadow: 0 7px 0 currentColor, 0 14px 0 currentColor;
		content: "";
		height: 2px;
		left: 3px;
		position: absolute;
		top: 5px;
		width: 18px;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container-open svg {
		display: none;
	}
}

@media (min-width: 920px) {
	.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container-open {
		display: none;
	}

	.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: block;
		position: relative;
	}

	/* Korrektur 10.08.: Die über functions.php in das Overlay-Container-
	 * Surface eingefügten Mobile-Menü-Bausteine (Marken-Band, Suche + Sprache,
	 * Spenden-Button) werden vom Container ≥920px als statischer Inline-Block
	 * mitgerendert und hätten die Desktop-Zeile mit einem zweiten Header,
	 * Suchfeld und Spenden-Button aufgebläht. Ab der Desktop-Schwelle werden
	 * sie deshalb ausgeblendet; der Spenden-Button der Desktop-Zeile hat
	 * danach wieder seine volle Breite (Korrektur gegen den 7-zeiligen
	 * Umbruch des Labels und ein zusätzliches white-space: nowrap). */
	.kv-site-header .kv-header-nav .kv-mobile-menu__head,
	.kv-site-header .kv-header-nav .kv-mobile-menu__tools,
	.kv-site-header .kv-header-nav .kv-mobile-menu__footer {
		display: none;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Mobile-Overlay-Menü — Marken-Kopf, Suchzeile, Spenden-Button
 * ---------------------------------------------------------------------------
 * Die Elemente werden von `klima_vor_acht_mobile_menu_extras()` in
 * functions.php beim Rendern des Header-Navigationsblocks in das Core-Modal
 * (`.wp-block-navigation__responsive-container-content`) geschrieben. Das
 * Modal ist ein fixiertes, weißes Vollbild-Dialogfenster; diese Regeln geben
 * ihm die Marken-Optik: obere Ink-Band mit Logo, Suchfeld + DE|EN-Umschalter
 * (Ink auf Paper), darunter die Navigationspunkte, am Ende der Spenden-
 * Button. `.kv-header-logo` und die Such-Klassen wiederverwenden die
 * bestehenden Header-Regeln; der Umschalter bekommt eigene Klassen, weil die
 * Header-Lang-Regal auf dunklem Grund (Paper-Text) liegt. Beide Header-
 * Varianten (Regel- und Inverted-Seiten) teilen dieses weiße Modal, deshalb
 * keine `kv-header-inverted`-Override nötig.
 */
/* Redesign 19.08.: Das Overlay ist jetzt ein Vollbild-Menü mit dunklem
 * Ink-Hintergrund und hellem Paper-Text statt des früheren weißen Modals.
 * Core erzwingt auf dem Overlay `background: #fff` (0,5,0) und `color: #000`
 * (0,5,0); die Regeln hier liegen gezielt spezifischer (0,6,0) und gewinnen
 * die Kaskade. Die Nav-Einträge erben Paper über das Container-`color`
 * (Core setzt auf Container/Einträge `color: inherit !important`). */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open {
	background-color: var(--wp--preset--color--ink) !important;
	color: var(--wp--preset--color--paper) !important;
}

/* Defensiv-pin der Linkfarben im Overlay: Einträge erben Paper über das
 * Container-`color` (Core: `color: inherit !important`), ein expliziter
 * Paper-Wert auf den Links macht sie zusätzlich unabhängig von Kettenbrüchen
 * der Farbvererbung sichtbar (12.26:1 AAA auf Ink). */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item__content {
	color: var(--wp--preset--color--paper);
	/* Größere Schrift im Mobile-Menü (Top-Level): größere Touch-Targets
	 * und bessere Lesbarkeit als der Desktop-Header. Die Untermenü-Einträge
	 * bekommen weiter unten eine eigene (etwas kleinere) Größe. */
	font-size: clamp(1rem, 3.2vw, 1.0625rem); /* 16–17px */
}

/* Top-Level-Hover im Overlay: signal wie im Desktop-Header. Muss höher
 * spezifisch liegen als die explizite Paper-Regel oben, sonst würde der
 * Hover-Zustand dort untergehen. (Untermenü-Hover signalisiert weiterhin
 * über die eigene Regel weiter unten.) */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item__content:hover,
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--signal);
}

.kv-mobile-menu__head {
	align-items: center;
	background-color: var(--wp--preset--color--ink);
	box-sizing: border-box;
	display: flex;
	justify-content: center;
	line-height: 0;
	padding: 0.875rem 1.25rem 0; /* unteres Padding 0, der 24px-Content-Gap übernimmt den Abstand zur Suche */
	width: 100%;
}

.kv-mobile-menu__head .kv-header-logo {
	display: inline-flex;
	line-height: 0;
	text-decoration: none;
}

.kv-mobile-menu__head .kv-header-logo__img {
	display: block;
	height: auto;
	width: 250px;
}

.kv-mobile-menu__tools {
	align-items: center;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: 1.5rem; /* 24px → Abstand Suche→Sprache */
	width: 100%;
}

.kv-mobile-menu__tools .kv-mobile-menu__search {
	width: min(100%, 320px);
}

.kv-mobile-menu__tools .wp-block-search__inside-wrapper {
	background: var(--wp--preset--color--ink);
	border: 1.5px solid var(--wp--preset--color--white); /* wie Secondary-Button */
	border-radius: 8px; /* abgerundete Ecken */
	padding: 0;
	width: 100% !important;
}

/* Mobile-Suchfeld im Secondary-Button-Look: Ink-Fill, weiße Border, weißer
 * Text. Der Input ist transparent (Ink scheint durch den Wrapper durch),
 * Plugin/Footer-Hintergründe des Headers sind hier bewusst nicht geerbt. */
.kv-mobile-menu__tools .wp-block-search__input {
	background: transparent;
	color: var(--wp--preset--color--white);
	font-size: clamp(1rem, 3.2vw, 1.0625rem); /* wie die Mobile-Menü-Punkte */
	padding: 0 0.6rem;
}

.kv-mobile-menu__tools .wp-block-search__input::placeholder {
	color: rgba(255, 255, 255, 0.65);
}

.kv-mobile-menu__tools .wp-block-search__button {
	background: var(--wp--preset--color--ink);
	border-left: 1px solid rgba(255, 255, 255, 0.35);
	border-radius: 0 7px 7px 0; /* passt zum 8px-Radius des Felds */
	color: var(--wp--preset--color--white);
}

.kv-mobile-menu__lang {
	align-items: center;
	display: inline-flex;
	gap: 0.625rem;
	/* Optische Ausrichtung zur Suchzeile darüber: Der Platzhaltertext im
	 * Suchfeld startet erst nach dem 1px-Wrapper-Rahmen plus dem
	 * Input-Innenabstand (0.6rem). Ohne diesen linken Abstand säße „DE"
	 * bündig an der Feldkante und wirkte im Vergleich zum Platzhalter
	 * nach links verschoben. */
	padding-left: calc(0.6rem + 1px);
}

.kv-mobile-menu__lang .kv-mobile-menu__lang-link {
	color: var(--wp--preset--color--paper);
	font-size: clamp(1rem, 3.2vw, 1.0625rem); /* wie die Mobile-Menü-Punkte */
	font-weight: 100; /* Nicht-aktive Sprache: ultra-dünn */
	letter-spacing: 0.08em;
	line-height: 1.4;
	text-decoration: none;
	text-transform: uppercase;
}

/* Aktuelle Sprache hervorgeben: fett, die andere bleibt regulär. */
.kv-mobile-menu__lang .kv-mobile-menu__lang-link.is-active {
	font-weight: 700;
}

.kv-mobile-menu__lang .kv-mobile-menu__lang-link:hover,
.kv-mobile-menu__lang .kv-mobile-menu__lang-link:focus-visible {
	color: var(--wp--preset--color--signal);
}

.kv-mobile-menu__lang .kv-mobile-menu__lang-sep {
	background: var(--wp--preset--color--paper);
	display: inline-block;
	flex: 0 0 auto;
	height: 0.75rem;
	opacity: 0.35;
	width: 1px;
}

.kv-mobile-menu__footer {
	box-sizing: border-box;
	display: flex;
	justify-content: center;
	width: 100%;
}

/* Spenden-Button als regulärer Secondary-Button (nicht mehr vollblütig und
 * auch nicht volle Breite): Ghost auf Ink — Paper-Border/-Text, im Hover
 * #FFF-Fill mit ink-Text. Entspricht der Systemvariante secondary-paper /
 * header-ghost, aber mit normaler Buttongröße (Secondary-Geometrie:
 * 0.5rem/1rem) statt der kompakten Header-Variante. */
.kv-mobile-menu__donate {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--paper);
	border-radius: 8px;
	box-sizing: border-box;
	color: var(--wp--preset--color--paper);
	display: inline-block;
	font-size: clamp(1rem, 3.2vw, 1.0625rem); /* gleiche große Schrift wie im Mobile-Menü */
	font-weight: 600;
	letter-spacing: 0.02em;
	padding: 0.5rem 1rem;
	text-align: center;
	text-decoration: none;
	width: auto;
}

.kv-mobile-menu__donate:hover,
.kv-mobile-menu__donate:focus-visible {
	background: var(--wp--preset--color--white);
	border-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

@media (max-width: 919px) {
	.kv-mobile-menu__head,
	.kv-mobile-menu__tools,
	.kv-mobile-menu__footer {
		padding-inline: 1.25rem;
	}
}

/*
 * Abstand des Mobile-Menüs vom oberen Modal-Rand.
 *
 * Der Schließen-Button der Core-Navigation ist absolut oben rechts im
 * Dialog positioniert (unabhängig vom Inhalt). 80px padding-top auf den
 * Inhalts-Container schieben deshalb alles GESCHLOSSENE (Logo-Bar, Suche,
 * Sprache, Navigation, Spenden-Button) um 80px nach unten — nur der
 * Schließen-Button bleibt oben stehen. Der Button wird dabei in Paper
 * gehalten und rechtsbündig ausgerichtet, sodass er auf der Ink-Fläche
 * lesbar bleibt (das Icon zeichnet `currentColor`); der Fokus-Ring
 * (globale signal-Outline) bleibt sichtbar auf Ink. */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-content {
	gap: 1.5rem; /* 24px zwischen den Abschnitten (Logo→→Footer) */
	padding-top: 80px;
}

.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-close {
	/* Fokus-Ring muss auf Ink lesbar bleiben; der globale signal-Fokus
	 * (3px Outline, 4px Offset) liegt 4px außerhalb des Buttons. */
	color: var(--wp--preset--color--paper);
	right: 1.25rem;
	top: 0.875rem; /* bleibt oben, unabhängig vom 80px-Inhalt-Padding */
}

/* Navigations-Liste im offenen Overlay zentrieren und deckeln.
 *
 * Die Header-Regel `.kv-header-nav .wp-block-navigation { margin-left:
 * auto }` zielt auf die Desktop-Zeile, matcht aber auch das innere
 * `ul.wp-block-navigation__container` (trägt selbst die Klasse
 * `wp-block-navigation`) im offenen Modal: das auto-Margin schiebt die
 * Liste im flex-column-Container nach rechts, auf breiteren Mobil-
 * Viewports (z. B. 540px) klebt sie dadurch am rechten Rand. Innerhalb
 * des Overlays wird das aufgehoben: die Liste bekommt max-width 320px
 * und auto-Margins auf beiden Seiten, zentriert sie also als Ganzes.
 *
 * Der Box allein sieht man das aber nicht an: Die Einträge sind in der
 * 320px-Spalte standardmäßig linksbündig, der Textblock rückt dadurch
 * visuell aus der Mitte (die kurzen Top-Level-Labels starten auf einer
 * Linie, während rechts Leerraum bleibt). Deshalb zentriert die Spalte
 * auch ihre Einträge selbst: `align-items: center` auf der Liste
 * (Flex-Spalte) zentriert die `<li>`-Zeilen, auf den Einträgen selbst
 * zentriert es deren Inhalt (Label und ausgeklapptes Untermenü), und auf
 * den Untermenü-Containern deren Einträge. So liegt jeder Menüpunkt als
 * Ganzes mittig in der 320px-Spalte. */
/* Die Nav-Spalte ist seit 19.08. zentriert, aber nicht mehr auf 320px
 * gedeckelt: Lange Untermenü-Labels (z. B. „Transparenz über Klimaberich-
 * erstattung") sollen fast die volle verfügbare Breite nutzen dürfen und
 * nicht in einer 320px-Spalte umbrechen. `width: 100%` nutzt die Content-
 * Breite des Modals (abzüglich Padding); der großzügige max-width-Fallback
 * ist bei sehr breiten Tablets sogar noch breiter als der Content. */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container {
	align-items: center;
	margin-inline: auto;
	max-width: 44rem; /* reicht über jede Mobile-/Tablet-Breite hinaus */
	width: 100%;
}

.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container > .wp-block-navigation-item {
	align-items: center;
	width: 100%;
}

/* Redesign 19.08. — Untermenüs standardmäßig zugeklappt, öffnen über
 * Chevron-Toggle; keine Panels mehr.
 *
 * Früher lagen die Untermenü-Einträge als gerundete Paper-Tiles auf dem
 * weißen Modal. Das neue Ink-Vollbild braucht keine Panels mehr: Die Kind-
 * Einträge sitzen direkt auf dem Ink-Hintergrund, nur leicht eingerückt,
 * um die Zugehörigkeit zum Top-Level-Label zu zeigen.
 *
 * Zugeklappt ist der Standard: Core erzwingt im Overlay `visibility:
 * visible` auf dem Untermenü-Container (0,5,0). Das wird hier mit höherer
 * Kaskadendichte überschrieben — `display: none`, solange keine `.is-open`-
 * Klasse hängt. Der Chevron-Toggle (Core-`.wp-block-navigation-submenu__
 * toggle`, im Overlay sonst per `display: none` versteckt) wird wieder
 * eingeblendet und dreht sich im offenen Zustand nach oben. Das Toggeln
 * der Zustandsklasse übernimmt assets/js/mobile-menu.js (blockiert dort
 * die Core-Interactivity, damit `.is-open` und aria-expanded konsistent
 * bleiben).
 *
 * Spezifität: Die Selectoren starten mit `.kv-site-header .kv-header-nav
 * .wp-block-navigation__responsive-container.is-menu-open` (0,4,0) plus
 * Element-Pfad (≥0,6,0) und liegen damit über den Core-Overlay-Regeln. */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item.has-child
	.wp-block-navigation__submenu-container {
	display: none; /* Standard: zugeklappt (keine `.is-open`-Klasse) */
}

.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item.has-child
	.wp-block-navigation__submenu-container.is-open {
	align-items: center; /* Untermenü-Einträge mittig, wie die Top-Level */
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	margin-top: 0.125rem;
	padding: 0;
	width: 100%;
}

/* Mobile-Menü: Der Elternpunkt wird zur Spalte Label → Untermenü → Chevron.
 * Der Toggle kommt per `order` NACH das Untermenü, sodass der Chevron beim
 * geöffneten Zustand UNTER den Kind-Einträgen sitzt (Schließen-Pfeil);
 * zugeklappt (Untermenü ausgeblendet) liegt er direkt unter dem Label.
 * Alle drei Kinder sind mittig ausgerichtet. */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item.has-child {
	align-items: center;
	flex-direction: column;
	width: 100%;
}

.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item.has-child > .wp-block-navigation-item__content {
	order: 1;
}

.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item.has-child > .wp-block-navigation__submenu-container {
	order: 2;
}

.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item.has-child > .wp-block-navigation-submenu__toggle {
	order: 3;
}

/* Chevron-Toggle eines Elternpunkts einblenden (Core blendet ihn im
 * Overlay aus) und zusammen mit dem Label mittig ausrichten. Core gibt dem
 * Icon `width: 0.6em` und dem SVG `width: inherit`; sobald der Toggle durch
 * `display: inline-flex` ein Flex-Container wird, schrumpft das SVG dank
 * Flex-Shrink auf ~1px und der Pfeil ist unsichtbar. Deshalb erhalten Toggle
 * und SVG hier explizite Abmessungen und `flex: none` gegen das Schrumpfen;
 * Paper-`currentColor` zeichnet die Pfeillinie. */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-submenu__toggle {
	align-items: center;
	align-self: center;
	box-sizing: border-box;
	color: var(--wp--preset--color--paper);
	display: inline-flex;
	flex: none;
	height: 1.25rem; /* 20px Tap-Zone */
	justify-content: center;
	margin: 0.5rem 0 0; /* Abstand zum (Unter-)Menü darüber */
	padding: 0;
	width: 1.25rem;
}

.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-submenu__toggle svg {
	flex: none;
	height: 0.875rem; /* 14px, gut sichtbar neben dem Label */
	margin-top: 0;
	width: 0.875rem;
}

/* Chevron-Rotation über den Zustand des Untermenü-Containers statt über
 * Core-aria-expanded (das die Interactivity überschreiben kann): im offenen
 * Zustand zeigt der Pfeil nach oben. */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item.has-child:has(> .wp-block-navigation__submenu-container.is-open)
	> .wp-block-navigation-submenu__toggle svg {
	transform: rotate(180deg);
}

/* Hierarchie: Untermenü-Einträge als Unterebene kennzeichnen — gleiche
 * Größe wie die Top-Level, aber super-dünn (font-weight: 100), Paper auf
 * Ink (12.26:1 AAA). Lange Labels dürfen in der mittigen Spalte umbrechen
 * (`white-space: normal`), damit nichts aus dem Fenster läuft. Keine
 * Panel-Tile mehr. */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__submenu-container
	.wp-block-navigation-item__content {
	color: var(--wp--preset--color--paper); /* 12.26:1 AAA auf Ink */
	font-size: clamp(1rem, 3.2vw, 1.0625rem); /* gleiche Größe wie Top-Level */
	font-weight: 100; /* super-dünn */
	padding: 0.375rem 0.25rem;
	/* Lange Labels wie „Transparenz über Klimaberichterstattung" bleiben auf
	 * einer Zeile — die (jetzt nicht mehr 320px-begrenzte) Spalte gibt ihnen
	 * fast die volle Modal-Breite. Bei extrem langen Labels, die selbst das
	 * verfehlen, darf es umbrechen statt überzulaufen. */
	white-space: nowrap;
}

.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__submenu-container
	.wp-block-navigation-item__content:hover,
 .kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__submenu-container
	.wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--signal);
}

/* Mobile-Overlay: 3. Ebene (Einträge der Klasse `kv-lvl3`) von den
 * 1./2.-Ebene-Einträgen unterscheiden — langer Rechtspfeil `⟶` (Paper-
 * currentColor-SVG) als Präfix, ohne Indent. Die Overlay-Einträge sind in
 * einer mittigen Spalte zentriert; ein `inline-block`-`::before` mit
 * `margin-right` hält Pfeil+Label als Einheit mittig. Es wird bewusst KEIN
 * padding-/margin-left gesetzt, damit „Profilbild erstellen" nicht aus der
 * Spaltenmitte rückt. Nur im geöffneten Overlay, Desktop bleibt unverändert. */
.kv-site-header .kv-header-nav .wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item.kv-lvl3
	> .wp-block-navigation-item__content::before {
	content: "";
	display: inline-block;
	width: 1.4rem;
	height: 0.64rem;
	margin-right: 0.75rem;
	/* align-self:center zentriert den Pfeil als Flex-Item vertikal in der
	 * Zeile (der Link ist display:flex mit align-items:normal/stretch).
	 * Kein margin-left/padding-left — alle Overlay-Einträge bleiben mittig. */
	align-self: center;
	background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2022%2010%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%23FCF8EC%22%20stroke-width%3D%222.5%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M1%205h16%22%2F%3E%3Cpath%20d%3D%22M17%200.5L21.5%205l-4.5%204.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
	background-repeat: no-repeat;
	background-position: left center;
	background-size: 1.4rem 0.64rem;
}

/*
 * ---------------------------------------------------------------------------
 * Inverted (light) header — legal pages
 * ---------------------------------------------------------------------------
 * The legal pages (/impressum/, /datenschutz/, body class
 * `kv-header-inverted`, see functions.php) swap the dark ink header chrome
 * for a white bar: white background, ink logo and ink text, an ink ghost
 * donate button. Everything below is scoped to the `kv-header-inverted`
 * body class, so all other pages keep the standard ink header untouched.
 * Notes:
 * - The core-generated `.has-ink-background-color` / `.has-paper-color`
 *   (from parts/header.html) carry `!important`; the overrides mirror it.
 * - The dropdown panels keep their ink styling on purpose: they work on both
 *   header variants, so no override is scoped into the submenu container
 *   above. The `:focus-visible` outline inside the panels is re-asserted to
 *   signal below, because the generic inverted outline rule (ink) would be
 *   invisible on the ink panels.
 * - Hover/focus on light surfaces uses dunkelblau-75 #3F62AD (the button
 *   system's ink-75 token): signal #FFC04E would fail contrast on white
 *   (~1.8:1), #3F62AD on white passes AA (~5.5:1).
 */

.kv-header-inverted .kv-site-header {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
}

/* Inverted: die Trennlinie (::after des Headers) auf dem hellen Grund in
 * dunkelblau-transparent statt paper-25; Breite/Position erbt die Basis-::after-
 * Regel (max. 1136px, zentriert). */
.kv-header-inverted .kv-site-header::after {
	background: rgba(5, 43, 142, 0.16);
}

.kv-header-inverted .kv-site-header.has-ink-background-color {
	background-color: var(--wp--preset--color--white) !important;
}

.kv-header-inverted .kv-site-header.has-paper-color {
	color: var(--wp--preset--color--ink) !important;
}

/* Logo: the inline SVG stylesheet fills the paths white. This rule wins the
 * cascade because it is more specific AND comes later (0,3,0 vs 0,2,0). */
.kv-header-inverted .kv-header-logo__svg .st0 {
	fill: var(--wp--preset--color--ink);
}

/* Top-level navigation items (the chevron inherits currentColor from the
 * item's color, so it flips to ink with the text). */
.kv-header-inverted .kv-site-header .wp-block-navigation-item__content {
	color: var(--wp--preset--color--ink);
}

/* Hover/Fokus der Top-Level-Nav-Links auf der hellen paper-Fläche: Konsistent
 * zu ink/tuerkis wechselt der Background auf einen hellen Warmton
 * (gelborange-25 #FFEFD3), der ink-Text bleibt unverändert. gelborange-25
 * liefert mit ink den höchsten Text-/Hintergrund-Kontrast (≈ 10,6:1 AAA,
 * besser als dunkelblau-25 ≈ 7,4:1) und harmoniert mit der warmen paper-
 * Fläche. KEIN Textfarbwechsel. Der Hover ist über die Unterstreichung
 * (nicht-farbabhängiger Indikator) ohnehin klar erkennbar, der Background
 * ist das sekundäre Affordanz. Bewusst über den Kind-Selektor nur auf die
 * oberste Ebene gescoped — Megapanel-Einträge bleiben unberührt. */
.kv-header-inverted .kv-site-header .wp-block-navigation__container >
	.wp-block-navigation-item > .wp-block-navigation-item__content:hover,
.kv-header-inverted .kv-site-header .wp-block-navigation__container >
	.wp-block-navigation-item > .wp-block-navigation-item__content:focus-visible {
	background: var(--wp--preset--color--gelborange-25);
}

/* Language switcher: ink text, ink divider (paper-25 would vanish on white).
 * Hover on light surfaces uses the ink-75 tone (see section comment). */
.kv-header-inverted .kv-header-lang__link {
	color: var(--wp--preset--color--ink);
}

/* Language-Switcher auf der hellen paper-Fläche: gleiches Background-Change-
 * Modell wie die Nav-Links (gelborange-25), ink-Text bleibt, keine Textfarbe. */
.kv-header-inverted .kv-header-lang__link:hover,
.kv-header-inverted .kv-header-lang__link:focus-visible {
	background: var(--wp--preset--color--gelborange-25);
}

.kv-header-inverted .kv-header-lang__separator {
	background: var(--wp--preset--color--ink);
}

/* Search field: the paper ghost border and paper pill would disappear on
 * the white header, so the pill flips to a white field with an ink border;
 * input text and search icon stay ink (already the base colours).
 *
 * The ink border used to be a hairline flush against the 36px children,
 * which filled the 36px content box of the 38px pill edge to edge. On some
 * real browsers that rasterized away, dropping the bottom border. Children
 * now keep 1px clearance on every side, so each border edge sees the same
 * stable geometry as the top border, which always rendered. */
.kv-header-inverted .kv-site-header .wp-block-search__inside-wrapper {
	align-items: center;
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--ink);
}

.kv-header-inverted .kv-site-header .wp-block-search__input {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	height: 34px;
}

.kv-header-inverted .kv-site-header .wp-block-search__button {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	height: 34px;
}

/* Donate ghost button: on white the paper-25 ghost is invisible, so it
 * becomes secondary-ink (transparent, ink border + text). 17.08.08
 * Figma-Fill-Logik: hover/focus = Primary-Auftritt, identisch zum System-
 * is-style-secondary-ink — ink-Fill, paper-25 Text (der ink-in-ink
 * gezogene Border verschwindet im Fill; paper-25 auf ink 11.85:1 AAA). */
.kv-header-inverted .wp-block-button.is-style-header-ghost .wp-block-button__link {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--ink);
	color: var(--wp--preset--color--ink);
}

.kv-header-inverted .wp-block-button.is-style-header-ghost .wp-block-button__link:hover,
.kv-header-inverted .wp-block-button.is-style-header-ghost .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

/* Focus outline: the theme-wide signal outline (3px) drops to ~1.8:1 on
 * white, so interactive controls in the inverted header focus with an ink
 * outline instead (ink on white > 11:1). */
.kv-header-inverted :where(a, button, input, textarea, select):focus-visible {
	outline-color: var(--wp--preset--color--ink);
}

/* The dropdown panels keep their ink background; re-assert the signal
 * outline for their focused items, because the ink outline above would be
 * invisible on the ink panels (signal on ink = 8.4:1). */
.kv-header-inverted .kv-site-header .kv-header-nav .wp-block-navigation__submenu-container
	.wp-block-navigation-item__content:focus-visible {
	outline: 3px solid var(--wp--preset--color--signal);
}

/*
 * .p-bold — Figma-Textstil "p-bold", eingeführt 12.08. nach
 * Auftraggeber-Spec: 17px / 24px Schriftschnitt, zentriert, dunkelblau.
 * Seit 17.08. läuft die Schriftgröße fluid über
 * clamp(0.9375rem, 1.5vw, 1.0625rem) (15–17px, Untergrenze ~88 % des
 * bisherigen Werts, Desktop ab 1136px identisch); die Zeilenhöhe bleibt
 * fest 24px. `color: #052B8E` ist der ink-Preset-Wert; `line-height:
 * 24px` entspricht 141 % bzw. der Figma-Feldhöhe. `Google Sans Flex`
 * wird laut Theme-Konvention (kein Selbst-Hosting externer Fonts) nur als
 * Name vorangestellt; das tatsächlich geladene und gerenderte Font ist der
 * Fallback IBM Plex Sans (var). Kein @import, kein externes Laden.
 * Seit 12.09. ohne `font-weight: 700` (User-Spec "Remove bold from the
 * CSS for the text"): der Text steht auf normalem Schnitt, betonte
 * Wörter markiert die Redaktion inline mit <b>/<i> im Tickertext (siehe
 * die <b>/<i>-Regel unten). Verbraucher: der Breaking-News-Ticker
 * (`.kv-breaking-news__item`).
 */
.p-bold {
	font-family: 'Google Sans Flex', var(--wp--preset--font-family--ibm-plex-sans);
	font-style: normal;
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem); /* 15–17px, fluid (Fluid-Typo) */
	line-height: 24px;
	text-align: center;
	color: #052B8E;
}

/*
 * ---------------------------------------------------------------------------
 * Breaking-news ticker
 * ---------------------------------------------------------------------------
 * Only additive rules, scoped with the `kv-breaking-news` prefix. The pattern
 * renders two identical halves of k copies each, so translating the track by
 * -50% of its own width loops seamlessly. k is estimated from the character
 * count so one half loop always covers the ticker window: the window is never
 * empty and the text never visibly jumps back to the start.
 *
 * Window (12.09., Muster): the gold bar itself still spans 100vw, but the
 * marquee no longer runs across the full bar. `.kv-breaking-news__window`
 * caps the stage at the 1136px content column (the same width the header
 * line and the `kv-shell` content sections use) and centers it in the bar;
 * on narrow screens it collapses to the bar's own inner width. The flanking
 * gold margins are left free for the Gradkreis decoration.
 *
 * Gradkreis decoration (12.09., Muster): five `__deco` slots, absolutely
 * positioned annuli (Testimonial-Slider morphology, one path per ring,
 * fill via currentColor) flanking the window, bleeding over the bar edges
 * (the bar's overflow: hidden clips them). The pattern rolls size, color
 * and morphology per render (class `__deco--0`…`--4`, color inline); the
 * geometry per slot lives in CSS below and only applies from 1420px, where
 * the margins are wide enough. `wp_rand()` means the deco legitimately
 * differs between reloads (same convention as the Testimonial-Slider).
 *
 * Speed follows reading research (Reading Traits for Dynamically Presented
 * Texts, Frontiers in Psychology 2017): about 6 chars/s are perceived as
 * optimal. The pattern hands in three values: `--kv8-breaking-news-length`
 * (N chars, kept for fallback compatibility), `--kv8-breaking-news-loop`
 * (k·N/6 s, one half loop) and `--kv8-breaking-news-entry`
 * (1440·N/(6c) s, the 1440px-basis entry scaled by the animation below to
 * the 100vw bar). The loop therefore always passes exactly 6 chars/s,
 * independent of glyph width; the entry duration equals bar width divided
 * by the loop's pixel speed (6c/N px/s). Because the stage now travels the
 * full 100vw bar (no longer capped at 1440px), the pattern's entry value is
 * scaled by (100vw/1440px) in the animation, so the visible velocity stays
 * constant from load into the loop at any viewport width.
 *
 * Both animations fall back to fixed values when the pattern does not
 * supply the variables (hand-placed markup).
 *
 * The item type is the p-bold text style (see the .p-bold rule above; since
 * 17.08. its font-size is fluid clamp(0.9375rem, 1.5vw, 1.0625rem), 15–17px,
 * line-height stays 24px): IBM Plex Sans fallback, 17/24, centred, ink.
 * Since 12.09. normal weight (User-Spec): inline <b>/<i> in the stored
 * ticker text carry the emphasis instead of a blanket font-weight; the
 * browser's own b/i user-agent styles render them. One copy is about
 * 9px per character plus the 1rem `padding-inline-end`, which also acts as
 * the uniform gap between the loop duplicates. The old 40px caps-on-gold
 * large-text ticker is gone (up to the 12.08. "Global B" typography
 * decision); the loop itself is font-size independent.
 *
 * Only the very first duplicate is announced to assistive technology; all
 * other copies carry aria-hidden (WCAG technique SCR36), so the text is read
 * once, statically.
 *
 * WCAG 2.2.2 (Pause, Stop, Hide): because the ticker runs longer than 5 s
 * next to other content, it must be pausable. The minimal compliant stop is
 * provided as a three-rule pause on hover and on keyboard focus below.
 */

.kv-breaking-news {
	background: var(--wp--preset--color--signal);
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	/* Direct shell child: same full-bleed breakout as the header and
	 * footer, so the gold bar spans the exact window width at every
	 * viewport (see the header/footer rule for the reasoning).
	 * The marquee animation timing is handled separately below and scaled
	 * to the 100vw bar. */
	margin-inline: calc(50% - 50vw);
	max-width: none;
	position: relative;
	overflow: hidden;
	padding-block: clamp(0.5rem, 1.4vw, 1rem);
	width: 100vw;
	/* Fallback so the loop duration stays well-defined even when the pattern
	 * does not supply a length (e.g. a hand-place markup). */
	--kv8-breaking-news-length: 60;
}

.kv-breaking-news:hover .kv-breaking-news__stage,
.kv-breaking-news:hover .kv-breaking-news__track,
.kv-breaking-news:focus-within .kv-breaking-news__stage,
.kv-breaking-news:focus-within .kv-breaking-news__track {
	animation-play-state: paused;
}

/* The marquee's clip area is the header's printed content column, so the
 * ticker text aligns exactly with the header content at every viewport:
 * the `.kv-header-top` shell is min(100%, 1136px) wide with 1rem inline
 * padding, i.e. its content is min(100%, 1136px) − 2rem (1104px on wide
 * screens). No padding here on purpose: overflow: hidden clips at the
 * PADDING box edge, so padding would NOT narrow the scrolling
 * (transformed) track — the width itself carries the inset per side. The
 * glyphs keep their own 0.5rem item padding as the air toward the clip
 * edge, where the deco strips end (see below): Gradkreise und Text stoßen
 * nie direkt aneinander. overflow: hidden clips the stage entry and the
 * track overflow at the window edges, so the Laufschrift never paints
 * over the flanking deco rings. */
.kv-breaking-news__window {
	margin-inline: auto;
	overflow: hidden;
	width: calc(min(100%, 1136px) - 2rem);
}

/* The stage begins exactly at the window's right edge, leaving the window
 * empty (12.09.: the entry starts at the WINDOW edge, not the viewport
 * edge — since the window clips the marquee, a 100vw start would make the
 * text invisible while it crosses the gold margins and delay the first
 * character on wide screens; the start point `min(100vw, 1136px)` is the
 * window width at every breakpoint, and the same factor divides the
 * pattern's entry duration so the pixel speed stays matched with the
 * loop). Its duration (1440·N/(6c) s from the pattern, scaled by
 * min(100vw, 1136px)/1440px in the animation below) matches the loop's
 * pixel speed at any viewport width and falls back to 12s without a
 * pattern value. The track waits for the entry, preventing two leftward
 * motions from combining into a faster initial glide. */
.kv-breaking-news__stage {
	animation: kv-breaking-news-enter calc(var(--kv8-breaking-news-entry, 12) * 1s * ((min(100vw, 1136px) - 2rem) / 1440px)) linear 0.4s 1 both;
	display: inline-block;
	will-change: transform;
}

.kv-breaking-news__track {
	animation: kv-breaking-news-scroll var(--kv8-breaking-news-loop, calc(var(--kv8-breaking-news-length) / 6 * 1s)) linear calc(0.4s + var(--kv8-breaking-news-entry, 12) * 1s * ((min(100vw, 1136px) - 2rem) / 1440px)) infinite both;
	display: inline-flex;
	max-width: none;
	white-space: nowrap;
	will-change: transform;
}

/* Gradkreis decoration: three annuli per side (six slots, Testimonial-
 * Slider morphology, fill via currentColor — color and ring path come per
 * render from the pattern) flanking the 1136px window in the gold margins.
 * Each half lives in a `__deco-side` strip that spans its gold margin from
 * the bar edge up to the window's padding edge (1136px text column + 2 ×
 * 0.5rem window padding) and clips with overflow: hidden — a structural
 * guarantee that no ring can ever paint inside the marquee window or touch
 * the text (User-Spec 12.09.: mindestens 0.5rem Luft zwischen Ringen und
 * Text). The rings themselves are placed fully inside the strip (no
 * window-edge cuts: the deco simply hides below 1420px, where the margins
 * grow too tight for the ring widths), so nothing is ever partially sliced.
 * Geometry is proportional: diameters in vw follow the band height (the
 * bar's clamp(0.5rem, 1.4vw, 1rem) padding), x-positions ride the strip.
 * Rings may still bleed over the bar's top/bottom edge like in the Muster
 * (the bar's overflow: hidden clips that). aria-hidden decoration:
 * pointer-events none keeps hover-pause on the bar itself. */
.kv-breaking-news__deco-side {
	box-sizing: border-box;
	display: none;
	height: 100%;
	overflow: hidden;
	pointer-events: none;
	position: absolute;
	top: 0;
	width: calc((100% - 1136px - 1rem) / 2);
	width: calc((100% - min(100%, 1136px)) / 2 + 1rem);
}

.kv-breaking-news__deco-side--left {
	left: 0;
}

.kv-breaking-news__deco-side--right {
	right: 0;
}

.kv-breaking-news__deco {
	position: absolute;
}

.kv-breaking-news__deco svg {
	display: block;
	height: auto;
	width: 100%;
}

/* The innermost rings (slot 2 left, slot 5 right) hold a fixed 1rem margin
 * to the window's clip edge (User-Spec 12.09.: Abstand zwischen Text und
 * Gradkreisen), anchored from the strip's window-side edge instead of a
 * percentage — the gap stays constant at every viewport width. Slots 0/1
 * (left) and 3/4 (right) spread across the outer two thirds of the strip
 * so no two rings share nearly the same x position. */
.kv-breaking-news__deco--0 {
	height: 5vw;
	left: 1%;
	top: 6%;
	width: 5vw;
}

.kv-breaking-news__deco--1 {
	height: 2.2vw;
	left: 38%;
	top: 10%;
	width: 2.2vw;
}

.kv-breaking-news__deco--2 {
	height: 3.6vw;
	right: 1rem;
	top: 56%;
	width: 3.6vw;
}

.kv-breaking-news__deco--3 {
	height: 4vw;
	right: 1%;
	top: 2%;
	width: 4vw;
}

.kv-breaking-news__deco--4 {
	height: 2.4vw;
	right: 40%;
	top: 54%;
	width: 2.4vw;
}

.kv-breaking-news__deco--5 {
	height: 4.6vw;
	left: 1rem;
	top: 8%;
	width: 4.6vw;
}

/* The deco shows from 1360px (User-Spec 12.09., previously 1420px): at
 * 1360px each margin strip is 104px wide, which still fits the smallest
 * ring (2.2vw ≈ 30px) plus the 1rem inner margin with room to spare; the
 * rings scale with vw, so the cascade compresses gracefully below the
 * old breakpoint instead of vanishing a step earlier. */
@media (min-width: 1360px) {
	.kv-breaking-news__deco-side {
		display: block;
	}
}

/* Seit 12.08. (User-Spec p-bold) ist der Ticker-Text die 17px p-bold-Optik
 * (siehe .p-bold oberhalb) statt des alten 40px caps-on-gold Großtexts: IBM
 * Plex Sans Fallback, 17/24, zentriert, weiterhin ink (#052B8E, =
 * var(--wp--preset--color--ink)); `text-transform: uppercase` ist entfernt.
 * Seit 17.08. läuft die Schriftgröße fluid über clamp(0.9375rem, 1.5vw,
 * 1.0625rem) (15–17px, siehe Fluid-Typo-Konvention); die Zeilenhöhe bleibt
 * fest 24px. Seit 12.09. ohne pauschales font-weight (User-Spec): die
 * Betonung kommt inline aus <b>/<i> im Tickertext, der Browser rendert die
 * User-Agent-Schnitte. Die `prefers-reduced-motion`-Variante (statischer
 * Umbruch, Animation none) bleibt unverändert.
 * Der Duplikat-Abstand bleibt 1rem: `padding-inline: 0.5rem` (User-Spec
 * 12.09., Luft an beiden Textenden) summiert sich über die Kopfgrenze auf
 * denselben 1rem, den früher `padding-inline-end: 1rem` allein lieferte —
 * die Copy-Breite-Schätzung (9·N + 16) bleibt exakt. */
.kv-breaking-news__item {
	color: var(--wp--preset--color--ink);
	font-family: 'Google Sans Flex', var(--wp--preset--font-family--ibm-plex-sans);
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem); /* 15–17px, fluid (Fluid-Typo) */
	line-height: 24px;
	padding-inline: 0.5rem;
	text-align: center;
}

/* Never underlined in the resting state (User-Spec 12.09. "Den Text
 * niemals unterstreichen. Also auch nicht, wenn ein Link vorhanden
 * ist."): the link stays ink and undecorated like the plain ticker text.
 * Hover/keyboard-focus reveals the interaction through a thick ink
 * underline (User-Spec 12.09. "Bei Hover: Kein Farbumschlag, aber dicke
 * Unterstreichung.") — no color change anywhere. */
.kv-breaking-news__link {
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}

.kv-breaking-news__link:hover,
.kv-breaking-news__link:focus-visible {
	text-decoration: underline;
	text-decoration-thickness: 3px;
	text-underline-offset: 0.18em;
}

/* Ink outline instead of the theme-wide signal outline, which would vanish
 * on the gold ticker background. */
.kv-breaking-news__link:focus-visible {
	outline: 3px solid var(--wp--preset--color--ink);
	outline-offset: 4px;
}

@keyframes kv-breaking-news-scroll {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(-50%);
	}
}

@keyframes kv-breaking-news-enter {
	from {
		transform: translateX(calc(min(100vw, 1136px) - 2rem));
	}
	to {
		transform: translateX(0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.kv-breaking-news__stage,
	.kv-breaking-news__track {
		animation: none;
		transform: none;
	}

	.kv-breaking-news__stage {
		display: block;
	}

	/* Static single-line layout: the track becomes a flex container that
	 * wraps, the item takes the full width and its text flows over as many
	 * lines as needed. Only the first copy is shown (the aria-hidden
	 * duplicate is dropped), keeping the static announcement a single text. */
	.kv-breaking-news__track {
		display: flex;
		flex-wrap: wrap;
		white-space: normal;
	}

	.kv-breaking-news__item {
		padding-inline: 0;
		width: 100%;
	}

	.kv-breaking-news__item[aria-hidden="true"] {
		display: none;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Logos-Laufband (Block klima-vor-acht/logos-laufband, Medien-Logos)
 * ---------------------------------------------------------------------------
 * Marquee-Zeile der Wirkungsseite, servergerendert vom Block
 * `klima-vor-acht/logos-laufband` (inc/logos-laufband.php). Technik nach
 * dem Breaking-News-Ticker oben: Der Track hält zwei exakt identische
 * Halbleisten (erstes Set + aria-hidden Duplikat-Set), `translateX(-50%)`
 * loopt damit nahtlos an der Halbbreite. Nur additive Regeln, scoped mit
 * dem `kv-logos-laufband`-Präfix.
 *
 * Zwei-Phasen-Ablauf (Enter + Loop, G1; H6: kurze, Loop-tempo-kalibrierte
 * Einfahrt):
 * 1. Enter (`.kv-logos-laufband__stage`): Beim Erscheinen startet das
 *    Laufband sichtbar rechts versetzt mit `@keyframes
 *    kv-logos-laufband-enter` bei `translateX(300px)` (Variable
 *    `--kv-logos-laufband-enter-from`; auf ≤782 px Viewport nur 180 px,
 *    Media-Query unten) und fährt auf `translateX(0)` ein – eine kleine,
 *    überschaubare Distanz in konstanten 2.5 s (`--kv-logos-laufband-
 *    entry`, H2). Die Einfahr-Geschwindigkeit liegt damit nahe dem
 *    Loop-Tempo: 300 px / 2.5 s = 120 px/s gegen ~103 px/s Loop
 *    (Desktop), 180 px / 2.5 s = 72 px/s = exakt das Mobile-Loop-Tempo
 *    (390 px, max-width:50vw-Deckelung). Die "von rechts außerhalb
 *    beginnend"-Optik bleibt: Der Start ist rechts versetzt und der
 *    Track fährt von dort in den Wrapper ein – kein "Rasen" mehr
 *    (Redaktions-Feedback H6; vorher 1440 px / 2.5 s ≈ 576 px/s). Die
 *    Stage darf dabei über die Spaltenbreite hinausragen, geklemmt wird
 *    am Wrapper `.kv-logos-laufband` (`overflow: hidden`, G2, analog
 *    `.kv-breaking-news`): Rechts neben der Laufband-Zeile ist auf der
 *    Sektionsfläche nichts sichtbar. Die Logos stehen währenddessen
 *    still (der Track wartet, siehe 2). Dauer auf jedem Viewport
 *    identisch 2.5 s – KEIN (min(100vw, …)/1440px)-Skalierungsfaktor in
 *    der Dauer (H6): Die Distanz ist fest, ein Viewport-Faktor würde die
 *    Dauer auf Mobile verkürzen und die Einfahrt damit wieder
 *    beschleunigen statt im Loop-Tempo zu halten.
 * 2. Loop (`.kv-logos-laufband__track`): Der endlose Scroll-Track läuft
 *    mit `animation-delay = 0.4s + Enter` und `fill-mode: both` – er
 *    hält im from-Zustand (translateX(0)) an, bis die Enter-Phase vorbei
 *    ist. So addieren sich nie zwei Links-Bewegungen und es gibt keinen
 *    Temposprung am Übergang.
 *
 * Geschwindigkeit (G2: −20 % Tempo gegenüber G1, Formel dokumentiert):
 * Die Loop-Dauer ist N × 2.5 s pro Halbschleife (Faktor `2 s` → `2.5 s`,
 * `2 / 0.8 = 2.5`, Redaktionsvorgabe). Eine Halbschleife ist exakt
 * N × (w + g) px breit (w = Logo-Breite, g = 2rem Gap), daraus folgt eine
 * konstante Pixelgeschwindigkeit von (w + g) / 2.5 px/s – unabhängig von
 * der Gesamtzahl der Terme (Terme ergänzen/entfernen verlängert bzw.
 * verkürzt die Schleife proportional, die wahrgenommene Laufgeschwindig-
 * keit bleibt gleich). Gemessenes Referenzpaar im realen Bestand: vorher
 * Faktor 2 s → ~128.5 px/s (G1), jetzt Faktor 2.5 s → ~103 px/s (G2;
 * Messprotokolle in den G1-/G2-Berichten). Ohne `--kv-logos-laufband-count`
 * greift ein fester Fallback (12 Logos → 30 s).
 *
 * Einfahrphase (H2: kurze Startsequenz, H6: Loop-Tempo-Niveau, Feedback
 * "Einfahrt rast"):
 * `--kv-logos-laufband-entry` ist seit H2 eine feste KONSTANTE von 2.5 s
 * (inc/logos-laufband.php) – die DAUER der Einfahrt, auf jedem Viewport
 * identisch. Seit H6 ist zusätzlich die Start-DISTANZ klein und fest:
 * `--kv-logos-laufband-enter-from` = 300 px (≤782 px Viewport 180 px,
 * Media-Query unten) statt der früheren vollen Viewport-Breite. Daraus
 * folgt die Einfahr-Geschwindigkeit von 300 px / 2.5 s = 120 px/s gegen
 * ~103 px/s Loop (Desktop 1440) bzw. 180 px / 2.5 s = 72 px/s gegen
 * ~72 px/s Loop (Mobile 390, max-width:50vw-Deckelung) – die Einfahrt
 * startet sofort sichtbar (0.4 s Delay) und bewegt sich im
 * Loop-Tempo-Bereich, kein Geschwindigkeitssprung zum Loop.
 * Positions-ruckfrei ist der Übergang trotzdem: Beide Animationen
 * klemmen mit `fill-mode: both` auf ihren Keyframe-Zuständen, und der
 * Loop startet mit `animation-delay = 0.4s + Entry` exakt, wenn die
 * Stage bei `translateX(0)` angekommen ist – die Loop-Keyframes (0 →
 * −50 %) treffen an der Halbleiste ohne Sprung aufeinander. Ohne
 * gesetztes `--kv-logos-laufband-entry` greift der CSS-Fallback 2.5,
 * ohne `--kv-logos-laufband-enter-from` der Fallback 300 px (gleiches
 * Verhalten, siehe unten). Logo-Breiten sind serverseitig weiterhin
 * nicht exakt bekannt und für die kleine, feste Startdistanz auch nicht
 * mehr nötig – die Geschwindigkeit (Distanz / 2.5 s) folgt daraus von
 * selbst.
 *
 * Breiten-Stabilität (Ursache des B4-"Sprunges" am Loop-Übergang, G1):
 * Zwei Faktoren machen den -50 %-Übergang exakt:
 * 1. Der Track ist `width: max-content` (nicht das block-level-Flex-
 *    Default, das den Track auf die Spaltenbreite zusammenzieht): Erst mit
 *    voller Inhaltsbreite bedeutet -50 % exakt eine Halbleiste. Der
 *    B4-Track war spaltenbreit (1136 px), während eine Halbleiste
 *    ~1800 px misst – der Loop sprang messbar (G1-Messung).
 * 2. Alle Logos laden eager (kein `loading="lazy"` mehr, siehe
 *    inc/logos-laufband.php): Die Breite jeder Halbleiste steht vom ersten
 *    Frame an fest, kein Layout-Shift während der Animation.
 *
 * Lücken-Abstand: `margin-inline-end` auf jedem `<img>` statt `gap` im
 * Flex-Track – genau wie `padding-inline-end` beim Breaking-News-Item
 * trägt JEDES Bild (auch das letzte einer Halbleiste) seinen Abstand,
 * eine Halbleiste ist damit N × (Bildbreite + Abstand) breit und die
 * -50 %-Verschiebung fällt exakt auf den Anfang der zweiten Halbleiste.
 *
 * Viewport-Pause (G1): assets/js/logos-laufband.js (IntersectionObserver)
 * togglet die Wrapper-Klasse `kv-logos-laufband--paused`, solange das
 * Laufband außerhalb des Viewports liegt; die Klasse pausiert Stage und
 * Track via `animation-play-state: paused !important`. `!important` ist
 * hier vertretbar und gewollt: Die Klasse lag ausschließlich im
 * unsichtbaren Zustand an (die Hover-/Focus-Pause unten bleibt für den
 * sichtbaren Zustand unangetastet) und muss jede andere play-state-Quelle
 * sicher übertreffen – deterministisches Einfrieren außerhalb des
 * Sichtbereichs. Ohne JS läuft Enter + Loop ab Seitenaufruf automatisch
 * (CSS-Fallback, wie bisher).
 *
 * WCAG 2.2.2 (Pause, Stop, Hide): läuft länger als 5 s neben anderem
 * Inhalt, daher Hover-/Focus-Pause wie beim Breaking-News-Ticker. Der
 * Block enthält selbst keine fokussierbaren Elemente (nur Bilder),
 * `:focus-within` greift als Guard, falls Redaktion später Verlinkte
 * Logos einbaut. `prefers-reduced-motion: reduce` schaltet BEIDE
 * Animationen ab (auch den Enter): statische, umbrechende flex-Reihe nur
 * aus dem ERSTEN Set (das aria-hidden Duplikat wird ausgeblendet – gleiche
 * Technik wie beim Ticker), kein Marquee, kein horizontaler Overflow.
 */

.kv-logos-laufband {
	--kv-logos-laufband-gap: 2rem;
	/* Start-Distanz der Einfahrt (H6): kleine, feste Strecke, damit die
	 * Enter-Phase im Loop-Tempo-Bereich bleibt – 300 px / 2.5 s = 120 px/s
	 * auf Desktop (Loop ≈ 103 px/s); auf ≤782 px Viewport wird die
	 * Variable per Media-Query auf 180 px gesetzt (180 / 2.5 = 72 px/s =
	 * exakt das Mobile-Loop-Tempo). Fallback in den Keyframes ebenfalls
	 * 300 px (fremdes/altes Markup). */
	--kv-logos-laufband-enter-from: 300px;
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	/* Klemmung (G2): Der Wrapper übernimmt das Overflow-Clipping der
	 * Laufband-Zeile. Während der Enter-Phase ist die Stage rechts
	 * versetzt (translateX(var(--kv-logos-laufband-enter-from)) plus
	 * Track-Breite) und ragt über die Spaltenbreite hinaus – ohne
	 * Wrapper-Clip würde der einfahrende Track rechts neben dem Laufband
	 * auf der Sektionsfläche sichtbar (Redaktions-Feedback zu G1). Analog
	 * `.kv-breaking-news`. Das Label darüber ist ein statisches
	 * Fluss-Element und bleibt davon unberührt. */
	overflow: hidden;
}

/* Dezent sichtbares Label über der Laufband-Zeile (i18n-String, siehe
 * inc/logos-laufband.php). Bewusst kein h-Tag: Der Block stellt keine
 * Überschriftsebene im Sektions-Raster, die umgebende Sektion (C4) trägt
 * die H2-Überschrift. */
.kv-logos-laufband__label {
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	margin: 0 0 0.75rem;
	opacity: 0.7;
	text-align: center;
	text-transform: uppercase;
}

/* No-Results-Hinweis (kein Marquee): schlichter i18n-Text, zentriert. */
.kv-logos-laufband__empty {
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: 0.9375rem;
	margin: 0;
	text-align: center;
}

.kv-logos-laufband:hover .kv-logos-laufband__stage,
.kv-logos-laufband:hover .kv-logos-laufband__track,
.kv-logos-laufband:focus-within .kv-logos-laufband__stage,
.kv-logos-laufband:focus-within .kv-logos-laufband__track {
	animation-play-state: paused;
}

/* Viewport-Pause (G1): Die JS-Klasse liegt nur an, solange das Laufband
 * unsichtbar ist; !important stellt sicher, dass das Einfrieren jede
 * andere play-state-Quelle übertrumpft (Hover-/Focus-Pause betrifft nur
 * den sichtbaren Zustand mit laufender Animation). */
.kv-logos-laufband--paused .kv-logos-laufband__stage,
.kv-logos-laufband--paused .kv-logos-laufband__track {
	animation-play-state: paused !important;
}

/* Enter von rechts (Breaking-News-Muster; H2: feste kurze Dauer 2.5 s,
 * H6: kleine feste Start-Distanz statt voller Viewport-Breite): Der
 * Stage gleitet von translateX(var(--kv-logos-laufband-enter-from))
 * (300 px, ≤782 px Viewport 180 px) auf 0 herein – Einfahrt im
 * Loop-Tempo-Bereich (120 px/s Desktop gegen ~103 px/s Loop; 72 px/s
 * Mobile = exakt Loop-Tempo, siehe Kopfkommentar). KEINE Viewport-
 * Skalierung in der Dauer: Die Distanz ist fest, ein
 * (min(100vw, …)/1440px)-Faktor würde die Dauer auf Mobile verkürzen und
 * die Einfahrt wieder beschleunigen; stattdessen läuft die Dauer auf
 * jedem Viewport identisch 2.5 s und der Track-Delay rechnet dieselbe
 * Formel (kein Versatz). display bleibt block (der Stage füllt die
 * Spalte). KEIN eigenes Overflow-Clipping (G2): Die Enter-Transformation
 * darf über die Spaltenbreite hinausragen – abgeschnitten wird am Wrapper
 * `.kv-logos-laufband` (overflow: hidden, analog `.kv-breaking-news`).
 * `will-change` bleibt, die Enter-Phase ist die kritische Transform.
 * Fallbacks 2.5 / 300 px: ohne serverseitigen Wert bzw. Variable
 * (fremdes/altes Markup) entsteht dieselbe kurze Einfahrt. */
.kv-logos-laufband__stage {
	animation: kv-logos-laufband-enter calc(var(--kv-logos-laufband-entry, 2.5) * 1s) linear 0.4s 1 both;
	will-change: transform;
}

/* Loop: width:max-content ist Pflicht für die -50 %-Nahtlosigkeit (siehe
 * Kopfkommentar, Punkt 1) – ohne JS-Eingriff hält fill-mode:both den Track
 * während der Enter-Phase im from-Zustand. animation-delay = 0.4s + Entry
 * (beide Formeln ohne Viewport-Faktor, H6): der Track setzt exakt dann
 * ein, wenn die Stage bei translateX(0) angekommen ist; kein
 * Positionssprung am Übergang. */
.kv-logos-laufband__track {
	animation: kv-logos-laufband-scroll calc(var(--kv-logos-laufband-count, 12) * 2.5s) linear calc(0.4s + var(--kv-logos-laufband-entry, 2.5) * 1s) infinite both;
	display: flex;
	width: max-content;
	will-change: transform;
}

/* Logo-Bild: feste Höhen-Bandbreite (clamp) hält die Zeile auf allen
 * Viewports kompakt; width:auto + object-fit:contain erhält das
 * Seitenverhältnis, flex:0 0 auto verhindert Schrumpfen im Flex-Track,
 * max-width begrenzt extreme Breit-Formate defensiv (Admin-pflegbare
 * Bilder). `margin-inline-end` = der einheitliche Lücken-Abstand (siehe
 * Kopfkommentar), er doppelt zugleich als Loop-Teilung. */
.kv-logos-laufband__track .kv-logos-laufband__logo {
	flex: 0 0 auto;
	height: clamp(2rem, 4vw, 3rem);
	margin-inline-end: var(--kv-logos-laufband-gap);
	max-width: 50vw;
	object-fit: contain;
	width: auto;
}

@keyframes kv-logos-laufband-scroll {
	from {
		transform: translateX(0);
	}
	to {
		transform: translateX(-50%);
	}
}

/* H6: from-Position ist eine kleine feste Distanz (Variable auf
 * `.kv-logos-laufband`, 300 px; ≤782 px Viewport 180 px per Media-Query)
 * statt der vollen Viewport-Breite – die Einfahrt läuft damit im
 * Loop-Tempo-Bereich statt über die ganze Zeile zu rasen (vorher 1440 px
 * / 2.5 s ≈ 576 px/s, H6: 120 px/s Desktop, 72 px/s Mobile). Der Fallback
 * 300 px hält fremdes/altes Markup konsistent zur Wrapper-Default. */
@keyframes kv-logos-laufband-enter {
	from {
		transform: translateX(var(--kv-logos-laufband-enter-from, 300px));
	}
	to {
		transform: translateX(0);
	}
}

/* Mobile (H6): kleinere Start-Distanz, damit die Einfahrt exakt dem
 * Mobile-Loop-Tempo entspricht – die Logos sind auf Mobile per
 * max-width:50vw gedeckelt und laufen langsamer (~72 px/s); mit der
 * Desktop-Distanz (300 px) würde die Einfahrt dort mit ~120 px/s laufen
 * (≈ 1.7× Loop-Tempo). 180 px / 2.5 s = 72 px/s = Loop. */
@media (max-width: 782px) {
	.kv-logos-laufband {
		--kv-logos-laufband-enter-from: 180px;
	}
}

@media (prefers-reduced-motion: reduce) {
	/* Beide Animationen (Enter + Loop) ab, Endzustand erzwingen:
	 * transform: none verhindert, dass ein fill-mode-Rest (vor allem der
	 * Enter) das Layout verschiebt. */
	.kv-logos-laufband__stage,
	.kv-logos-laufband__track {
		animation: none;
		transform: none;
	}

	/* Statische Reihe: Track als umbrechende Flex-Reihe; width:auto hebt
	 * die Loop-Notwendigkeit width:max-content für diesen Fall auf (sonst
	 * bliebe der Track auf Inhaltsbreite statt auf Spaltenbreite). Nur das
	 * Duplikat-Set ausblenden: Die Logos sind nacheinander lesbar, kein
	 * Marquee, kein horizontaler Overflow. */
	.kv-logos-laufband__track {
		display: flex;
		flex-wrap: wrap;
		width: auto;
	}

	.kv-logos-laufband__track .kv-logos-laufband__logo[aria-hidden="true"] {
		display: none;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Wirkung Slider — home section
 * ---------------------------------------------------------------------------
 * Carousel with the latest "Wirkung & Erfolg" posts, server-rendered by the
 * dynamic block `klima-vor-acht/wirkung-slider` (inc/slider.php). Geometry
 * from the Figma "A - Startseite" export, proof section: 1136px outer content
 * shell, the card stacked as image (460.41 x 437.6) left, info column right,
 * 40px gap between them, intro above with 40px spacing. Dots are 24px with a
 * 12px radius (cornerRadius 12 in the export), pagination row gap 16px,
 * arrows are 24 x 24 icon buttons. The section is ink with paper-25 text,
 * matching the hero overlay pairing; the card button is a light (paper)
 * button on the ink surface, like the hero CTA.
 *
 * Naming decision (12.08.): die Slider-Chrome (slider, viewport, slide,
 * card-image, card-body, card-title, card-text, card-button, pagination,
 * arrow, dots, dot, status) ist als zentrale, Sektionen-übergreifende
 * Einmal-Pflege unter `.kv-slider__*` generalisiert – einschließlich des
 * Card-Layouts, weil die Card-Struktur (image-text) ein fester Bestandteil
 * des Sliders ist (`klima_vor_acht_render_slider()` in inc/slider.php).
 * Sektions-spezifisch bleiben nur der `.kv-wirkung`-Section-Kontext und der
 * Sektion-CTA `.kv-wirkung__cta`. Mit dem aktiven Dot zieht die Slider-Dots
 * die Pagination-Semantik der Archive nach (gelbe signal-Füllung wie
 * `.kv-archive .wp-block-query-pagination .page-numbers.current`).
 *
 * The section wrapper (kv-section) is un-positioned so the hero overlay that
 * hangs 40px past the hero image edge stays visible above it; nothing in
 * this block is absolutely positioned either.
 *
 * Scroll UX: the track is a CSS scroll-snap row (scroll-snap-type: x
 * mandatory); the vanilla JS (assets/js/slider.js) only wires the dots and
 * arrows to it and reads the active slide from the scroll position. Dots are
 * real <button> elements, the arrows are real buttons with aria-labels,
 * slides announce via aria-roledescription="carousel". No autoplay anywhere.
 */

.kv-wirkung {
	box-sizing: border-box;
	color: var(--wp--preset--color--paper-25);
}

.kv-wirkung > .wp-block-heading,
.kv-wirkung > p {
	margin-block-end: 0;
	margin-block-start: 0;
}

/* Intro stack: title + subline, 40px below the card (Figma stackSpacing). */
.kv-wirkung > .wp-block-heading + p,
.kv-wirkung .kv-slider__slider + p {
	margin-block-start: 0;
}

/* Slider wrapper: keeps intro, track and pagination apart (40px Figma gap).
 * No position/z-index — the hero overhang must stay visible. */
.kv-slider__slider {
	box-sizing: border-box;
	margin-block-start: clamp(1.5rem, 3vw, 2.5rem);
}

/* Scroll-snap track. Slides fill the 1136px content column one at a time;
 * the track itself scrolls horizontally and hides its scrollbar. */
.kv-slider__viewport {
	box-sizing: border-box;
	display: flex;
	overflow-x: auto;
	scroll-behavior: smooth;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
}

.kv-slider__viewport::-webkit-scrollbar {
	display: none;
}

.kv-slider__slide {
	box-sizing: border-box;
	display: flex;
	flex: 0 0 100%;
	gap: 40px;
	scroll-snap-align: center;
}

/* Card: image left (460.41 x 437.6 in the export -> 460px wide, ~1.05:1),
 * info column right, 40px horizontal gap. On small screens the image sits
 * above the text. */
.kv-slider__card-image {
	box-sizing: border-box;
	flex: 0 0 460px;
	margin: 0;
	max-width: 100%;
}

.kv-slider__card-image-el {
	aspect-ratio: 460.41 / 437.6;
	border-radius: 24px;
	display: block;
	height: auto;
	object-fit: contain;
	width: 100%;
}

.kv-slider__card-body {
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: 24px;
	justify-content: center;
}

.kv-slider__card-title {
	color: var(--wp--preset--color--paper-25);
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: var(--wp--preset--font-size--x-large);
	font-weight: 700;
	line-height: 1.25;
	margin: 0;
}

.kv-slider__card-text {
	color: var(--wp--preset--color--paper-25);
	font-size: var(--wp--preset--font-size--normal);
	line-height: 1.55;
	margin: 0;
	max-width: 56ch;
}

/* Card button: ghost secondary button on the ink surface. The slide markup
 * renders a real core/button with the system style class
 * is-style-secondary-paper (registered in functions.php, 08.08. button
 * system), so the shared system rules provide the whole look — transparent
 * background, 1.5px paper border + paper text in rest; hover/focus seit
 * 17.08.08 Figma-Fill-Logik = Primary-Auftritt (paper-25 fill + ink text),
 * identisch zu header-ghost/footer-outline, radius 8, padding 16/12. This
 * wrapper rule only keeps the button left-aligned inside the card column;
 * the transition mirrors the section chrome's 160ms color easing. The focus
 * outline comes from the theme-wide signal rule (:focus-visible, 3px offset
 * 4px) and stays visible on the ink section. */
.kv-slider__card-button {
	align-self: flex-start;
	box-sizing: border-box;
}

.kv-slider__card-button .wp-block-button__link {
	transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}

/* Pagination row: arrows flanking the dot row, 16px Figma gap. */
.kv-slider__pagination {
	align-items: center;
	box-sizing: border-box;
	display: flex;
	gap: 16px;
	justify-content: center;
	margin-block-start: clamp(1.5rem, 3vw, 2.5rem);
}

/* Arrows: 30 x 30 circle icon buttons (border-radius 999px), paper-25 on ink.
 * 30px, kleiner als die 40px-Pills der Aktuellen-Pagination (die Pfeile tragen
 * keine Seitennummern) und proportional zu den 24px-Dots. Hover/focus wie die
 * Aktuelles-Pills: weißer paper-25-Fill mit ink (11.85:1 AAA). */
.kv-slider__arrow {
	align-items: center;
	background: transparent;
	border: 0;
	border-radius: 999px;
	color: var(--wp--preset--color--paper-25);
	cursor: pointer;
	display: inline-flex;
	height: 30px;
	justify-content: center;
	line-height: 0;
	padding: 0;
	transition: background-color 160ms ease, color 160ms ease;
	width: 30px;
}

.kv-slider__arrow:hover,
.kv-slider__arrow:focus-visible {
	background: var(--wp--preset--color--paper-25);
	color: var(--wp--preset--color--ink);
}

.kv-slider__arrow:disabled {
	cursor: default;
	opacity: 0.35;
}

.kv-slider__arrow:disabled:hover,
.kv-slider__arrow:disabled:focus-visible {
	background: transparent;
	color: var(--wp--preset--color--paper-25);
}

/* Live status: visually hidden position announcement for screen readers
 * (role="status" / aria-live="polite", own text node, no wrapping content
 * siblings — assets/js/slider.js updates the text when the slide changes).
 * Standard visually-hidden snippet: 1px clip so AT still announces it. */
.kv-slider__status {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	white-space: nowrap;
	width: 1px;
	word-wrap: normal !important;
}

/* Dots: 24 x 24, 12px radius (Figma cornerRadius 12), paper-25 outline;
 * active slide fills signal (gelb, wie die aktive Seite der Archiv-Pagination
 * `.kv-archive .wp-block-query-pagination .page-numbers.current`). Hover auf
 * einer nicht-aktiven dot füllt sie wie die Aktuelles-Pills in weißem
 * paper-25; die aktive dot behält ihren signal-Fill. Focus uses the theme
 * signal outline. */
.kv-slider__dots {
	align-items: center;
	display: inline-flex;
	gap: 16px;
}

.kv-slider__dot {
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--paper-25);
	border-radius: 12px;
	box-sizing: border-box;
	cursor: pointer;
	height: 24px;
	padding: 0;
	transition: background-color 160ms ease, border-color 160ms ease;
	width: 24px;
}

.kv-slider__dot:not(.is-active):hover,
.kv-slider__dot:not(.is-active):focus-visible {
	background: var(--wp--preset--color--paper-25);
	border-color: var(--wp--preset--color--paper-25);
}

.kv-slider__dot.is-active {
	background: var(--wp--preset--color--signal);
	border-color: var(--wp--preset--color--signal);
}

/* CTA under the slider, centered (Figma btn-primary on ink: light button).
 * The base background is pure white (#fff) per user request; text stays ink.
 * The selector is scoped on the style class too: the generic
 * `.is-style-primary` alias (signal fill) would otherwise win the cascade
 * (0,3,0 vs 0,2,0) and render the CTA signal/ink on this ink section. */
.kv-wirkung__cta {
	display: flex;
	justify-content: center;
	margin-block-start: clamp(1.5rem, 3.5vw, 3rem);
}

.kv-wirkung__cta .wp-block-button.is-style-primary .wp-block-button__link {
	background: #fff;
	border-radius: 8px;
	color: var(--wp--preset--color--ink);
	padding: 0.75rem 1rem;
}

.kv-wirkung__cta .wp-block-button.is-style-primary .wp-block-button__link:hover,
.kv-wirkung__cta .wp-block-button.is-style-primary .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--paper-25);
	color: var(--wp--preset--color--ink);
}

/* Keyboard: the scroll track itself is focusable (tabindex="0"); give it a
 * visible focus state on the ink surface (signal outline works there). */
.kv-slider__viewport:focus-visible {
	outline: 3px solid var(--wp--preset--color--signal);
	outline-offset: 4px;
}

@media (max-width: 782px) {
	.kv-slider__card-image {
		flex-basis: 100%;
	}

	.kv-slider__slide {
		flex-direction: column;
		gap: 0;
	}
}

/* The theme-wide reduced-motion rule already kills transitions; the smooth
 * scroll-behavior on the track must also become an instant jump there. */
@media (prefers-reduced-motion: reduce) {
	.kv-slider__viewport {
		scroll-behavior: auto;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Testimonials-Slider — section of the `klima-vor-acht/testimonials` block
 * ---------------------------------------------------------------------------
 * Sektion "Stimmen zu unserer Arbeit" (inc/testimonials.php, Phase B – B2)
 * für die Wirkungsseite. Die Sektion übernimmt das `.kv-wirkung`-Muster der
 * Startseite: Breakout über `.kv-section` (1440px-Shell + ink-Fläche über
 * die Core-Farbklassen has-ink-background-color/has-paper-25-color), eigener
 * Kontext `.kv-testimonials` nur für die Sektionstexte. Die Slider-Chrome
 * (Slides, Dots, Pfeile, Status) ist identisch mit dem Wirkung-Slider –
 * `.kv-slider__*` wird wiederverwendet, inklusive der Kontrastbehandlung
 * (gelber aktiver Dot, paper-25-Hover auf nicht-aktiven Dots, ink-Fokus);
 * dieser Abschnitt ergänzt nur die Testimonial-spezifische Slide-Geometrie.
 *
 * Slide-Geometrie (Typ 'testimonial', inc/slider.php, Figma-Spec): Frame-
 * Layout statt Foto-Zitat-Row. `.kv-testimonial-frame` ist ein Flex-
 * Konstrukt mit max-width: 752px (voll ausgelegt: 356 + 40 Gap + 356)
 * und liegt horizontal zentriert im Slide (der Slide selbst bleibt 100 %
 * des Viewports, `justify-content: center`). Die Spalten verteilen die
 * Breite prozentual (`flex: 1 1 calc(50% - 20px)`, bei voller Frame-Breite
 * exakt je 356px): sobald die verfügbare Breite unter 752px fällt (ab
 * Viewport ≈ 950px durch das .kv-section-Inline-Padding), schrumpfen sie
 * proportional statt zu überlaufen. Linke Spalte
 * `.kv-testimonial-frame__copy` (Zitat blockquote + Name-Cite, paper-25
 * auf ink), rechte Spalte `.kv-testimonial-frame__media` (position:
 * relative, max-width: 356px – der Deckel hält die Deko-Ringe am
 * Media-Frame statt bei wenig Platz an der Viewport-Kante, im gestapelten
 * Mobil-Layout bleibt der Frame zentriert): darin das Foto
 * (Pflicht-Foto, 244 × 244,
 * border-radius 24px, object-fit cover, vertikal und horizontal zentriert)
 * und zwei gefüllte Deko-Ringe (Annulus, Loch in der Mitte)
 * `.kv-testimonial-frame__circle` an den äußeren x-Kanten des Media-
 *  Frames (bei voller Frame-Breite ~120px / ~95px, Durchmesser-Bereich
 *  80–135px; unterhalb skaliert beides proportional mit der Media-Breite
 *  – siehe Ringe-Kommentar): die y-Position (top bei beiden Ringen, als
 *  PROZENT der Frame-Höhe – Diagonal-Effekt: ein Ring im oberen Band
 *  0–15 %, der andere zwingend im unteren Band 39–48 % (Signal) bzw.
 *  44–60 % (Leaf), die vertikale Mitte bleibt aus; welcher Ring oben
 *  liegt, entscheidet pro Render zufällig wp_rand( 0, 1 ) – bewusst
 *  kein `$index`-Muster, auch Editor-Vorschau und Frontend dürfen
 *  sich unterscheiden), die Farbe und die
 *  Bandbreite
 *  variieren weiterhin deterministisch pro Slide (Seed = Slide-Index, Farbpool
 * signal/white/leaf/warmweiss-25/mittelblau-50, nie zwei gleiche
 * Ringfarben pro Testimonial; Bandbreiten dünn/regular/dick nach
 * gradkreise.md, über die Slides kommen alle drei vor – siehe
 * inc/slider.php), die Ringe
 * berühren die Außenkanten des Media-Frames an der x-Seite, liegen über
 * dem Foto (z-index) und überdecken es teilweise – pointer-events none
 * und aria-hidden, damit sie Touch- und Tastatur-Nutzung nicht stören.
 * Die Ringe folgen der Theme-Morphologie gradkreise.md: ein `<path>` mit
 * zwei gegenläufigen Kreis-Subpfaden (außen sweep 0, innen sweep 1 →
 * nonzero-fill erzeugt das Loch in der Mitte), fill = Kreisfarbe via
 * currentColor, kein Stroke. Der Slide trägt die Klassenstruktur
 * `.kv-slider__slide kv-slider__slide--testimonial > .kv-testimonial-frame`
 * (siehe inc/slider.php); das Figure-HTML behält seine Klassen
 * `kv-slider__testimonial-photo` / `-el`.
 */

/* Die Sektion fuehrt keine eigenen Farbklassen mehr (inc/testimonials.php):
 * Textfarbe und Flaeche erbt sie vom Sektions-Kontext – auf der Wirkungsseite
 * von der ink-Erfolge-Sektion (paper-Text), sonst vom Seitengrund. */
.kv-testimonials {
	box-sizing: border-box;
	color: inherit;
}

/* Wirkungsseite (Auftrag 30.08., Stand nach dem Umzug): Die Intro-Zeile
 * (Bild + Einleitungstext) gehoert in den Titel-Hero; die Panels-Sektion
 * beginnt direkt mit der Karten-Reihe. Folgt sie auf den Hero, traegt ONLY
 * der Hero das Boden-Padding (80px am 1440px-Shell); ihr Innen-Abstand oben
 * wird auf die ubliche Sektions-Luecke (~112px Gesamtdistanz) eingedampft,
 * sonst stapeln sich 80 + 80 zu einer Luecke von 160px. */
 .kv-wirkung-hero + .kv-panel-section .kv-section__inner {
	padding-block-start: clamp(1.25rem, 2.5vw, 2rem);
}

/* Intro-Zeile im Hero (Umzug 30.08.): Wenn die Intro-Zeile die
 * Hero-Innenflaeche schliesst, wird das Boden-Padding kompakt – die
 * Karten-Reihe der folgenden Panels-Sektion folgt dann mit ~64px
 * Gesamtdistanz (32 + 32) und haelt damit die vom Auftraggeber
 * gewuenschte enge Bindung an "Hier ein Auszug:". */
.kv-wirkung-hero:has(.kv-wirkung-intro) .kv-section__inner {
	padding-block-end: clamp(1.25rem, 2.5vw, 2rem);
}

/* Titel -> Intro-Zeile im Hero (Nachzug 30.08.): fester Top-Abstand von
 * 20px – so nah soll die Intro-Zeile unter der H1 stehen. Explizit statt
 * nur auf den Core-Flow-Gap vertrauend, damit der Wert auch bei anderen
 * Flow-Gap-Einstellungen stabil bleibt. */
.kv-wirkung-hero__copy + .kv-wirkung-intro {
	margin-block-start: 20px;
}

/* Wirkungsseiten-Kontext (Seite 29): Folgt die Testimonials-Sektion direkt
 * auf den Titel-Hero (.kv-wirkung-hero + .kv-testimonials, Adjacent-
 * Sibling – zwischen den Sektionen liegen nur Whitespace-Textknoten, die
 * der Selektorkombinator überspringt), wird ihr padding-block-start
 * gegenüber dem .kv-section-Standard (120px am 1440px-Shell) deutlich
 * reduziert: Der Hero liefert mit seinem eigenen padding-block-end (80px
 * am 1440px-Shell) bereits genug Abstand zur H1. Ohne die Korrektur
 * entstünde zwischen H1-Unterkante und Testimonials-Slider auf der
 * durchgehenden ink-Fläche eine Lücke von ≈200px (80 + 120) – zu viel für
 * den dichten Einstieg der Wirkungsseite. Mit dem kompakten Auftakt
 * (Skala wie der Spenden-CTA, 20–32px) sinkt die Gesamtlücke auf ≈112px
 * am 1440px-Shell (1280: ≈102px, Mobil: ≈60px); die Sektion beginnt damit
 * dicht unter dem Titel, in allen anderen Kontexten (Slider ohne
 * Hero-Vorgänger, eigenständig eingefügt) behält sie den
 * .kv-section-Standard. Der Block rendert seit der User-Entscheidung
 * bewusst keine eigene Sektions-H2 mehr; der Einstieg ist damit noch
 * kompakter, die Regel bleibt für den Slider-Auftakt gültig. */
.kv-wirkung-hero + .kv-testimonials {
	padding-block-start: clamp(1.25rem, 2.5vw, 2rem);
}

/* Wirkungs-Hero -> Testimonials: Die Shell-Korrektur oben reduziert nur das
 * Shell-Padding; das kv-section__inner traegt zusaetzlich sein eigenes
 * padding-block-start (80px) und der Slider seinen 40px-Top-Margin. So
 * stapelt sich ueber die beabsichtigten ~32px hinaus ~152px vor dem Slider
 * (plus Hero-pb 80px -> 232px statt der dokumentierten ~112px). Erstes Kind
 * (Slider; diese Sektion hat bewusst keine H2) dicht unter den Titel, damit
 * die Gesamtluecke der Dokument-Intent (~112px am 1440px-Shell) entspricht. */
.kv-wirkung-hero + .kv-testimonials .kv-section__inner {
	padding-block-start: 0;
}
.kv-wirkung-hero + .kv-testimonials .kv-slider__slider:first-child {
	margin-block-start: 0;
}

/* Testimonial-Slide: Der Slide bleibt 100 % des Viewports; der Frame wird
 * horizontal zentriert (justify-content) und vertikal mittig gehalten. Die
 * 40px-Gap der gebauten Slide-Basis bleibt ohne Wirkung (ein Frame-Kind). */
.kv-slider__slide--testimonial {
	align-items: center;
	justify-content: center;
}

/* Frame: Flex-Row mit 40px Gap, das Gesamtkonstrukt bleibt über
 * max-width auf 752px begrenzt (voll ausgelegt: 356 + 40 Gap + 356,
 * Figma-Spec); die Spalten füllen die Breite prozentual
 * (flex: 1 1 calc(50% - 20px), bei voller Breite je 356px) und schrumpfen
 * proportional, sobald die verfügbare Breite unter 752px fällt. */
.kv-testimonial-frame {
	box-sizing: border-box;
	display: flex;
	flex: 0 0 auto;
	gap: 40px;
	max-width: 752px;
	width: 100%;
}

/* Copy-Spalte: Zitat und Name übereinander, Breite prozentual
 * gleichverteilt (flex: 1 1 calc(50% - 20px), bei voller Frame-Breite
 * 356px wie im Spec); min-width: 0 erlaubt das Schrumpfen. */
.kv-testimonial-frame__copy {
	box-sizing: border-box;
	flex: 1 1 calc(50% - 20px);
	min-width: 0;
}

/* Media-Frame: position relative als Bezug für die absolut positionierten
 * Deko-Kreise; Flex-Zentrierung legt das Foto vertikal und horizontal in
 * die Mitte, unabhängig von der Höhe des Frames (Copy-Spalte kann höher
 * sein). Spaltenbreite prozentual gleichverteilt (flex: 1 1
 * calc(50% - 20px)); max-width: 356px deckelt den Frame, damit die
 * Deko-Ringe an seinen x-Kanten bleiben statt bei wenig Platz an der
 * Viewport-Kante zu hängen, margin-inline: auto zentriert den gedeckelten
 * Frame im gestapelten Mobil-Layout (im Row-Modus wirkungslos, flex-grow
 * füllt die Spalte); min-width: 0 erlaubt das Schrumpfen. */
.kv-testimonial-frame__media {
	align-items: center;
	box-sizing: border-box;
	display: flex;
	flex: 1 1 calc(50% - 20px);
	justify-content: center;
	margin-inline: auto;
	max-width: 356px;
	min-width: 0;
	position: relative;
}

/* Foto: 68,54 % der Media-Frame-Breite (Verhältnis 244/356), bei 356px
 * exakt 244 × 244; aspect-ratio 1/1 (Figure) + height/width 100 % (IMG)
 * halten die Quadratur, 24px Radius bleibt fix, object-fit cover
 * schneidet abweichende Formate auf die Quadratur zu
 * (Größen-Disziplin wie im Spec). */
.kv-slider__testimonial-photo {
	aspect-ratio: 1/1;
	box-sizing: border-box;
	margin: 0;
	width: 68.54%;
}

.kv-slider__testimonial-photo .kv-slider__testimonial-photo-el,
.kv-slider__testimonial-photo-el {
	border-radius: 24px;
	display: block;
	height: 100%;
	object-fit: cover;
	width: 100%;
}

/* Deko-Ringe: gefüllte Ringe (Annulus, Loch in der Mitte) gemäß Theme-
 * Morphologie gradkreise.md (ein `<path>` mit zwei Kreis-Subpfaden, fill =
 * Kreisfarbe via currentColor, kein Stroke), absolut positioniert an den
 * äußeren x-Kanten des Media-Frames (Signal-Ring links, Leaf-Ring rechts),
 * sodass ihre Kanten an der x-Seite der Frame-Außenkanten anliegen und sie
 * das Foto teilweise überdecken; z-index über dem Bild, pointer-events
 * none (stört weder Touch- noch Tastatur-Nutzung), aria-hidden im Markup.
 * Dass die Ringe auch bei schmalen Viewports an den x-Kanten des Media-
 * Frames bleiben statt an der Viewport-Kante zu hängen, sichert
 * max-width: 356px des Media-Frames: das Gesamtkonstrukt ist über
 * max-width: 752px gedeckelt, die prozentual gleichverteilten Spalten
 * (flex: 1 1 calc(50% - 20px)) schrumpfen proportional, im gestapelten
 * Mobil-Layout bleibt der gedeckelte Frame zentriert (margin-inline:
 * auto).
 *  y-Position (top bei beiden Ringen, inline als PROZENT der
 *  Media-Frame-Höhe – Diagonal-Effekt: ein Ring im oberen Band
 *  0–15 %, der andere zwingend im unteren Band 39–48 % (Signal) bzw.
 *  44–60 % (Leaf), die vertikale Mitte bleibt aus; welcher Ring oben
 *  liegt, entscheidet pro Render zufällig wp_rand( 0, 1 ) – bewusst
 *  kein `$index`-Muster, auch Editor-Vorschau und Frontend dürfen sich
 *  unterscheiden), Farbe (color-Token aus dem Pool
 *  signal/white/leaf/warmweiss-25/mittelblau-50) und Bandbreite (Ring-Path
 *  aus dünn/regular/dick, rIn 40.512/33.6/18.24) setzt inc/slider.php
 *  inline pro Slide – y-Position zufällig pro Render, Farbe und Bandbreite
 *  weiterhin deterministisch aus dem Slide-Index (Seed), nie zwei
 * gleiche Ringfarben pro Testimonial, über die Slides kommen alle drei
 * Bandbreiten vor; die Klassen --signal/--leaf tragen nur noch Größe und
 * x-Seite. Der Ring kommt aus dem Path-Fill des viewBox-0-0-100-SVGs, die
 * Farbe aus `color` (SVG-Path fill="currentColor"); Größe über
 * width/height. Die Ringe skalieren proportional zur Media-Frame-Breite:
 * Signal-Ring width 33,71 % (= 120/356, bei 356px exakt 120px), Leaf-Ring
 * width 26,69 % (= 95/356, bei 356px exakt 95px), bei beiden aspect-ratio
 * 1/1 + height auto für die Quadratur. Dadurch bleibt die Teilüberdeckung
 * des Fotos bei jeder Breite konstant, statt bei schmalen Frames zu
 * wachsen; der Figma-Durchmesser-Bereich 80–135px gilt nur bei voller
 * Frame-Breite. */
.kv-testimonial-frame__circle {
	display: block;
	pointer-events: none;
	position: absolute;
	z-index: 1;
}

.kv-testimonial-frame__circle--signal {
	aspect-ratio: 1/1;
	height: auto;
	left: 0;
	width: 33.71%;
}

.kv-testimonial-frame__circle--leaf {
	aspect-ratio: 1/1;
	height: auto;
	right: 0;
	width: 26.69%;
}

/* Zitat: paper-25 auf ink, Typografie nach der Vorgabe "Klasse p-quote"
 * des Auftraggebers (15.08.) – fluid, auf 24px begrenzt: Die Vorgabe
 * waren ursprünglich feste 24px; die Clamp hält 24px auf Desktop ein
 * und skaliert darunter bis 18px. Review-Hinweis: Dieselbe Flüssigkeit
 * wie bei den übrigen Layout-Font-Sizes, damit das Zitat auf schmalen
 * Screens nicht überläuft. Rest der Spec unverändert: 140 % Zeilenhöhe
 * (Auftraggeber 28.08., Zwischenstand 125 %, ursprünglich 100 %),
 * kursiv, Gewicht 400, in der Standard-Schrift (Source Sans 3, keine
 * explizite font-family), ohne abgesetzte Zitat-Linie (keine
 * border-block-start; das frühere padding-block-start der Linie entfällt). */
.kv-testimonial-frame__quote {
	box-sizing: border-box;
	color: inherit;
	font-size: clamp(1.125rem, 2.1vw, 1.5rem);
	font-style: italic;
	font-weight: 400;
	line-height: 140%;
	margin: 0;
	max-width: 56ch;
}

/* Name: cite-Element, "Standardschrift 17/24" nach Vorgabe des
 * Auftraggebers (15.08.) – fluid 15–17px auf 24px Zeilenhöhe, das
 * Maximum 17px entspricht der ursprünglichen festen Vorgabe und bleibt
 * erhalten, darunter skaliert der Text bis 15px; aufrecht
 * (font-style normal), Gewicht 400, in der Standard-Schrift (Source
 * Sans 3, keine explizite font-family), dezente Absetzung vom Zitat
 * über den Block-Abstand. Das em-Dash als Aufzählungszeichen kommt
 * ausschließlich aus dem `::before` (U+2014 + geschütztes
 * Leerzeichen \00a0, absolut am Zeilenanfang); der Namens-Text
 * beginnt bei padding-inline-start 1.5em, und auch der Beruf (nach
 * dem `<br>` im Markup, inc/slider.php) beginnt bei 1.5em – Name und
 * Beruf stehen damit exakt bündig untereinander, ein Umbruch langer
 * Namen hängt weiterhin bei 1.5em ein. Bewusst kein `ul`/`li`-
 * Muster: `cite` erlaubt nur Phrasing Content, Listen-Elemente
 * wären invalide – die ::before-Lösung hält die Cite-Semantik. Der
 * Cite-Text (inc/slider.php) enthält selbst kein em-Dash mehr. */
.kv-testimonial-frame__name {
	box-sizing: border-box;
	color: inherit;
	display: block;
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem);
	font-style: normal;
	font-weight: 400;
	line-height: 24px;
	margin-block-start: 0.75rem;
	padding-inline-start: 1.5em;
	position: relative;
}

.kv-testimonial-frame__name::before {
	content: "—\00a0";
	inset-inline-start: 0;
	position: absolute;
}

/* Mobile (≤782px): Frame und Spalten stapeln vertikal – Media-Frame über
 * der Copy (per order, das Markup bleibt copy-first wie im Desktop-Spec).
 * Im Stack bleibt die Copy-Spalte voll breit; der Media-Frame ist
 * width: 100%, wird aber durch max-width: 356px gedeckelt und horizontal
 * zentriert (margin-inline: auto + align-self: center) – die Deko-Ringe
 * bleiben damit am Foto statt an der Viewport-Kante. Im Stack und bei
 * schmalen Frames skalieren Foto und Ringe proportional mit der
 * Media-Frame-Breite (68,54 % bzw. 33,71 %/26,69 %); einen fixen
 * 96/80-Override gibt es nicht mehr. */
@media (max-width: 782px) {
	.kv-testimonial-frame {
		flex-direction: column;
		gap: 1.25rem;
		max-width: 100%;
	}

	.kv-testimonial-frame__copy,
	.kv-testimonial-frame__media {
		flex: 0 0 auto;
		width: 100%;
	}

	/* Media-Frame im Stack explizit horizontal zentrieren: die Basisregel
	 * deckelt den Frame über max-width: 356px und zentriert ihn via
	 * margin-inline: auto – align-self: center macht die Zentrierung
	 * robust gegen künftige Refactors, die margin-inline entfernen. */
	.kv-testimonial-frame__media {
		align-self: center;
		order: -1;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Wirkungsseite – Title-Hero (Pattern wirkung-hero.php)
 * ---------------------------------------------------------------------------
 * Titel-Hero der Wirkungsseite (Vorlage wirkung.html, Phasen C1/C2): die
 * Sektion ist die erste des Seiteninhalts, liegt bündig unter dem ink-
 * Header und spannt als .kv-section-Breakout die 1440px-Shell. Die ink-
 * Fläche kommt aus den Core-Farbklassen der Pattern-Sektion
 * (has-ink-background-color / has-paper-25-color, 11.85:1 WCAG AA/AAA),
 * die eigenen Farb-/Textdeklarationen sind nur der Fallback für den
 * Sektions-Kontext (Muster .kv-wirkung/.kv-testimonials). Das Vertikal-
 * Padding ist kompakter als der .kv-section-Standard (120px am 1440px-
 * Shell): 40–80px, skaliert wie der Spenden-CTA (gleiche "clay"-Werte),
 * damit der Einstieg der Wirkungsseite dicht und knapp unter dem Header
 * bleibt.
 *
 * Geometrie (15.08.): Seit der C1-Korrektur trägt der Hero nur noch die
 * H1, ohne Bild und ohne einleitende Textbausteine; der copy-Stack läuft
 * ohne Grid-Wrapper über die volle Breite der .kv-section-Shell. Das
 * frühere 1/3–2/3-Spaltenpaar (.kv-wirkung-hero__grid / __media) ist
 * ersatzlos entfernt, ebenso der einspaltige Fallback für ≤782px.
 *
 * Untertitel (16.08.): Der gebundene Untertitel (p.kv-post-subtitle,
 * wps_subtitle-Meta-Binding) steht als Schwester direkt unter der H1 im
 * copy-Stack – Textfarbe paper-25 (has-paper-25-color), Größe x-large
 * (immer größer als die 24px von p.has-large-font-size); die Vergrößerung
 * gilt nur im Wirkungs-Hero, nicht in den Artikel-/Seiten-Templates. Der
 * Abstand regelt der Geschwister-Selektor im Abschnitt "Post-Templates:
 * Untertitel + Teaser-Spalten". Ist das Meta leer, blendet
 * p.kv-post-subtitle:empty die Zeile aus; der Hero bleibt unverändert.
 */
.kv-wirkung-hero .kv-section__inner {
	box-sizing: border-box;
	color: var(--wp--preset--color--paper-25);
	padding-block: clamp(2.5rem, 8vw, 5rem);
}

/* Die H1 (huge) liegt direkt im copy-Stack, der Rhythmus folgt dem
 * globalen Block-Gap. */
.kv-wirkung-hero__copy .wp-block-heading {
	margin: 0;
}

@media (min-width: 1440px) {
	.kv-wirkung-hero .kv-section__inner {
		padding-block: 80px;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Wirkungsseite – Social Proof (Block klima-vor-acht/social-proof)
 * ---------------------------------------------------------------------------
 * Die Social-Proof-Sektion rendert der Block `klima-vor-acht/social-proof`
 * (inc/social-proof.php) seit dem Slider-Umbau vollständig selbst: eine
 * eigenständige, überall im Inserter einfügbare paper-Sektion (kv-section
 * kv-social-proof-section, H2/Intro inklusive – Muster des Testimonials-
 * Blocks). Die veröffentlichten Einträge liegen als Zitat-Slides (Slide-Typ
 * 'social-proof', inc/slider.php, Wiederverwendung des Karten-Markups
 * `.kv-social-proof`) in der zentralen Slider-Chrome
 * `klima_vor_acht_render_slider()`, die IN der Sektion zwischen Intro und
 * Sektionsende steht. Das frühere Rahmen-Pattern wirkung-social-proof.php
 * entfällt (Task 2); das Medien-Logos-Laufband `klima-vor-acht/logos-laufband`
 * (inc/logos-laufband.php) ist seitdem eine eigene, ebenfalls
 * eigenständige Sektion (Regeln dafür siehe Abschnitt "Medien-Laufband –
 * eigenständige Sektion" unten). Die
 * paper-Fläche und der 1440px-Breakout kommen aus .kv-section + den Core-
 * Farbklassen der Block-Sektion; dieser Abschnitt liefert nur die
 * Sektions-Ebene: Abstände, Slide-Layout, Zitat-Karten-Optik, die
 * paper-Variante der Slider-Pagination und (harmloser Rest) die
 * Button-Zeilen-Ausrichtung.
 *
 * Sektions-Rhythmus: Die Kinder der section-Group liegen als Flow-Stack.
 * Zwischen den Blöcken (H2 → Intro → Slider) gilt der große,
 * geklemmte Sektions-Gap clamp(1.5rem, 3vw, 2.5rem) (24–40px) – dieselbe
 * Design-Sprache wie .kv-post-cta > * + *; nur die eng zusammengehörige
 * Intro-Zeile aus H2 + Einleitungsabsatz behält den normalen Fließtext-
 * Abstand (1.25rem, Core-Flow-Default). Beide Regeln sind bewusst nur
 * selektiv gesetzt, damit die globalen Core-Flow-Margins
 * (:root :where(.is-layout-flow) > * + *) im Karten-/Laufband-Inneren
 * unangetastet bleiben.
 *
 * Zitat-Karte .kv-social-proof: Das Karten-Markup (H3, optionale Subline,
 * blockquote mit Zitat + Quelle) rendert der Slide-Renderer der zentralen
 * Slider-Chrome (Slide-Typ 'social-proof', inc/slider.php) für jeden
 * Eintrag; die Karten-Optik übernimmt diese Sektionsebene nach der
 * .kv-panel--card-Konvention (paper-25-Fläche, 16px Radius, 2rem Padding).
 * Im Slider füllt die Karte die volle Slide-Breite (siehe
 * .kv-slider__slide--social-proof unten), damit der Slider wie eine
 * übergroße Zitat-Sektion wirkt. Innen der Stack: H3-Titel (large,
 * Heading-Font IBM Plex Sans aus dem element-heading-Style von theme.json),
 * Subline als decenter Uppercase-Kicker (identisch zum Laufband-Label),
 * blockquote großzügig (medium-large, 600er IBM Plex Sans, signal-Zitatlinie
 * links) und die Quelle als schmale, klein gesetzte Cite-Zeile über der
 * Zitatlinie.
 *
 * Slider-Pagination auf paper: Die Basis-Regeln der Slider-Chrome (Arrows +
 * Dots, Abschnitt "Kv8-Slider") sind auf ink/paper-25 ausgelegt; die
 * paper-Variante unten färbt die Pagination auf ink um (inkl.
 * Hover/Focus-Fill und signal-dot für die aktive Position).
 * .kv-slider__viewport:focus-visible (signal outline) funktioniert auf
 * paper ebenfalls – keine Änderung nötig.
 *
 * Rest: Die (harmlose) Button-Zeilen-Regel `.wp-block-buttons` aus der
 * Karten-Phase bleibt bestehen; der Slider ist der neue Sektionsabschluss.
 */

.kv-social-proof-section .kv-section__inner > * + * {
	margin-block-start: clamp(1.5rem, 3vw, 2.5rem);
}

/* Intro-Zeile (H2 + Einleitungsabsatz) dicht – normale Fließtext-Lücke
 * statt des großen Sektions-Gaps. */
.kv-social-proof-section .kv-section__inner > .wp-block-heading + p {
	margin-block-start: 1.25rem;
}

/* PHP-gerenderte Sektion (kein is-layout-flow): das erste Kind dicht am
 * oberen Sektionsrand. Core-`is-layout-flow` wuerde margin-block-start des
 * ersten Kindes sonst auf 0 setzen; das Sektions-Padding liefert den
 * Rhythmus. */
.kv-social-proof-section .kv-section__inner > :first-child {
	margin-block-start: 0;
}

/* Zitat-Karte: paper-25-Fläche, 16px Radius, 2rem Padding (Karten-Panel-
 * Werte). Papier-auf-Papier-Abstufung (paper-25 auf paper) setzt die Karte
 * dezent von der Sektionsfläche ab. */
.kv-social-proof {
	background: var(--wp--preset--color--paper-25);
	border-radius: 16px;
	box-sizing: border-box;
	padding: 2rem;
}

.kv-social-proof__title {
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--large);
	margin: 0;
}

/* Subline: Kicker-Stil (identisch zum Laufband-Label: IBM Plex Sans,
 * 0.875rem, 600, Uppercase, dezente Transparenz) – redaktionelles Etikett
 * über dem Zitat, z. B. "Presse". */
.kv-social-proof__subline {
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: 0.875rem;
	font-weight: 600;
	letter-spacing: 0.02em;
	margin: 0;
	opacity: 0.7;
	text-transform: uppercase;
}

/* Quelle als schmale Cite-Zeile über der Zitatlinie: klein, IBM Plex Sans,
 * 600, leicht gesperrt – bewusst im Gegensatz zum großen Fließtext des
 * Zitats. */
.kv-social-proof__source {
	color: var(--wp--preset--color--ink);
	display: block;
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: var(--wp--preset--font-size--small);
	font-style: normal;
	font-weight: 600;
	letter-spacing: 0.04em;
	line-height: 1.45;
	margin-block-start: 1rem;
}

/* Beruf der zitierten Person (Buch-Zitate-Slider): direkt unter dem
 * Namen (cite) – gleiche Größenstaffel wie die Quelle, aber ohne
 * Uppercase/Sperrung (Redaktionsvorgabe 20.09.2026: Beruf "normal"
 * lesbar), dezente Transparenz zur Absetzung vom Zitattext. */
.kv-social-proof__role {
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 400;
	line-height: 1.45;
	margin: 0.25rem 0 0;
	opacity: 0.75;
}

/* Zitat (blockquote): großzügig gesetzt (medium-large-Clamp 20–28px),
 * 600er IBM Plex Sans, mit dezenter signal-Zitatlinie links (Anker zur
 * Zitathaftigkeit, wie die Testimonial-Zitate ihre signal-Markierung
 * tragen). */
.kv-social-proof__quote {
	border-inline-start: 4px solid var(--wp--preset--color--signal);
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: var(--wp--preset--font-size--medium-large);
	font-weight: 600;
	line-height: 1.4;
	margin: 0;
	max-width: 62ch;
	padding-inline-start: 1.5rem;
}

.kv-social-proof__quote p {
	margin: 0;
}

.kv-social-proof__quote p + p {
	margin-block-start: 1rem;
}

/* Innerer Stack-Gap der Karte (Spiegel der .kv-panel--card > * + *-Regel,
 * 24px): bewusst NACH den margin:0-Shorthands der Elemente (__title,
 * __subline, __quote) positioniert — gleiche Spezifität (0,1,0), die
 * Quellreihenfolge entscheidet. Vor 15.09. stand die Regel vor den
 * Element-Regeln und wurde dort von deren margin:0 kaskadisch erschlagen
 * (Abstand Titel→Zitat 0px statt 24px). Der __source-abstand (1rem, unten)
 * gilt innerhalb des Blockquotes und bleibt unberührt. */
.kv-social-proof > * + * {
	margin-block-start: 1.5rem;
}

/* Abschluss-CTA: zentrierte Button-Zeile (Ghost-Button secondary-ink, die
 * System-Regel trägt die Optik); der Sektions-Gap oben sorgt für den Abstand
 * zum Laufband. */
.kv-social-proof-section .wp-block-buttons {
	justify-content: center;
}

/* Slide-Layout: Die Slider-Chrome steckt IN der Sektion; die Zitat-Karte
 * füllt die volle Slide-Breite, damit der Slider wie eine übergroße
 * Zitat-Sektion wirkt (eine große Karte statt Kacheln). box-sizing steckt
 * bereits in .kv-social-proof. */
.kv-slider__slide--social-proof {
	align-items: stretch;
}

.kv-slider__slide--social-proof .kv-social-proof {
	flex: 1 1 auto;
	min-width: 0;
	width: 100%;
}
/* Wirkungsseiten-Social-Proof (ink): Die paper-25-Karte bleibt STATISCH -
 * nur der Inhalt gleitet. Dafür liegt die paper-25-Fläche samt 16px-Radius
 * auf der Slider-Fläche (.kv-slider__viewport). Der Viewport ist der
 * Scroll-Container und wandert beim Sliden nicht mit; overflow-y: hidden
 * erweitert den Radius-Clip, sodass die Slides an den runden Ecken
 * abgeschnitten werden und dahinter paper-25 statt ink liegt. So zeigen die
 * abgerundeten Stoßkanten beim Sliden KEINE blauen Ecken; der Slide selbst
 * ist nur noch ein transparenter Text-Panel. Buch-Zitate (paper) bleiben
 * unverändert. */
.kv-social-proof-section:not(.kv-buch-zitate-section) .kv-slider__viewport {
	background: var(--wp--preset--color--paper-25);
	border-radius: 16px;
	overflow-y: hidden;
}
.kv-social-proof-section:not(.kv-buch-zitate-section) .kv-social-proof {
	background: transparent;
	border-radius: 0;
}

/* Pagination auf paper (nur noch Buch-Zitate: kv-social-proof-section in
 * Kombination mit kv-buch-zitate-section): Die Basis-Regeln der
 * Slider-Chrome sind auf ink/paper-25 ausgelegt; hier die ink-Variante
 * für die paper-Sektion (Arrows + Dots, Hover/Focus-Fill, aktive dot
 * signal). Die Transitions kommen aus den Basis-Regeln. Die
 * Wirkungsseiten-Social-Proof-Sektion (kv-social-proof-section ohne
 * kv-buch-zitate-section) ist seit dem Farbtausch ink und nutzt das
 * ink/paper-25 Basis-Chrome. */
.kv-social-proof-section.kv-buch-zitate-section .kv-slider__arrow {
	color: var(--wp--preset--color--ink);
}

.kv-social-proof-section.kv-buch-zitate-section .kv-slider__arrow:hover,
.kv-social-proof-section.kv-buch-zitate-section .kv-slider__arrow:focus-visible {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

.kv-social-proof-section.kv-buch-zitate-section .kv-slider__arrow:disabled {
	opacity: 0.35;
}

.kv-social-proof-section.kv-buch-zitate-section .kv-slider__arrow:disabled:hover,
.kv-social-proof-section.kv-buch-zitate-section .kv-slider__arrow:disabled:focus-visible {
	background: transparent;
	color: var(--wp--preset--color--ink);
}

.kv-social-proof-section.kv-buch-zitate-section .kv-slider__dot {
	border: 1.5px solid var(--wp--preset--color--ink);
}

.kv-social-proof-section.kv-buch-zitate-section .kv-slider__dot:not(.is-active):hover,
.kv-social-proof-section.kv-buch-zitate-section .kv-slider__dot:not(.is-active):focus-visible {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
}

.kv-social-proof-section.kv-buch-zitate-section .kv-slider__dot.is-active {
	background: var(--wp--preset--color--signal);
	border-color: var(--wp--preset--color--signal);
}

/* Pagination auf paper (Erfolge-Sektion, kv-wirkung-erfolge): Der
 * Testimonials-Block sitzt seit dem Farbtausch auf paper; sein
 * Slider-Chrome erbte sonst das ink/paper-25-Basis-Chrome und wäre
 * dort unsichtbar. Hier die ink-Variante für die paper-Sektion -
 * identisch zum ink-Chrome der paper-Buch-Zitate-Sektion. */
.kv-wirkung-erfolge .kv-slider__arrow {
	color: var(--wp--preset--color--ink);
}

.kv-wirkung-erfolge .kv-slider__arrow:hover,
.kv-wirkung-erfolge .kv-slider__arrow:focus-visible {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

.kv-wirkung-erfolge .kv-slider__arrow:disabled {
	opacity: 0.35;
}

.kv-wirkung-erfolge .kv-slider__arrow:disabled:hover,
.kv-wirkung-erfolge .kv-slider__arrow:disabled:focus-visible {
	background: transparent;
	color: var(--wp--preset--color--ink);
}

.kv-wirkung-erfolge .kv-slider__dot {
	border: 1.5px solid var(--wp--preset--color--ink);
}

.kv-wirkung-erfolge .kv-slider__dot:not(.is-active):hover,
.kv-wirkung-erfolge .kv-slider__dot:not(.is-active):focus-visible {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
}

.kv-wirkung-erfolge .kv-slider__dot.is-active {
	background: var(--wp--preset--color--signal);
	border-color: var(--wp--preset--color--signal);
}

/*
 * ---------------------------------------------------------------------------
 * Über uns – Sektion "Unsere Message in den Medien" (Auftrag 09.09.)
 * ---------------------------------------------------------------------------
 * Die Sektion steht im Seiteninhalt der Über-uns-Seite (Seite 32) und
 * kombiniert die beiden Wirkungsseiten-Komponenten auf EINER paper-Fläche:
 * oben der Social-Proof-Slider (Block klima-vor-acht/social-proof, gleiche
 * Arbeitsteilung wie auf der Wirkungsseite – Sektions-Hülle, H2 und Intro-
 * Absatz stehen im Seiteninhalt, die Chrome liefert der Block), darunter
 * das Medien-Laufband als eigene paper-Sektion (Block
 * klima-vor-acht/logos-laufband). Beide Flächen laufen ohne Trennlinie
 * ineinander – die paper-Sektionen grenzen aneinander an, der
 * Sektions-Padding-Rhythmus liefert den Abstand. Die Zitat-Karten behalten
 * ihre Basis-Optik (paper-25 auf paper, .kv-social-proof-Regeln oben); nur
 * die Slider-Pagination braucht die ink-Variante (identisch zu
 * kv-buch-zitate-section und kv-wirkung-erfolge). assets/js/slider.js lädt
 * seit diesem Auftrag auch hier (klima_vor_acht_has_social_proof_block(),
 * functions.php).
 */

.kv-ueber-medien .kv-section__inner > * + * {
	margin-block-start: clamp(1.5rem, 3vw, 2.5rem);
}

/* Intro-Zeile (H2 + Einleitungsabsatz) dicht – normale Fließtext-Lücke
 * statt des großen Sektions-Gaps (wie .kv-social-proof-section). */
.kv-ueber-medien .kv-section__inner > .wp-block-heading + p {
	margin-block-start: 1.25rem;
}

/* Statisch gerenderte Sektion (kein is-layout-flow): das erste Kind dicht am
 * oberen Sektionsrand; das Sektions-Padding liefert den Rhythmus. */
.kv-ueber-medien .kv-section__inner > :first-child {
	margin-block-start: 0;
}

/* Pagination auf paper (Über-uns-Medien-Sektion): ink-Variante der
 * Slider-Chrome, identisch zu kv-wirkung-erfolge und kv-buch-zitate-section
 * (Arrows + Dots, Hover/Focus-Fill, aktive dot signal). Die Transitions
 * kommen aus den Basis-Regeln. */
.kv-ueber-medien .kv-slider__arrow {
	color: var(--wp--preset--color--ink);
}

.kv-ueber-medien .kv-slider__arrow:hover,
.kv-ueber-medien .kv-slider__arrow:focus-visible {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

.kv-ueber-medien .kv-slider__arrow:disabled {
	opacity: 0.35;
}

.kv-ueber-medien .kv-slider__arrow:disabled:hover,
.kv-ueber-medien .kv-slider__arrow:disabled:focus-visible {
	background: transparent;
	color: var(--wp--preset--color--ink);
}

.kv-ueber-medien .kv-slider__dot {
	border: 1.5px solid var(--wp--preset--color--ink);
}

.kv-ueber-medien .kv-slider__dot:not(.is-active):hover,
.kv-ueber-medien .kv-slider__dot:not(.is-active):focus-visible {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
}

.kv-ueber-medien .kv-slider__dot.is-active {
	background: var(--wp--preset--color--signal);
	border-color: var(--wp--preset--color--signal);
}

/*
 * ---------------------------------------------------------------------------
 * Medien-Laufband – eigenständige Sektion (Block klima-vor-acht/logos-laufband)
 * ---------------------------------------------------------------------------
 * Rhythmus innerhalb der eigenständigen Laufband-Sektion (Komponente,
 * Block klima-vor-acht/logos-laufband): der große geklemmte Sektions-
 * Gap zwischen optionaler h2 und dem Laufband, identische Design-
 * Sprache wie .kv-social-proof-section > * + *. Das Laufband-Chrome-CSS
 * selbst (Marquee, Hover-Pause, reduced-motion) liegt im Abschnitt
 * "Logos-Laufband" weiter oben.
 */

.kv-media-laufband-section .kv-section__inner > * + * {
	margin-block-start: clamp(1.5rem, 3vw, 2.5rem);
}

/*
 * ---------------------------------------------------------------------------
 * Kontaktformular (WPForms, Seite /kontakt/)
 * ---------------------------------------------------------------------------
 * WPForms-Einstellung "Basis-Styling: none" (wpforms_settings disable-css = 3):
 * das Plugin lädt nur wpforms-no-styles.css (Utility-Klassen, keine sichtbare
 * Optik), damit keine WPForms-Default-Styles mit dem Theme kollidieren. Die
 * gesamte Formular-Optik stammt aus diesem Abschnitt. Scope ist die
 * Form-Klasse `kv-contact-form` (form_class des WPForms-Formulars, liegt auf
 * dem `.wpforms-container`-Element), unabhängig von wpforms-container-full.
 *
 * Felder: angelehnt an den Newsletter-Input im Footer (.kv-newsletter-form
 * input: 1px Border, 6px Radius, 2.75rem Mindesthöhe). Auf dem hellen Grund
 * nutzen sie den Theme-eigenen dezenten Border-Token (--kv-border, ink bei
 * 16 %) statt des ink-Volltons; Fokus = signal-Outline (offset 2px, dicht am
 * Feld) plus ink-Border zum bestehenden Theme-Fokus (3px signal, oben global).
 *
 * Senden-Button = Primary-System primary-ink auf heller Fläche (vgl.
 * Button-System-Abschnitt): ink-Füllung / paper-25-Text, Radius 8px, Padding
 * 0.75rem/1rem (12/16px), 17px/600/letter-spacing 0.02em; Hover/Focus hellt
 * die Füllung auf dunkelblau-75 #3F62AD auf, Text bleibt paper-25 (5.80:1 AA).
 *
 * Fehler: das Theme hat kein Rot-Token; #B3261E (Material Error, Kontrast
 * ~6:1 auf paper) ist eine dokumentierte Ausnahme für die Fehlersemantik auf
 * dem hellen Grund.
 */
.kv-contact-form .wpforms-field {
	margin: 0 0 1.25rem;
}

.kv-contact-form .wpforms-field-label {
	color: var(--wp--preset--color--ink);
	display: block;
	font-size: clamp(0.875rem, 1.5vw, 1rem);
	font-weight: 600;
	line-height: 1.4;
	margin-bottom: 0.4rem;
}

.kv-contact-form .wpforms-required-label {
	color: var(--wp--preset--color--ink);
}

/* 17.08. iOS-Zoomschutz wie beim Newsletter-Input: font-size-Clamp NACH
 * dem font:-Shorthand (16–18px, nie unter 1rem). */
.kv-contact-form input[type="text"],
.kv-contact-form input[type="email"],
.kv-contact-form textarea {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--kv-border);
	border-radius: 6px;
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	font: inherit;
	font-size: clamp(1rem, 1.6vw, 1.125rem);
	line-height: 1.5;
	min-height: 2.75rem;
	padding: 0.65rem 0.875rem;
	width: 100%;
}

.kv-contact-form textarea {
	min-height: 9rem;
	padding: 0.75rem 0.875rem;
	resize: vertical;
}

.kv-contact-form input::placeholder,
.kv-contact-form textarea::placeholder {
	color: rgba(5, 43, 142, 0.55);
}

.kv-contact-form input:focus-visible,
.kv-contact-form textarea:focus-visible {
	border-color: var(--wp--preset--color--ink);
	outline: 3px solid var(--wp--preset--color--signal);
	outline-offset: 2px;
}

/* Fehlerzustand (clientseitige WPForms-Validierung). */
.kv-contact-form input.wpforms-error,
.kv-contact-form textarea.wpforms-error {
	border-color: #b3261e;
}

.kv-contact-form label.wpforms-error,
.kv-contact-form .wpforms-error-container .wpforms-error {
	color: #b3261e;
	font-weight: 600;
}

.kv-contact-form .wpforms-error-container {
	margin-bottom: 1rem;
}

/* Submit = Primary-System primary-ink auf heller Fläche. Das Submit ist ein
 * natives <button>-Element und KEIN .wp-block-button-System-Button: Seine
 * Größe bleibt bewusst bei 15–17px und wird nicht von der späteren
 * Button-Cap berührt. */
.kv-contact-form .wpforms-submit-container {
	margin-top: 1.75rem;
}

.kv-contact-form button.wpforms-submit {
	background: var(--wp--preset--color--ink);
	border: 0;
	border-radius: 8px;
	color: var(--wp--preset--color--paper-25);
	cursor: pointer;
	font-family: inherit;
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem);
	font-weight: 600;
	letter-spacing: 0.02em;
	line-height: 1.2;
	padding: 0.75rem 1rem;
}

.kv-contact-form button.wpforms-submit:hover,
.kv-contact-form button.wpforms-submit:focus-visible {
	background: #3F62AD;
	color: var(--wp--preset--color--paper-25);
}

/*
 * Bestätigungsmeldung (Erfolgszustand nach dem Absenden). WPForms ersetzt
 * das Formular bei AJAX-Submit durch div.wpforms-confirmation-container
 * (ohne dessen eigene Optik, da Basis-Styling: none), das innerhalb von
 * .kv-contact-form liegt, und scrollt per message_scroll dorthin. Ohne
 * eigene Regeln war diese Meldung kaum vom Seiteninhalt zu unterscheiden;
 * hier erhält sie eine klare Erfolgsfläche im Türkis-Branding (leaf auf
 * tuerkis-25), analog zur Fehlerfläche in #B3261E.
 *
 * Aufbau: gefüllte, abgesetzte Fläche mit kräftigem linker Kante, einem
 * Häkchen vor der Meldung und hervorgehobenem Text. Text bleibt ink, das
 * Häkchen nutzt die gleiche Textfarbe, damit das Symbol auch schmal satt
 * lesbar bleibt (Erfolg wird zusätzlich über die Meldung selbst vermittelt,
 * nicht nur über die Farbe).
 */
.kv-contact-form .wpforms-confirmation-container {
	background: var(--wp--preset--color--tuerkis-25);
	border: 1px solid var(--wp--preset--color--leaf);
	border-left: 4px solid var(--wp--preset--color--leaf);
	border-radius: 6px;
	color: var(--wp--preset--color--ink);
	display: flex;
	gap: 0.75rem;
	align-items: flex-start;
	margin: 0 0 1.25rem;
	padding: 1.25rem 1.5rem;
}

.kv-contact-form .wpforms-confirmation-container::before {
	align-self: center;
	color: var(--wp--preset--color--ink);
	content: "✓";
	font-size: clamp(1.125rem, 2.1vw, 1.5rem);
	font-weight: 700;
	line-height: 1;
}

.kv-contact-form .wpforms-confirmation-container p {
	font-size: clamp(1rem, 1.6vw, 1.125rem);
	font-weight: 600;
	line-height: 1.45;
	margin: 0;
}

.kv-contact-form .wpforms-confirmation-container a {
	color: var(--wp--preset--color--ink);
}

/* E-Mail-Alternative unter dem Formular: eigener Absatz im Fluss. */
.kv-contact-alternative {
	margin-top: 1.5rem;
}

/*
 * Kontaktseite: Inhalt in der 752px-contentSize (theme.json-Default) halten.
 * Hinweis: templates/page.html legt den post-content aktuell auf alignwide
 * (1136px) — das gilt für alle Standardseiten. Für die Kontaktseite greift
 * die schmalere Inhalts-Spalte (Formularfelder sind bei 1136px zu breit),
 * ohne das Template oder Bestandsseiten zu verändern.
 */
body.page-id-103 .wp-block-post-content {
	max-width: 752px;
}

/*
 * ---------------------------------------------------------------------------
 * Newsletter-Seite (/newsletter/, Seiten-ID 108)
 * ---------------------------------------------------------------------------
 * Inhalt auf 752px-contentSize halten — gleicher Mechanismus wie die
 * Kontaktseite (templates/page.html legt den post-content auf alignwide,
 * 1136px; fürs schmale Formular greift hier die schmalere Spalte).
 */
body.page-id-108 .wp-block-post-content {
	max-width: 752px;
}

/*
 * Seiten-Formular: Variante des Footer-Formulars auf heller Fläche. Das
 * Markup teilt die Basis-Klassen (.kv-newsletter-form) und damit die
 * Footer-Regeln (dunkler Input, paper-Button) — die Regeln unten sind
 * gezielt über `.kv-newsletter-page-form` (die zusätzliche Klasse auf dem
 * Formular-Element der Seite) gescopet und gewinnen durch höhere Spezifität.
 *
 * Input: wie die Kontaktformular-Felder — weiß, 1px --kv-border (ink bei
 * 16 %), 2.75rem Mindesthöhe, Fokus signal-Outline dicht am Feld (offset 2px)
 * plus ink-Border.
 *
 * 09.08. Nahtlose Verbindung (wie im Footer): E-Mail-Feld und Button
 * stoßen an der inneren Kontaktkante ohne Radius aneinander — input
 * border-radius 6px 0 0 6px, button 0 8px 8px 0. Die äußeren Ecken behalten
 * ihren Radius (input 6px, button 8px). Das Layout bleibt auch schmal eine
 * Zeile (flex, nowrap; siehe Media-Query ≤ 782px), ein gestapelter Fall
 * existiert nicht — die nahtlose Kante gilt damit auf allen Breiten.
 *
 * Button: Primary-System primary-ink auf heller Fläche (konsistent zum
 * WPForms-Submit auf /kontakt/): ink-Füllung / paper-25-Text, Radius 8px,
 * Hover/Focus dunkelblau-75 #3F62AD, Text bleibt paper-25. Der Pfeil-SVG im
 * Markup ist hard-kodiert ink (#052B8E); auf dem dunklen Button wird er über
 * fill: currentColor an die paper-25-Textfarbe gekoppelt.
 *
 * Die globale "Kompakte Chrome"-Regel (3px vertikales Padding für
 * .kv-newsletter-form input/button, weiter oben im Stylesheet) gilt nur
 * für Header/Footer-Kontext; hier im Seiten-Inhalt setzen wir die
 * großzügigeren Maße des Primary-Systems wieder (0.65rem/0.75rem vertikal).
 */
.kv-newsletter-page-form input {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--kv-border);
	border-radius: 6px 0 0 6px;
	color: var(--wp--preset--color--ink);
	padding: 0.65rem 0.875rem;
}

.kv-newsletter-page-form input::placeholder {
	color: rgba(5, 43, 142, 0.55);
}

.kv-newsletter-page-form input:focus-visible {
	border-color: var(--wp--preset--color--ink);
	outline: 3px solid var(--wp--preset--color--signal);
	outline-offset: 2px;
}

.kv-newsletter-page-form button {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	border-radius: 0 8px 8px 0;
	color: var(--wp--preset--color--paper-25);
	padding: 0.75rem 1.1rem;
}

.kv-newsletter-page-form button svg path {
	fill: currentColor;
}

.kv-newsletter-page-form button:hover,
.kv-newsletter-page-form button:focus-visible {
	background: #3F62AD;
	border-color: #3F62AD;
	color: var(--wp--preset--color--paper-25);
}

/*
 * Hinweis unter dem Anmeldeformular (Double-Opt-In + Datenschutzlink):
 * gedämpfter ink-Text, in normaler Schriftgröße auf der Clamp-Spanne
 * 1rem–1.125rem (16–18px, die Body-Größe aus theme.json
 * styles.typography.fontSize als oberes Ende) — die Markup-Klasse
 * has-small-font-size (0.875rem, Utility mit !important) wird per
 * Seiten-Scope überschrieben, damit der Footer-Hinweis (.kv-footer-hint,
 * weiter oben, bewusst klein) unverändert bleibt.
 * Kontrast der 75 %-Tönung auf paper ≈ 5.8:1 (AA auch für Fließtext).
 */
.kv-newsletter-hint {
	color: rgba(5, 43, 142, 0.75);
	margin-top: 1rem;
}

body.page-id-108 .kv-newsletter-hint {
	font-size: clamp(1rem, 1.6vw, 1.125rem) !important;
}

/*
 * 09.08. Mehr Abstand vor dem "Newsletter-Archiv"-Abschnitt: Der h2 folgt
 * direkt auf den Hinweis; statt eines Trennelements (Auftrag "ggf.") wird
 * der Bestand (1.25rem Flow-Gap der is-layout-flow-Regel) um 2rem erhöht —
 * final 3.25rem (52px) zwischen Hinweis-Unterkante und Archiv-Titel. Der
 * Geschwister-Selektor schlägt den :where()-Flow-Gap (Spezifität 0) und
 * bleibt auf diese eine Seitenstruktur gescoped.
 */
body.page-id-108 .kv-newsletter-hint + h2 {
	margin-top: 3.25rem;
}

/*
 * ---------------------------------------------------------------------------
 * Post-Templates: Untertitel + Teaser-Spalten
 * ---------------------------------------------------------------------------
 * Beiträge rendern über templates/single.html bzw. single-fullwidth.html die
 * H1 (wp-block-post-title) und den darunter gebundenen Untertitel
 * (p.kv-post-subtitle, Block-Binding auf das `wps_subtitle`-Meta). Farbe
 * (ink) und Größe (has-large-font-size) kommen aus dem Template-Markup und
 * tragen dort `!important` (has-ink-color / has-large-font-size) — hier wird
 * nur Typo (IBM Plex Sans, normale Stärke), Zeilenhöhe und der enge Abstand
 * unter der H1 gesetzt. Die Flow-Gap-Regel von Core (`is-layout-flow > *`,
 * margin-block-start: 1.25rem) wird über den Geschwister-Selektor
 * (höhere Spezifität) bewusst unterschritten.
 *
 * Dieselben Regeln gelten für Seiten (page.html/presse.html, gleiches
 * Template-Markup) und für den Title-Hero der Wirkungsseite: Dort steht der
 * gebundene Untertitel als Schwester der huge-H1 im kv-wirkung-hero__copy-
 * Stack (Textfarbe paper-25 auf der ink-Fläche). Der Abstand unter der
 * huge-H1 ist großzügiger als bei den Artikeltiteln, bleibt aber kompakt
 * (12–24px statt der Core-Flow-Gap von 20px). Die Schriftgröße des Hero-
 * Untertitels weicht bewusst ab: Er läuft auf x-large (30–48px, Regel direkt
 * unter p.kv-post-subtitle) statt der 24px von p.has-large-font-size; die
 * Artikel-/Seiten-Untertitel bleiben bei 24px.
 *
 * Der leere Untertitel (Beitrag/Seite ohne `wps_subtitle`-Meta) wird per
 * `:empty` komplett ausgeblendet; der Folgeblock (Feature-Image bzw.
 * post-content bzw. die Testimonials nach dem Hero) startet dann direkt mit
 * dem normalen 1.25rem Flow-Abstand — keine Lücke. Das `:empty` greift für
 * alle Kontexte, weil der Binding-Paragraph ohne Wert als leeres Element
 * gerendert wird (kein Whitespace-Kind).
 *
 * Das Teilzwei-Spalten-Layout des Patterns "Beitrag: Teaser-Spalten" klebt am
 * Block-Style `is-style-teaser-spalten` (core/columns, registriert in
 * functions.php). Alle Regeln sind auf diesen Style gescoped, damit
 * columns-Blöcke ohne den Style unverändert bleiben: erste Spalte (der
 * descriptionTeaser mit .kv-post-teaser) etwas kleiner als der Fließtext und
 * gedämpft (75 %-ink, ≈ 5.8:1 auf paper, AA), zweite Spalte Standard;
 * großzügiger Abstand zur Kopfgruppe (H1/Untertitel). Unterhalb des
 * Core-Breakpoint (782px) stapeln die Spalten ohnehin — Teaser (Spalte 1)
 * vor Inhalt (Spalte 2) — Abstand und Schriftgrößen bleiben dabei
 * proportional, es kommen keine zusätzlichen Margins dazu.
 */

/* Untertitel: eng unter der H1, Heading-Familie, normale Stärke. */
p.kv-post-subtitle {
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-weight: 400;
	line-height: 1.3;
	margin-block-end: 0;
}

/* Enger Abstand statt der 1.25rem Flow-Gap: > * + *-Regel von Core schlagen. */
.wp-block-post-title + p.kv-post-subtitle {
	margin-block-start: clamp(0.25rem, 0.6vw, 0.5rem);
}

/* Wirkungsseite: Untertitel unter der huge-H1 im kv-wirkung-hero__copy-Stack.
 * Der Abstand ist bewusst größer als bei Artikeltiteln (die H1 ist deutlich
 * höher), aber immer noch deutlich unter der 20px-Flow-Gap – der Untertitel
 * sitzt optisch direkt an der H1 und folgt ihrer linken Kante (kein
 * eigenes Top-Level-Element mit eigenem Layout-Container). Die Schriftgröße
 * hebt der Wirkungs-Hero auf x-large an (clamp(1.875rem, 3.6vw, 3rem) =
 * 30–48px) – immer größer als die 24px von p.has-large-font-size: Die
 * Subline unter der huge-H1 wirkt eigenständig und darf größer sein als der
 * Fließtext. Nur dieser Kontext; die Artikel-/Seiten-Untertitel bleiben
 * unverändert bei 24px. */
.kv-wirkung-hero__copy .wp-block-heading + p.kv-post-subtitle {
	font-size: var(--wp--preset--font-size--x-large) !important;
	margin-block-start: clamp(0.75rem, 1.75vw, 1.5rem);
}

/* Leerer Untertitel (kein wps_subtitle-Meta) komplett ausblenden. */
p.kv-post-subtitle:empty {
	display: none;
}

/* Teaser-Spalten: großzügiger Abstand zur Kopfgruppe (H1 + Untertitel). */
.wp-block-columns.is-style-teaser-spalten {
	margin-block-start: clamp(2rem, 4vw, 3rem);
}

/* Erste Spalte (descriptionTeaser): kleiner als der Fließtext, gedämpft. */
.wp-block-columns.is-style-teaser-spalten > .wp-block-column:first-child {
	color: rgba(5, 43, 142, 0.75);
	font-size: 0.9em;
}

/*
 * ---------------------------------------------------------------------------
 * Post-Templates: Meta-Zeile, Schlagworte, Teilen-Leiste
 * ---------------------------------------------------------------------------
 * Ergänzung zu templates/single.html und single-fullwidth.html. Reihenfolge
 * im Template nach der Kopfgruppe (H1 + Untertitel):
 *
 *   1. Meta-Zeile (.kv-post-meta): die Hauptkategorie (core/post-terms,
 *      term=category, Link aufs Archiv) und das deutsche Datum
 *      (core/post-date, "j. F Y", ohne Link) fließen als ein Satz in einer
 *      Inline-Zeile: "Veröffentlicht in <Kategorie> am <Datum>." Die Gruppe
 *      nutzt das Default-Layout (kein flex), die Kinder werden per CSS auf
 *      display:inline gestellt. Die Wortabstände stecken als Leerzeichen in
 *      den `prefix`- und `suffix`-Attributen des Term-Blocks (get_the_term_list
 *      konkateniert prefix + Link + suffix ohne zusätzliche Textknoten, die
 *      Leerzeichen bleiben also an Ort und Stelle). Den Schlusspunkt ergänzt
 *      ein ::after-Pseudo-Element am Datum, damit er nicht im TextContent
 *      auftaucht. Vertikale Margins greifen auf inline-Elementen nicht,
 *      dadurch wird zugleich die Flow-Gap-Regel von Core (is-layout-flow > *)
 *      für die Meta-Zeile neutralisiert. Die Kategorie ist die
 *      "Hauptkategorie" (erste Kategorie): alle Beiträge des Projekts haben
 *      genau eine Kategorie; ein render_block-Filter in functions.php hält
 *      die Anzeige defensiv auf dem ersten Term, falls ein Beitrag je
 *      mehrere Kategorien bekommt. Die prefix/suffix-Texte übersetzt ein
 *      scoped render_block_data-Filter in inc/i18n.php (nur für
 *      className kv-post-category), niemals ein globaler String-Swap.
 *   2. Schlagwort-Zeile (.kv-post-tags): core/post-terms (term=post_tag)
 *      mit Prefix "Schlagworte: " hinter dem Beitragsinhalt. Bei leerer
 *      Tag-Liste rendert core/post-terms gar keinen Container (WP 7.0.3,
 *      verifiziert in wp-includes/blocks/post-terms.php liefert bei leerer
 *      Liste "" zurück), die Zeile verschwindet also komplett und der
 *      nächste Abstand darunter entfällt – die defensive `:empty`-Regel unten
 *      deckt ältere WP-Versionen oder andere Core-Container ab.
 *   3. Teilen-Leiste (.kv-share-title + .kv-share-list): Label-Paragraph
 *      (normale Fließtextgröße, bold) + 6 Kacheln als zusammenhängende
 *      Segmentleiste
 *      (Segmented-Control-Optik, 20px-SVGs, fill=currentColor; Optik wie das
 *      Button-System, details im Abschnittskommentar unten). Die hrefs setzt
 *      assets/js/share.js aus window.location.href, document.title und dem
 *      Textauszug der versteckten Quelle .kv-share-excerpt-source (ein
 *      core/post-excerpt-Block, display:none, nur auf Einzelbeiträgen
 *      eingebunden).
 *
 * Abstände laut Vorgabe „großzügige vertikale Abstände (2rem)" an allen
 * Übergängen: Untertitel → Meta 2rem, Meta → Feature-Image/Inhalt 2rem,
 * Inhalt → Schlagworte 2rem, Schlagworte → Teilen 2rem. Die Beträge sind
 * bewusst lokal auf die eigenen Klassen gesetzt (theme.json-Spacing bleibt
 * unberührt); die Flow-Gap-Regel von Core (is-layout-flow > *, 1.25rem)
 * wird über Geschwister-Selektoren mit höherer Spezifität unterschritten.
 * Margins kollabieren zwischen den Geschwister-Selektoren, es entsteht
 * also keine Doppelung der 2rem.
 */

/* Meta-Zeile: Kategorie-Link + Datum, unter dem Untertitel. Default-Layout
 * in den Templates (kein is-layout-flex), die Kinder werden inline gestellt,
 * damit der gesamte Satz in einer Inline-Formatierungsebene fließt. Die
 * Wortabstände kommen aus den Leerzeichen der prefix/suffix-Attribute des
 * Term-Blocks. Block-Margins der Kinder (Flow-Gap von Core, is-layout-flow)
 * greifen auf inline-Elementen nicht, ein flex-gap gibt es nicht mehr. */
.wp-block-group.kv-post-meta {
	margin-block-start: 2rem;
}

/* Term-Wrapper (core/post-terms rendert ein <div>) und Datum als inline
 * Geschwister: ein zusammenhängender Satz, der am Wortende umbricht. */
.wp-block-group.kv-post-meta > :where(.wp-block-post-terms, .wp-block-post-date) {
	display: inline;
}

/* Schlusspunkt des Satzes nur visuell (nicht im TextContent). */
.wp-block-group.kv-post-meta > .wp-block-post-date::after {
	content: ".";
}

.kv-post-meta a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

.kv-post-meta a:hover,
.kv-post-meta a:focus-visible {
	text-decoration-thickness: 3px;
}

/* Meta → Feature-Image (single.html) bzw. Meta → Inhalt
 * (single-fullwidth.html, kein Feature-Image). */
.kv-post-meta + .wp-block-post-featured-image,
.kv-post-meta + .wp-block-post-content {
	margin-block-start: 2rem;
}

/* Schlagwort-Zeile; ohne Tags wird kein Container gerendert, siehe
 * Abschnitts-Kommentar oben. Der core/post-terms-Wrapper ist ein Inline-
 * <span> – verticale Margins würden sonst nicht greifen, daher block.
 * Der Prefix "Schlagworte: " wird von core/post-terms als reiner Textknoten
 * vor den Tag-Links gerendert (kein eigenes Element, per CSS nicht einzeln
 * selektierbar) – daher bekommt der Wrapper font-weight: 700 und die
 * Tag-Links werden über die a-Regel darunter auf normale Schriftstärke
 * (400) zurückgenommen. */
.wp-block-post-terms.kv-post-tags {
	display: block;
	font-weight: 700;
	margin-block-start: 2rem;
	text-align: center;
}

.kv-post-tags a {
	color: var(--wp--preset--color--ink);
	font-weight: 400;
	text-underline-offset: 0.1em;
}

.kv-post-tags a:hover,
.kv-post-tags a:focus-visible {
	text-decoration-thickness: 3px;
}

/* Defensive Leer-Container-Regel für core/post-terms (ältere WP-Versionen
 * rendern einen leeren <span>); aktuell liefert WP 7.0.3 "" (kein Markup). */
.wp-block-post-terms:empty {
	display: none;
}

/* Teilen-Leiste: Label + zusammenhängende Segmentleiste (Segmented-Control-
 * Optik) mit 6 Kacheln auf voller Content-Breite. Ein gemeinsamer Außen-
 * rahmen (Border auf der Leiste selbst), innen feine Trennlinien zwischen
 * den Kacheln (`li + li` → border-left ab der 2. Kachel), Border-Radius nur
 * an den äußeren Ecken der Leiste: Der Radius steht auf dem Container,
 * `overflow: hidden` klipst Kachelhintergründe und Hover-Fills an die
 * gerundeten Ecken; Innenkanten am mobilen Umbruch bleiben dadurch sauber
 * rechtwinklig. Keine Gaps zwischen den Kacheln, eine durchgehende 1px-
 * Linie an jeder Berührungsstelle (Außenrahmen und Teilersegmente liegen
 * auf verschiedenen Ebenen, kein Doppelstrich). Kacheln sind reine Tipp-
 * flächen (min-height 64px, Icon 20px zentriert). Farb- und Hover-Logik wie
 * das Secondary-Button-System (ink-Variante, vgl. Abschnitt "Button-System"
 * oben): transparent, ink-Text; Hover/Fokus invertieren auf den Primary-
 * Auftritt (ink-Fill, paper-25-Text) analog is-style-secondary-ink. */
.kv-share-title {
	font-weight: 700;
	margin-block-end: 0.75rem;
	margin-block-start: 2rem;
}

.kv-share-list {
	border: 1px solid var(--wp--preset--color--ink);
	border-radius: 8px;
	display: grid;
	grid-template-columns: repeat(6, 1fr);
	list-style: none;
	margin: 0;
	overflow: hidden;
	padding: 0;
}

.kv-share-list li {
	display: flex;
	margin: 0;
	padding: 0;
}

/* Geteilte Trennlinie zwischen benachbarten Kacheln (kein Doppelstrich). */
.kv-share-list li + li {
	border-left: 1px solid var(--wp--preset--color--ink);
	transition: border-color 160ms ease;
}

/* Beim Hover/Fokus einer Kachel verschmilzt die Trennlinie rechts davon mit
 * dem ink-Fill (die aktive Kachel wirkt exakt eine Kachel breit, kein 1px-
 * Überstand am Zellenende; die Linie links bleibt Teil des Fills). */
.kv-share-list li:hover + li,
.kv-share-list li:focus-within + li {
	border-left-color: transparent;
}

.kv-share-link {
	align-items: center;
	background: transparent;
	border: 0;
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	display: inline-flex;
	font-weight: 600;
	justify-content: center;
	line-height: 0;
	min-height: 64px;
	padding: 0.75rem 0.5rem;
	text-decoration: none;
	transition: background-color 160ms ease, color 160ms ease;
	width: 100%;
}

.kv-share-link:hover,
.kv-share-link:focus-visible {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

.kv-share-link svg {
	display: block;
}

/* Versteckte Textauszug-Quelle für die Teilen-Leiste (core/post-excerpt mit
 * Klasse kv-share-excerpt-source, in beiden Single-Templates). display:none
 * statt screen-reader-text: Der Auszug ist nur Datenquelle für share.js
 * (textContent bleibt lesbar) und soll nicht in den Accessibility-Tree. */
.kv-share-excerpt-source {
	display: none;
}

/* Visuell verstecke Link-Texte pro Teilen-Link (WCAG 1.3.1 / 4.1.2),
 * Muster wie in der Footer-Sektion. */
.kv-share-list .screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* Responsiv: Unter 782px (Core-Tablet-Breakpoint) bricht die 6er-Zeile in
 * eine zusammenhängende 2×3-Leiste um (3 Spalten × 2 Zeilen): Der Außen-
 * rahmen und die vertikalen Trennlinien bleiben erhalten, die Zeilenanfänger
 * (nth-child(3n+1)) verlieren ihre linke Trennlinie (der Containerrahmen
 * übernimmt die Außenkante) und alle Kacheln der zweiten Zeile (nth-child(
 * n+4)) bekommen eine obere Trennlinie als horizontalen Teiler. Die Innen-
 * kante am Umbruch ist bewusst rechtwinklig (der Radius gehört nur dem Außen-
 * rahmen) – das entspricht der Optik eines umgebrochenen Segmented Controls
 * ohne Doppelstriche. Drei Spalten bleiben bis einschließlich 320px trag-
 * fähig (Content-Spalte ≥ ~288px → ≥ ~94px pro Kachel, Icon 20px zentriert,
 * min-height 64px): kein weiterer Umbruch nötig, kein horizontaler Overflow.
 * 1fr-Spalten teilen die Content-Breite. */
@media (max-width: 781px) {
	.kv-share-list {
		grid-template-columns: repeat(3, 1fr);
	}

	/* Zeilenanfänger (1. und 4. Kachel): linke Trennlinie entfällt, die
	 * Außenkante übernimmt der Containerrahmen. */
	.kv-share-list li:nth-child(3n + 1) {
		border-left: 0;
	}

	/* Zweite Zeile: obere Trennlinie als horizontaler Teiler zwischen den
	 * beiden Kachelzeilen. */
	.kv-share-list li:nth-child(n + 4) {
		border-top: 1px solid var(--wp--preset--color--ink);
	}
}

/*
 * ---------------------------------------------------------------------------
 * Tag-Archiv — templates/tag.html
 * ---------------------------------------------------------------------------
 * Die Karten im Query-Loop des Tag-Archivs folgen dem Design des Patterns
 * patterns/article-card.php (weise Fläche, Bild 352:198, Kategorie-Pill auf
 * dem Bild, Titel, Teaser), werden aber mit Loop-fähigen Core-Blöcken gebaut
 * (post-featured-image, post-title, post-excerpt), damit sie pro Beitrag
 * dupliziert werden. Diese Regeln ergänzen das Pattern-CSS nur dort, wo die
 * dynamischen Block-Wrapper vom statischen Pattern-Markup abweichen.
 *
 * 1. featured-image-figure: die UA-Margin des <figure> (oben/unten 1em) im
 *    Karten-Medienbereich entfernen; die Pattern-CSS `.kv-article-card__media`
 *    setzt nur margin:0 auf dem Wrapper.
 * 2. Gleiche Kartenhöhe pro Raster-Zeile (li = Grid-Item streckt).
 * 3. Verlinkter Kartentitel in Tintenfarbe, Hover/Fokus Blau + Unterstreichung
 *    (die globale :focus-visible-Outline des Themes bleibt aktiv).
 * 4. Kategorie-Pill: core/post-terms rendert Terme immer als Links; im
 *    Pill-Design die Erbfarbe übernehmen.
 * 5. Teaser-Paragraf: Default-<p>-Margin im Excerpt-Wrapper neutralisieren.
 * 6. Raster auf Mobile stapeln — Core kollabiert Post-Template-Grids erst bei
 *    600 px, die Theme-Patterns stapeln bei 782 px; gleiches Verhalten hier.
 */
.kv-article-card__media .wp-block-post-featured-image {
	margin: 0;
}

.wp-block-post-template > li > .kv-article-card {
	height: 100%;
}

.kv-article-card .wp-block-post-title a {
	color: inherit;
	text-decoration: none;
}

.kv-article-card .wp-block-post-title a:hover,
.kv-article-card .wp-block-post-title a:focus-visible {
	color: var(--wp--preset--color--blue);
	text-decoration: underline;
}

/* Der Kategorie-Link füllt das Badge komplett aus: negatives Margin in
 * Höhe des Badge-Paddings (0.45rem/0.6rem, s. Zeile ~1541) + gleiches
 * Padding lässt das Block-Level-Link genau den Badge-Bereich abdecken,
 * damit die Hover-Fläche den ganzen Badge-Fill ersetzt. */
.kv-article-card__tag a {
	border-radius: 8px; /* dieselbe Rundung wie der Badge-Wrapper: Ohne
	 * sie lief der #FFD183-Hover-Fill eckig über die abgerundeten
	 * Ecken des Badges (Bug-Report 12.09.). */
	color: inherit;
	display: block;
	margin: -0.45rem -0.6rem;
	padding: 0.45rem 0.6rem;
	text-decoration: none;
}

/* Button-Hover wie primary-signal: Fill wechselt auf das User-Design-Token
 * "gelborange 75" #FFD183 (keine CSS-Variable, im Theme hardcodiert wie im
 * Button-System). Text bleibt ink über color: inherit — ink auf #FFD183
 * misst 8.44:1 (WCAG AAA), der Hover ist also klar lesbar. Auftrag
 * 12.09.: Beim Hover/Fokus zusätzlich die dicke Unterstreichung (2px,
 * wie beim Blog-Posts-Badge). Die theme-globale signal-Fokus-Outline
 * (3px, 4px Offset) bleibt aktiv. */
.kv-article-card__tag a:hover,
.kv-article-card__tag a:focus-visible {
	background: #FFD183;
	text-decoration: underline;
	text-decoration-thickness: 2px;
}

.kv-article-card .wp-block-post-excerpt__excerpt {
	margin: 0;
}

@media (max-width: 781px) {
	.wp-block-post-template.is-layout-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/*
 * ---------------------------------------------------------------------------
 * Archiv & Kategorie-Auswahl — category.html, tag.html, home.html
 * ---------------------------------------------------------------------------
 * Kategorie-Seite, Tag-Seite und die Blog-Übersicht /aktuelles/ teilen
 * sich die Sektion .kv-archive: dunkle ink-Fläche mit paper-25-Text.
 * Fläche und Textfarbe liefern die Utility-Klassen der Sektion
 * (has-ink-background-color / has-paper-25-color aus theme.json); die
 * Regeln hier ergänzen gezielt die dynamischen Blöcke:
 *
 * 1. Textfarben: query-title trägt has-paper-25-color und kv-display
 *    bereits in der Vorlage; No-Results-Text und alle Pagination-Links
 *    setzt dieser Abschnitt explizit auf paper-25 (11.85:1 AAA), damit
 *    keine UA- oder Core-Farbe dazwischenfunkt. Der Archiv-Eyebrow
 *    ("Archiv", leaf auf ink) misst 6.91:1: WCAG-AA-Normaltext ist ab
 *    4.5:1 erfüllt, eine Korrektur auf paper-25 ist nicht nötig, leaf
 *    bleibt.
 * 2. Kategorie-Menü (Block klima-vor-acht/kategorie-auswahl, rendert auf
 *    den Kategorie-Seiten und der Blog-Übersicht /aktuelles/): Kompakte
 *    Secondary-Buttons analog zum Button-System secondary-paper
 *    (transparent, 1.5px paper-Border, paper-Text, Radius 6px, Padding
 *    0.1875rem/0.75rem). Hover und Fokus folgen dem System-Hover
 *    (paper-25-Fill, ink-Text, 11.85:1 AAA). Einen aktiven Eintrag gibt
 *    es nicht mehr: Die aktuell angezeigte Kategorie steht als Titel
 *    über dem Menü und wird im Render-Callback komplett aus der Liste
 *    entfernt, auf /aktuelles/ entfällt der sonst führende "Alle"-
 *    Eintrag. Alle Einträge sind reine Links. Label und Buttons liegen
 *    inline nebeneinander (flex row mit wrap, siehe Menü-Regeln unten).
 * 3. Pagination: Links und Seitenzahlen in paper-25 (11.85:1 AAA). Die
 *    Zahlen sind 40x40-Pill-Ziele (Zielgröße ~40px, Radius 999px); die
 *    aktive Seite setzt sich mit signal-Fill und
 *    ink-Text ab (7.40:1 AAA). Hover/Fokus folgen dem Theme-Standard:
 *    Vor/Zurück-Textlinks bekommen eine Unterstreichung, Zahlen-Pills
 *    den paper-25-Fill mit ink-Text; die globale signal-Outline (3px,
 *    Offset 4px, :focus-visible) bleibt aktiv und ist auf der ink-Fläche
 *    klar sichtbar (7.40:1) — eine zweite Outline wird nicht eingeführt.
 * 4. Raster: Das Post-Template-Grid der Archive rendert Core-Block-seitig
 *    (3 Spalten, 2.5rem-Gap über blockGap — identisch zum
 *    kv-aktuelles__grid der Startseite mit 40px-Gap). Für das
 *    Einspaltig-Stapeln bei ≤781px greift die bestehende Regel aus dem
 *    Tag-Archiv-Abschnitt (.wp-block-post-template.is-layout-grid), sie
 *    wird hier nicht dupliziert. Keine neue Bildgröße, kein Crop-Override
 *    (Entscheidung 13).
 * 5. Mobile: Das Menü liegt inline und bricht über flex-wrap um. Bei
 *    ≤375px beansprucht das Label bewusst die volle erste Zeile
 *    (flex-basis: 100%, Media-Query unten), die Buttons fließen sauber
 *    darunter statt sich mit dem Label in eine gequetschte Zeile zu
 *    teilen (Entscheidung, dokumentiert an der Media-Query). Die
 *    Pagination bricht unter 600px ebenfalls um und zentriert ihre
 *    umgebrochenen Zeilen (das inline justify-content:space-between des
 *    Core-Blocks weicht per !important, gleiches Muster wie im übrigen
 *    Theme gegen Core-Inline-Werte). Kein horizontaler Overflow, das
 *    Raster bleibt einspaltig.
 * 6. Flächenbreite: volle Viewportbreite (Vollbreite/Full-Bleed). Die Sektion
 *    trägt alignfull; die Shell-Kappe
 *    `.wp-site-blocks .alignfull { max-width: 100% }` würde sie nur auf die
 *    1440px-Shell zurückschneiden und in der Puffer-Paper-Fläche belassen.
 *    Diese spezifischere Regel nutzt denselben Vollbreite-Breakout wie
 *    .kv-site-header und .kv-site-footer:
 *    `width: 100vw` spannt die ink-Fläche bis exakt an die Fensterkanten,
 *    `margin-inline: calc(50% - 50vw)` zentriert sie im (zentrierten)
 *    umgebenden Container; die Rechnung kürzt sich damit bei jeder Breite
 *    randlos weg, die Fläche reicht bis an den Viewportrand (kein seitlicher
 *    Papierrest, kein Overflow: html/body sind overflow-x: clip). Die 50vw
 *    in der Formel löst gegen den `main`-Container auf, der die zentrierte
 *    Shell 1:1 ausfüllt, die Rechnung ist damit dieselbe wie bei den
 *    Shell-Kindern. Die Inhaltsbreite übernimmt
 *    weiterhin allein die innere Group (align wide, layout constrained mit
 *    contentSize/wideSize 1136px, Task 10d): max. 1136px Inhalt, zentriert,
 *    mit 16px Abstand zu den Sektionsrändern. Der 16px-Abstand steht inline
 *    an der inneren Group in home.html und tag.html: im Style-Attribut des
 *    Gruppen-Placeholders (`padding-left/right:16px`, gespiegelt in
 *    style.spacing.padding der Block-Kommentarzeile für den Editor).
 *    Ausnahme templates/presse.html: Dort nutzt die innere Group paddings
 *    var(--kv-root-gutter) (clamp(1rem, 3vw, 3rem)) statt fixem 16px, damit
 *    die Innenkante der Pressemitteilungen-Sektion bei allen Breiten exakt
 *    der Intro- und Pressespiegel-Sektion folgt (deren alignwide-Kanten dem
 *    Body-Gutter folgen); ab der 1136px-Deckelung zentriert das
 *    constrained-Layout die Kinder gruppenintern neu und das Gutter-Padding
 *    hebt sich rechnerisch auf (152px-Kante bleibt, Fix 11.08.). Das
 *    Frontend übernimmt die Platzhalter-Styles 1:1; horizontales Padding
 *    allein aus dem Block-Kommentar würde WP 7.0.3 beim Template-Rendering
 *    verwerfen (nur Top/Bottom aus Kommentar-Styles überleben), daher liegt
 *    es im gerenderten Placeholder wie bei der Section. Die 1136px-Deckel
 *    liefert das Block-Layout (contentSize/wideSize 1136px, der page-wide
 *    Wide-Size aus theme.json).
 *    Eine eigene CSS-Regel, die die Group selbst auf 1136px deckelt, ist
 *    bewusst nicht nötig: Sie würde die Kinder auf 1104px (1136 minus 2×16px
 *    Padding) einziehen statt auf die gewünschten 1136px. Diese Regel hier
 *    ändert nur die Fläche, nie die Inhaltsbreite.
 */

/* Section-Fläche: volle Viewportbreite (Inhalt innen begrenzt die
 * 1136px-Group mit 16px-Padding, siehe Kommentar oben). */
.wp-site-blocks .alignfull.kv-archive {
	box-sizing: border-box;
	margin-inline: calc(50% - 50vw);
	max-width: none;
	width: 100vw;
}

/* Der No-Results-Hinweis erbt paper-25 von der Sektion, wird aber zur
 * Sicherheit explizit gesetzt (Core kann den Absatz färben). */
.kv-archive .wp-block-query-no-results {
	color: var(--wp--preset--color--paper-25);
}

/* Suffix „(alle Beiträge)" im H1 der Blog-Übersicht /aktuelles/
 * (home.html): kleiner und heller als der Headline-Text, gleiche
 * Schriftfamilie (erbt IBM Plex Sans und letter-spacing aus dem
 * .kv-display-h1). 0.65em relativ zur h1-Größe (x-large:
 * clamp(1.875rem, 3.6vw, 3rem) → 31.2px bei 48px max., 19.5px mobil);
 * bewusst innerhalb der 0.6–0.75em-Spanne, klein genug für den
 * Subtext-Charakter, groß genug, um lesbar zu bleiben. Farbe paper-25
 * bei 75% Deckkraft: gemischter Wert auf dem ink-Grund ergibt ≈ #C0C8DF
 * auf #052B8E = 7.21:1 (WCAG-AA für Normaltext, AA/AAA für Large Text
 * erfüllt — die Theme-Doku weist für die volle paper-25-Deckkraft
 * 11.85:1 aus, die Reduktion auf 75% ist die hier gewollte visuelle
 * Abhebung). white-space: nowrap hält die Klammerphrase bei schmalen
 * Viewports zusammen: Ein Umbruch darf höchstens als Ganzes zwischen
 * „Aktuelles" und dem Suffix passieren, nie innerhalb der Phrase
 * (kein Overflow, geprüft bei 375px). */
.kv-aktuelles-suffix {
	color: var(--wp--preset--color--paper-25);
	font-size: 0.65em;
	font-weight: 400;
	opacity: 0.75;
	white-space: nowrap;
}

/* Kategorie-Menü: Label und Buttons liegen inline nebeneinander (flex
 * row), bei Platzmangel bricht die Reihe über flex-wrap um. Der Gap
 * (0.75rem) trennt Label und Liste horizontal, beim Umbruch auch die
 * Zeilen untereinander. align-items: center richtet das Eyebrow-Label
 * an der mittleren Höhe der Button-Reihe aus (eine Zeile bei
 * Normalbreite, die Playwright-Prüfung nutzt genau diese Ausrichtung). */
.kv-category-menu {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
}

/* Label im Eyebrow-Look des Archiv-Eyebrows ("Archiv"): klein, fett,
 * gesperrt, uppercase; Farbe erbt paper-25 von der Sektion. Als
 * Flex-Item steht es direkt links neben der Liste, ein eigener
 * Block-Umbruch existiert nicht (kein display-Wechsel nötig). Bei
 * ≤375px erzwingt die Media-Query unten die volle erste Zeile. */
.kv-category-menu__label {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.12em;
	margin: 0;
	/* 4px Top-Aufschlag: optisch bündig zur Button-Zeile (Buttons: 3px
	 * vertikales Padding + 1.5px Border). */
	padding-top: 4px;
	text-transform: uppercase;
}

/* Liste als umbrechende Zeile (Wrap bei schmalen Viewports), die
 * UA-Abstände des ul werden neutralisiert. */
.kv-category-menu__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 0.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Kompakte Secondary-Buttons analog secondary-paper: transparent, 1.5px
 * paper-Border, paper-Text, Radius 6px, Padding 0.1875rem/0.75rem
 * (3/12px). Das vertikale 3px-Padding ist der Wunsch des Auftraggebers
 * (kompakte Button-Optik statt Ghost-Pill); die alte 40px-Mindesthöhe
 * der Pille entfällt damit, die Zielfläche bleibt mit knapp 26px über
 * dem WCAG-2.2-Mindestmaß von 24px. Der frühere `gap` für das
 * Häkchen-SVG ist obsolet. */
.kv-category-menu__link {
	align-items: center;
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--paper);
	border-radius: 6px;
	box-sizing: border-box;
	color: var(--wp--preset--color--paper);
	display: inline-flex;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	line-height: 1.2;
	padding: 0.1875rem 0.75rem;
	text-decoration: none;
}

/* Hover/Fokus wie der System-Hover der Ghost-Buttons: paper-25-Fill mit
 * ink-Text (11.85:1 AAA); die globale signal-Outline (3px, Offset 4px)
 * bleibt für den Fokus aktiv und ist auf ink klar sichtbar (7.40:1).
 * Einen eigenen aktiven Zustand gibt es nicht mehr: Die aktuelle
 * Kategorie fehlt im Menü komplett (der Seiten-Titel übernimmt ihre
 * Kennzeichnung), jeder Eintrag ist ein Link. */
.kv-category-menu__link:hover,
.kv-category-menu__link:focus-visible {
	background: var(--wp--preset--color--paper-25);
	border-color: var(--wp--preset--color--paper-25);
	color: var(--wp--preset--color--ink);
}

/* ≤375px: Das Label bekommt die volle Breite (flex-basis: 100%) und
 * steht damit allein in der ersten Zeile, die Buttons fließen als
 * umbrechende Reihe darunter. Entscheidung: Bei dieser Breite ist das
 * Label (uppercase, gesperrt) teils so breit, dass neben ihm nur ein
 * Button Platz fände; die saubere Trennung in Label-Zeile und
 * Button-Zeile ist lesbarer als eine gequetschte gemeinsame Zeile.
 * Kein Overflow: Beide Ebenen wrappen (nav und ul), die Einträge
 * behalten dank min-width:auto ihre min-content-Breite. */
@media (max-width: 375px) {
	.kv-category-menu__label {
		flex-basis: 100%;
	}
}

/* Pagination: alle Elemente (Zahlen, Vor/Zurück) als einheitliche
 * 40px-Pills in paper-25, die komplette Zeile mittig (auch wenn nur
 * Zahlen oder nur ein Vor/Zurück-Pfeil steht, bleibt die Gruppe
 * zentriert); flex-wrap für den Umbruch bei schmalen Viewports. */
.kv-archive .wp-block-query-pagination {
	flex-wrap: wrap;
	gap: 0.25rem;
	justify-content: center;
}

.kv-archive .wp-block-query-pagination a,
.kv-archive .wp-block-query-pagination .page-numbers {
	align-items: center;
	box-sizing: border-box;
	border-radius: 999px;
	color: var(--wp--preset--color--paper-25);
	display: inline-flex;
	justify-content: center;
	min-height: 40px;
	min-width: 40px;
	padding: 0;
	text-decoration: none;
}

/* Hover aller Pills außer der aktiven Seite: paper-25-Fill mit ink-Text
 * (11.85:1 AAA); die aktive Seite behält ihren signal-Fill. */
.kv-archive .wp-block-query-pagination a:not(.page-numbers.current):hover {
	background: var(--wp--preset--color--paper-25);
	color: var(--wp--preset--color--ink);
}

/* Zahlenblock: eigene umbrechende Reihe, 4px-Lücke zwischen den Pills
 * (gleicher Abstand wie auf Nav-Ebene), damit benachbarte Pills beim
 * Hover nicht aneinanderkleben. */
.kv-archive .wp-block-query-pagination-numbers {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem;
	justify-content: center;
}

/* Aktive Seite deutlich abgesetzt: signal-Fill, ink-Text (7.40:1 AAA),
 * Gewicht 700; ändert sich beim Hover nicht. */
.kv-archive .wp-block-query-pagination .page-numbers.current {
	background: var(--wp--preset--color--signal);
	color: var(--wp--preset--color--ink);
	font-weight: 700;
}

/*
 * ---------------------------------------------------------------------------
 * Presse – kv-presse-layout (Seitenvorlage "Presse")
 * ---------------------------------------------------------------------------
 * Zweispaltiges Layout: links die schmale Kontaktspalte (~1/3.6, sticky),
 * rechts der Inhalt mit den Eintragslisten. Unter ≤781px stapeln sich die
 * Bereiche einspaltig; die Kontaktspalte steht dann oben, ohne Stickiness,
 * und ihre zwei Sektionen liegen zweispaltig nebeneinander.
 *
 * Kontaktspalte: Das Pattern presse-kontakt.php rendert zwei Sektionen mit
 * der Klasse kv-section (Pressekontakt und Social Media), deren
 * Breakout-Geometrie (width: 100vw) in der schmalen Spalte bis an den
 * Viewportrand ausbrechen würde; die Asides-Regeln (kv-presse-kontakt,
 * kv-presse-social) stellen die Spaltengeometrie wieder her. Die Spalte
 * klebt beim Scrollen am Viewport-Oberrand, unterhalb des sticky
 * Site-Headers (152px). Den Abstand steuert zentral die Variable
 * --kv-presse-sticky-offset; bei einer anderen Header-Höhe muss sie
 * angepasst werden (visuell ab ≥1024px prüfen).
 *
 * Eintragslisten: kv-presse-list ist einspaltig mit Hairline-Trennern je
 * Eintrag (--kv-border, ink bei 16 %). Jeder Eintrag zeigt Datum (17/24,
 * muted), Titel (24px/700 über die Heading-Schrift) und eine Aktionszeile
 * mit dem sekundären Button. Der Toggle ist ein normal großer
 * secondary-ink-Ghost auf der weißen Karte; [hidden] schlägt display, damit der
 * No-JS-Fall und die JS-Klapplogik funktionieren. Die Animation
 * kv-presse-reveal (opacity, translateY(4px), 200ms) existiert nur unter
 * prefers-reduced-motion: no-preference; unter reduce greift keine
 * Animation.
 */

/* Zweispaltiges Raster: Kontaktspalte schmaler als ein Viertel
 * (minmax(0, 1fr) | minmax(0, 2.6fr); 04.09. Korrektur: die
 * Social-Buttons laufen einspaltig, die Spalte braucht die Breite nicht
 * mehr — bei 1136px Rasterbreite ≈ 304/792px statt 365/730px), Lücke fest
 * 40px (Objektabstand laut Figma-Vorgabe). align-items: start hält die
 * Zellen oben ausgerichtet, damit die sticky-Spalte in ihrer Zelle
 * arbeiten kann.
 * --kv-presse-sticky-offset ist hier einmal definiert und gilt für
 * die calc() der Aside-Regel. padding-block-end gibt Luft zum Footer; oben
 * übernimmt die Intro-Group den Rhythmus. */
.kv-presse-layout {
	--kv-presse-sticky-offset: 176px;
	align-items: start;
	display: grid;
	gap: 40px;
	grid-template-areas: "aside content";
	grid-template-columns: minmax(0, 1fr) minmax(0, 2.6fr);
	padding-block-end: clamp(2.5rem, 5vw, 4rem);
}

/* Core setzt auf die Layout-Group is-layout-flow; deren `> * + *`-Regel
 * würde dem zweiten Grid-Kind (Content) zusätzlich margin-block-start in
 * Höhe von block-gap geben. Die Zellen liegen aber bereits über das eigene
 * grid gap (40px) auseinander, der Flow-Abstand muss hier null sein. */
.kv-presse-layout > * + * {
	margin-block-start: 0;
}

.kv-presse-layout__aside {
	grid-area: aside;
}

.kv-presse-layout__content {
	grid-area: content;
}

/* Alle drei Content-Container ("Downloads für die Presse",
 * "Pressemitteilungen", "KLIMA° vor acht in den Medien") sind weiße Karten
 * (Figma-Vorgabe: weißer Grund, Radius 16px, Innenabstand 20px); der
 * Objektabstand zwischen den Karten beträgt 40px. Das padding-block-end
 * des Layouts (clamp(2.5rem, 5vw, 4rem)) addiert sich beim letzten
 * Container zum Abstand vor dem Footer. Der margin der Gruppe ist additiv
 * zum margin-block-end der Überschrift darin. */
.kv-presse-layout__content > .wp-block-group {
	background: var(--wp--preset--color--white);
	border-radius: 16px;
	margin-block-end: 40px;
	padding: 20px;
}

/* Abschnittsüberschriften im Content: wp-block-heading erhält von Core
 * margin: 0, dadurch säßen die Listen direkt unter dem h2. Ein gemeinsames
 * margin-block-end hält die drei Überschriften von der jeweiligen Liste
 * beziehungsweise vom Download-Button der Presse-Info-Gruppe ab. */
.kv-presse-layout__content .wp-block-heading {
	margin-block-end: 1.5rem;
}

/* Sticky-Kontaktspalte: bleibt beim Scrollen stehen, top liegt unter dem
 * sticky Site-Header (152px) plus Sicherheitsabstand. Der Default 176px
 * deckt den ausgeklappten Desktop-Header ab; --kv-presse-sticky-offset ist
 * oben einmal definiert und zentral nachjustierbar. Zwei Zustände: Ist der
 * Header sichtbar, klebt die Spalte 176px unter der Viewport-Oberkante;
 * blendet die JS-Klasse kv-site-header--hidden ihn aus, greift die :has()-
 * Regel darunter und die Spalte klebt nur noch unter der Admin-Bar. Ein
 * Übergang (transition: top 0.3s ease) gleicht das Umschalten weich aus;
 * unter prefers-reduced-motion wird er global auf 0.01ms reduziert. */
.kv-presse-layout__aside {
	align-self: start;
	position: sticky;
	top: calc(var(--wp-admin--admin-bar--height, 0px) + var(--kv-presse-sticky-offset, 176px));
	transition: top 0.3s ease;
}

body:has(.kv-site-header.kv-site-header--hidden) .kv-presse-layout__aside {
	top: var(--wp-admin--admin-bar--height, 0px);
}

/* Kleben + interne Scroll-Flaeche (04.09., einspaltige Social-Buttons):
 * Die Aside ist jetzt hoeher als der sichtbare Rest unter dem sticky
 * Header. Ein reiner top:-Kleber wuerde den Kartenboden (Mastodon,
 * YouTube, Facebook) im geklebten Zustand unerreichbar machen. Die
 * max-height deckelt die Aside auf die sichtbare Flaeche (Viewport minus
 * Sticky-Offset minus 24px Luft), overflow-y: auto bringt bei Bedarf
 * eine duenne interne Scrollleiste — der obere Kartenbereich bleibt
 * stehen, der untere ist durchscrollbar. OHNE overscroll-behavior:
 * contain: am inneren Scroll-Ende soll das Mausrad auf die Seite
 * durchgreifen (kein Scroll-Trap ueber der Spalte). Das 4px-End-Padding
 * haelt die Kartenkante frei von der Leiste, scrollbar-width: thin
 * haelt die Leiste dezent. Die :has()-Regel spiegelt den Zustand
 * "Header ausgeblendet" (top: 0 => volle Viewport-Hoehe minus
 * Admin-Bar). */
@media (min-width: 782px) {
	.kv-presse-layout__aside {
		max-height: calc(100vh - var(--kv-presse-sticky-offset, 176px) - 24px);
		overflow-y: auto;
		padding-inline-end: 4px;
		scrollbar-width: thin;
	}

	body:has(.kv-site-header.kv-site-header--hidden) .kv-presse-layout__aside {
		max-height: calc(100vh - var(--wp-admin--admin-bar--height, 0px) - 24px);
	}
}


/* Neutralisierung des kv-section-Breakouts im Aside: Die beiden Sektionen
 * des presse-kontakt-Patterns (Pressekontakt und kv-presse-social) tragen
 * kv-section (width: 100vw, margin-inline: calc(50% - 50vw)); in der
 * 1/3-Spalte würde das die Zelle sprengen. Die drei Werte fallen auf die
 * Spaltengeometrie zurück, box-sizing: border-box aus kv-section bleibt
 * unverändert. Zusätzlich Karten-Auftritt: Der Paper-Hintergrund des
 * Patterns (has-paper-background-color) weicht weißen Karten mit Radius
 * 16px und Innenabstand 20px (Figma-Vorgabe). Das !important ist nötig,
 * weil der Core-Utility has-paper-background-color aus dem Global-Styles-
 * Inline-CSS selbst !important trägt und so trotz niedrigerer Spezifität
 * einen normalen background-Shorthand der Kartenregel schlagen würde
 * (Muster wie .kv-header-inverted .kv-site-header.has-ink-background-color
 * oben). */
.kv-presse-layout__aside .kv-presse-kontakt,
.kv-presse-layout__aside .kv-presse-social {
	background-color: var(--wp--preset--color--white) !important;
	border-radius: 16px;
	margin-inline: 0;
	max-width: none;
	padding: 20px;
	width: auto;
}

/* Karten-Abstand der beiden Aside-Sektionen auf dem Desktop: Die Aside ist
 * ein Core-Flow-Layout (blockGap 1.25rem = 20px), der Objektabstand von
 * 40px zwischen den Karten kommt aus dieser Regel. Unter ≤781px legt die
 * Mobile-Regel margin-block-start: 0 auf die Grid-Kinder (zweispaltige
 * Anordnung), dort übernimmt das Grid-Gap den Abstand. */
.kv-presse-layout__aside > * + * {
	margin-block-start: 40px;
}

/* Nackte URLs in der Kontaktspalte (E-Mail und Telefonnummern in den
 * Absätzen der ersten Sektion): overflow-wrap: anywhere erlaubt den Bruch
 * an beliebiger Stelle, kein horizontaler Overflow bis 375px, auch in der
 * zweispaltigen Mobile-Anordnung der Sektionen. (Seit dem 04.09.
 * Button-Umbau der Social-Sektion enthält das Aside keine naked-URL-Liste
 * mehr; die Regel bleibt für die Kontaktlinks erhalten.) */
.kv-presse-layout__aside .kv-presse-kontakt a,
.kv-presse-layout__aside .kv-presse-social a {
	overflow-wrap: anywhere;
}

/* Textlinks in der Pressekontakt-Spalte (tel:, mailto:, Social-Links der
 * Sektionen Pressekontakt und Social Media) in dunkelblau (ink #052B8E,
 * User-Vorgabe "Links: Use dunkelblau as color", 18.08.2026): Die Links
 * sind normale Textlinks nach der KERN-UX-Konvention des Themes (permanente
 * Unterstreichung, Dicke 0.0625rem, Offset 0.1em; Hover/Fokus verdicken die
 * Linie auf 3px, die Textfarbe bleibt ink wie bei .kv-post-meta/
 * .kv-post-tags). Unterstreichung und Dicke liefert die globale a-Regel;
 * hier wird nur die Farbe gesetzt (kein text-decoration-Shorthand, das die
 * Dicke auf auto zurücksetzen würde). Die globale :focus-visible-Outline
 * (signal, 3px, Offset 4px) bleibt aktiv. */
.kv-presse-layout__aside .kv-presse-kontakt a,
.kv-presse-layout__aside .kv-presse-social a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

.kv-presse-layout__aside .kv-presse-kontakt a:hover,
.kv-presse-layout__aside .kv-presse-kontakt a:focus-visible,
.kv-presse-layout__aside .kv-presse-social a:hover,
.kv-presse-layout__aside .kv-presse-social a:focus-visible {
	text-decoration-thickness: 3px;
}

/* Social-Media-Buttons (04.09.): Die Linkliste der Sektion
 * kv-presse-social ist durch sechs Ghost-Buttons (Systemvariante
 * is-style-secondary-ink, Optik komplett aus dem Button-System oben)
 * ersetzt: Icon + Service-Name, ein Button pro Zeile (04.09. Korrektur,
 * Auftraggeber). Der Zeilenabstand 0.75rem (12px) ist bewusst Bedienung
 * (WCAG 2.2 Target Spacing: zu den 33px hohen Buttons bleibt >8px Luft);
 * die Buttons füllen die Kartenbreite, dadurch gleichmäßige Klickzonen.
 * Die Buttons sind wp:html-Freeform mit den core-Klassen; die Flow-Regel
 * der Sektion (blockGap) würde den einzelnen wp-block-button-Kindern je
 * 20px Margin geben — der Abstand kommt allein aus dem Grid, deshalb
 * margin: 0. */
.kv-presse-social__buttons {
	display: grid;
	gap: 0.75rem;
	grid-template-columns: minmax(0, 1fr);
}

.kv-presse-social__buttons > .wp-block-button {
	margin: 0;
}

/* Link als Flex-Zeile Icon + Text (04.09., vierte Korrektur): Die
 * Pillen fuellen volle Kartenbreite (Auftraggeber), die Icon+Text-
 * Gruppe wird darin ZENTRIERT (justify-content: center) — und die
 * Service-Namen stehen trotzdem buendig untereinander. Trick: jeder
 * Label-Span traegt dieselbe min-width (4.75em, s. u.). Damit ist
 * die Gruppe in allen sechs Buttons exakt gleich breit; zentriert
 * sitzt sie bei allen auf demselben x, also auch Icon-Kante und
 * Textanfang. text-align: left stellt sicher, dass kuerzere Namen in
 * ihrer Equal-Size-Box links buendig bleiben. Uniforme
 * 20x20-Icon-Boxen (Regel unten) zaehlen zusaetzlich: die Logos
 * haben natuerlich verschiedene Seitenverhaeltnisse (Mastodon
 * 18,65x20, YouTube 20x14). text-decoration: none, weil die globale
 * a-Regel sonst die Button-Beschriftung unterstreicht (Praezedenz
 * .kv-darum/.kv-panel-section). Die Buttons blockieren den
 * Unterstreichungs-Hover der Aside-Linkregeln (0,3,x gegen 0,2,x),
 * Farbe und Hover-Fill bleiben vollstaendig beim Button-System. */
.kv-presse-social__buttons .wp-block-button__link {
	align-items: center;
	display: flex;
	gap: 0.5rem;
	justify-content: center;
	text-align: left;
	text-decoration: none;
	width: 100%;
}

/* Label-Box (04.09., vierte Korrektur): min-width in em skaliert mit
 * der fluiden Button-Typo (clamp), das Laengsten-Label "Instagram"
 * misst 4,53em — 4,55em laedt alle kuerzeren Namen auf dieselbe
 * Breite auf, ohne dass Instagram jemals darueber hinauswaechst
 * (waechse ueber die min-width hinaus, wuerde nur seine eigene Box
 * groesser machen und die Buendigkeit brechen — bei kuenftigen,
 * laengeren Service-Namen im Pattern aufpassen). white-space: nowrap
 * verhindert Umbrueche, die die Gleichlaeufigkeit der Boxhoehen
 * storen koennten. */
.kv-presse-social__label {
	min-width: 4.55em;
	white-space: nowrap;
}
.kv-presse-social__buttons svg {
	display: block;
	flex: none;
	height: 20px;
	width: 20px;
}

/* Eintragsliste: Listenstil zurücksetzen, einspaltig. Seit dem 18.08.2026
 * gibt es keine Hairline-Trenner je Eintrag mehr (border-block-end
 * entfernt); der Abstand zwischen den Einträgen entsteht über
 * margin-bottom: 2.5rem an .kv-presse-entry, der Grid-Gap steht darum auf
 * 0, damit sich beides nicht addiert. */
.kv-presse-list {
	display: grid;
	gap: 0;
	grid-template-columns: minmax(0, 1fr);
	list-style: none;
	margin: 0;
	padding: 0;
}

.kv-presse-list > * + * {
	margin-block-start: 0;
}

/* Eintrag: margin-bottom 2.5rem trennt die Einträge großzügig
 * (mehr Luft als die früheren 24px), padding-bottom 16px hält den
 * Inhalt sauber von der Trennkante. */
.kv-presse-entry {
	margin-bottom: 2.5rem;
	padding-bottom: 16px;
}

/* Letzter sichtbarer Eintrag: ohne den 2.5rem-Margin nach unten, damit der
 * Toggle (eigener margin-top: 1rem) dicht an der Liste bleibt. Der Selektor
 * zielt auf den letzten nicht versteckten Eintrag statt auf das DOM-letzte
 * li: klappt das JS die Liste über das hidden-Attribut zusammen, wäre das
 * DOM-letzte li sonst versteckt und der letzte sichtbare Eintrag behielte
 * seine 2.5rem, die als Lücke über dem Toggle stünden. Greift damit in
 * beiden Zuständen (zusammengeklappt und aufgeklappt). Das padding-bottom
 * des Eintrags bleibt als Atem vor dem Toggle. */
.kv-presse-list li.kv-presse-entry:not([hidden]):not(:has(~ li.kv-presse-entry:not([hidden]))) {
	margin-bottom: 0;
}

/* Defensive hidden-Regel für die Einträge: Das JS klappt die Liste über das
 * hidden-Attribut zusammen; setzt eine künftige Regel display auf den
 * Einträgen, bleibt die Sichtbarkeits-Logik erhalten (Spiegel der
 * kv-presse-toggle[hidden]-Regel). */
.kv-presse-list [hidden] {
	display: none;
}

/* Datum: muted über die etablierte Muted-Tönung des Themes (ink bei 75 %,
 * ≈ 5.8:1 WCAG-AA auf paper), 17/24-Metrik wie kv-article-card__date
 * (fluid 15–17px auf fester 24px-Zeilenhöhe), ohne Karten-Padding.
 * margin-block-start: 0 entzieht dem <p> den UA-Default-Abstand (≈17px),
 * damit Logo (6px) und Datum (4px) das Datum einrahmen;
 * margin-block-end hält es dicht am Titel. */
.kv-presse-entry__date {
	color: rgba(5, 43, 142, 0.75);
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem);
	line-height: 24px;
	margin-block-end: 0.25rem;
	margin-block-start: 0;
}

/* Titel: fluid 18–24px/700 mit 125 % Zeilenhöhe, die Schrift erbt das
 * Überschriften-Element (IBM Plex Sans über die Heading-Typo des Themes).
 * Die Clamp hält den Titel stets unter den Abschnittsüberschriften (large,
 * 22–34px): Bei 375px steht der Titel bei ≈18px unter dem h2 mit 22px, bei
 * 1440px bei 24px unter dem h2 mit 34px, damit die Hierarchie nie kippt.
 * margin-block-start: 0 hebt den WordPress-Default-Abstand auf, damit das
 * Datum direkt darüber sitzt; margin-block-end: 12px liefert den Abstand zur
 * Aktionszeile. 12px statt 8px: gewünscht ist eine größere visuelle Lücke
 * zwischen Titel und Aktionszeile. Datum→Titel bleibt bei 4px (Datum-MB),
 * die Aktion selbst hat kein Top-Margin mehr
 * (siehe .kv-presse-list .kv-presse-entry__action). */
.kv-presse-entry__title {
	font-size: clamp(1.125rem, 1.8vw, 1.5rem);
	font-weight: 700;
	line-height: 125%;
	margin-block-end: 12px;
	margin-block-start: 0;
}

/* Titel (beider Eintragslisten) ist seit 04.09. reiner Text — die
 * fruehere Titel-Link-Regel (ink + Unterstreichung nach KERN-UX) lief
 * mit dem Entkernen der Titel-Links (Pressemitteilungen zuerst,
 * Pressespiegel 04.09.) ins Leere und ist entfernt; die Verlinkung
 * laeuft ausschliesslich ueber die Buttons der Aktionszeile. Die
 * Typo-Regel .kv-presse-entry__title weiter oben bleibt unveraendert. */

/* Logo des Mediums: feste Höhe 28px, Breite proportional, object-fit:
 * contain als Defensive gegen Verzerrung; display: block entzieht das
 * Inline-Bild der Zeilengeometrie (der sonst unterhalb des Bildes liegende
 * Zeilen-Descender würde den Abstand zum Datum künstlich vergrößern).
 * margin-block-end: 6px hält die Luft zum folgenden Datum (18.08.2026:
 * von 4px erhöht). */
.kv-presse-entry__logo {
	display: block;
	height: 28px;
	margin-block-end: 6px;
	object-fit: contain;
	width: auto;
}

/* Aktionszeile (sekundärer Button): kein eigenes Top-Margin (0), den
 * Abstand zur Titelzeile liefert jetzt das margin-block-end: 12px des
 * Titels. Die intra-Eintrag-Abstände: Logo→Datum 6px (18.08.2026 von 4px
 * erhöht), Datum→Titel 4px, Titel→Aktion 12px. Kein display: flex auf dem
 * .wp-block-button-Wrapper (18.08.2026, zweite Korrektur): flex streckte
 * die innere .wp-block-button__link (width: 100% aus Core) auf volle
 * Spaltenbreite. Ohne die Flex-Deklaration greift wieder die Core-Regel
 * `.wp-block-buttons > .wp-block-button` (display: inline-block,
 * margin-top: 0), der Button hat natürliche Inline-Breite. Der
 * Listen-Prefix (0,2,0) bleibt nötig, damit das margin-block-start: 0
 * gegen das Core-margin-top: 0 gewinnt. */
.kv-presse-list .kv-presse-entry__action {
	margin-block-start: 0;
}

/* Button-Abstand in der Aktionszeile (04.09., Bedienung): Der
 * Pressemitteilungen-Block rendert den .wp-block-buttons-Wrapper ohne
 * Core-Layout-Klassen, die Core-gap-Regel (.is-layout-flex) greift dort
 * nicht — die Buttons ("Jetzt lesen", "Download als PDF (…)") klebten
 * aneinander. display: flex + wrap spiegelt core's .is-layout-flex-Regel
 * (der Render-Callback liefert die Klasse nicht mit); ohne flex greift
 * gap im Block-Container nicht. Beide Achsen 0.75rem (12px) wie der
 * Social-Buttons-Abstand (WCAG-2.2-Target-Spacing-Reserve). */
.kv-presse-list .wp-block-buttons {
	column-gap: 0.75rem;
	display: flex;
	flex-wrap: wrap;
	row-gap: 0.75rem;
}

/* Pressinfo-Sektion (14.09., zwei Download-Buttons "Vereinsprofil als
 * PDF (…)" und "Logo als ZIP (…)"): Der Render-Callback liefert den
 * .wp-block-buttons-Wrapper ohne Core-Layout-Klassen (gleiche Lage wie
 * .kv-presse-list .wp-block-buttons oben), deshalb dieselbe
 * Spiegel-Regel: display: flex + wrap, beide Achsen 0.75rem (12px).
 * Mit einem Button verhält sich die Reihe identisch zum bisherigen
 * Einzelbutton; mit zwei Buttons laufen sie inline nebeneinander und
 * brechen bei schmalen Viewports um. */
.kv-pressinfo__buttons {
	column-gap: 0.75rem;
	display: flex;
	flex-wrap: wrap;
	row-gap: 0.75rem;
}

/* "Alle … anzeigen"-Toggle (Pressemitteilungen: „Alle Pressemitteilungen
 * anzeigen", Pressespiegel: „Alle Einträge anzeigen"): hebt sich als
 * einziger gefüllte Button von den secondary-ink-Ghosts der Karten ab.
 * Ruhezustand (zugeklappt, Aktion = Öffnen) ist der primary-ink-Look
 * (ink-Fill, paper-25-Text 11.85:1 AAA), Hover/Fokus dunkelblau-75
 * #3F62AD wie im Button-System. Aufgeklappt (aria-expanded="true", Label
 * „Weniger Pressemitteilungen/Einträge anzeigen") fällt er bewusst auf den Ghost zurück:
 * die Rücknahme-Aktion wird leiser als das Öffnen; Ghost-Hover wieder
 * ink-Fill (wie secondary-ink). Die Aufgelöst-Reihenfolge hält die
 * Kaskade: Expanded-Ruhe (0,2,0) nach Fill-Hover (0,2,0), Expanded-Hover
 * (0,3,0) gewinnt gegen beide. Chevron als ::after (siehe unten).
 * Geometrie aus dem Button-System: Padding 0.75rem/1rem, Radius 8,
 * 17px/600/0.02em. Der Toggle ist ein natives <button> und KEIN
 * .wp-block-button-System-Button; margin-inline: auto zentriert ihn unter
 * der Liste, margin-top gibt den Abstand zum Listenende. font-family:
 * inherit und text-align: center sind nötig, weil das UA-Stylesheet für
 * button-Elemente Arial erzwingt. */
.kv-presse-toggle {
	background: var(--wp--preset--color--ink);
	border: 1.5px solid var(--wp--preset--color--ink);
	border-radius: 8px;
	box-sizing: border-box;
	color: var(--wp--preset--color--paper-25);
	cursor: pointer;
	display: block;
	font-family: inherit;
	font-size: clamp(0.9375rem, 1.5vw, 1.0625rem);
	font-weight: 600;
	letter-spacing: 0.02em;
	line-height: 1.2;
	margin-inline: auto;
	margin-top: 1rem;
	padding: 0.75rem 1rem;
	text-align: center;
}

.kv-presse-toggle:hover,
.kv-presse-toggle:focus-visible {
	background: #3F62AD;
	border-color: #3F62AD;
	color: var(--wp--preset--color--paper-25);
}

.kv-presse-toggle[aria-expanded="true"] {
	background: transparent;
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--ink);
}

.kv-presse-toggle[aria-expanded="true"]:hover,
.kv-presse-toggle[aria-expanded="true"]:focus-visible {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

/* Chevron-Richtungsweiser als ::after: presse-lists.js tauscht das
 * Button-Label per textContent, ein Kind-Element im Markup würde dabei
 * gelöscht — das Pseudo-Element überlebt. Border-Trick (rechts+unten,
 * 45° = Chevron nach unten, -135° = nach oben), currentColor passt sich
 * der jeweiligen Button-Textfarbe an; 3px Strich, damit der Winkel bei
 * 17px nicht hairline-fein wirkt. Die Richtung folgt aria-expanded,
 * das JS setzt, also ohne zusätzlichen Code. Aufgeklappt liegt die
 * Spitze des Border-Winkels rechnerisch ~0,05em über der Cap-Oberkante
 * des Textes; das translateY(0.2em) (vor der Rotation, also in
 * Bildschirmkoordinaten) holt den nach-oben-Chevron sichtbar unter den
 * oberen Textrand. Rotation animiert nur unter no-preference (die
 * globale reduce-Regel würde sonst ohnehin auf 0.01ms ziehen; der Guard
 * hält die Regel-Paare symmetrisch). */
.kv-presse-toggle::after {
	border-bottom: 3px solid currentColor;
	border-right: 3px solid currentColor;
	content: "";
	display: inline-block;
	height: 0.5em;
	margin-inline-start: 0.6em;
	transform: rotate(45deg);
	vertical-align: 0.15em;
	width: 0.5em;
}

.kv-presse-toggle[aria-expanded="true"]::after {
	transform: translateY(0.2em) rotate(-135deg);
}

@media (prefers-reduced-motion: no-preference) {
	.kv-presse-toggle::after {
		transition: transform 0.25s ease;
	}
}

/* hidden-Attribut schlägt display: Das UA-Stylesheet ([hidden] {
 * display: none }) würde sonst von display: block übersteuert und der
 * Toggle wäre trotz hidden sichtbar, kaputt für den No-JS-Fall. */
.kv-presse-toggle[hidden] {
	display: none;
}

/* Visuell versteckter Text (z. B. Labels der Buch- und Newsletter-Patterns):
 * absolute Positionierung plus Clip-Standardmuster, identisch zu den
 * bestehenden .screen-reader-text-Regeln des Themes. */
.kv-screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* Einspaltiger Umbruch ≤781px: Die Kontaktspalte steht jetzt OBERHALB des
 * Inhalts (grid-template-areas "aside" "content"), Stickiness entfällt. Die
 * Aside selbst wird zum zweispaltigen Grid: Die zwei Sektionen des
 * presse-kontakt-Patterns (Pressekontakt und Social Media) liegen dann
 * nebeneinander statt untereinander. minmax(0, 1fr) verhindert, dass lange
 * Social-URLs die Spalten aufblähen; das Brechen übernimmt die
 * overflow-wrap-Regel der Social-Links. Die Spaltenbreiten gleichen sich
 * an, die kürzere Sektion füllt ihre Zelle mit dem Karten-Hintergrund.
 * margin-block-start: 0 auf der zweiten Sektion hebt die Flow-Gap der
 * Aside auf (Core blockGap 1.25rem, Desktop zusätzlich 40px
 * Karten-Abstand), die das zweite Grid-Kind sonst aus der Flucht schieben
 * würde; der Abstand zwischen den Sektionen kommt allein aus dem Grid-Gap. */
@media (max-width: 781px) {
	.kv-presse-layout {
		grid-template-areas: "aside" "content";
		grid-template-columns: minmax(0, 1fr);
	}

	.kv-presse-layout__aside {
		display: grid;
		gap: clamp(1rem, 3vw, 2rem);
		grid-template-columns: repeat(2, minmax(0, 1fr));
		position: static;
	}

	.kv-presse-layout__aside > * + * {
		margin-block-start: 0;
	}
}

/* Sehr schmale Smartphones ≤479px: Die zweispaltige Aside-Anordnung aus
 * der 781px-Regel wird auf diesen Viewports zu eng, die zwei Sektionen des
 * presse-kontakt-Patterns (Pressekontakt und Social Media) stapeln sich
 * deshalb wieder untereinander. display: grid, der Gap
 * (clamp(1rem, 3vw, 2rem)) und margin-block-start: 0 bleiben aus der
 * 781px-Regel bestehen, nur die Spaltenzahl fällt auf eine zurück. */
@media (max-width: 479px) {
	.kv-presse-layout__aside {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Reveal der Einträge beim Aufklappen: kurz eintauchen statt hart
 * einblenden. Ausschließlich unter no-preference definiert, die Keyframes
 * liegen mit im Media-Block; unter prefers-reduced-motion: reduce existiert
 * gar keine Animation. */
@media (prefers-reduced-motion: no-preference) {
	.kv-presse-entry--reveal {
		animation: kv-presse-reveal 200ms ease-out both;
	}

	@keyframes kv-presse-reveal {
		from {
			opacity: 0;
			transform: translateY(4px);
		}
		to {
			opacity: 1;
			transform: translateY(0);
		}
	}
}

/*
 * Blog-Posts-Block (klima-vor-acht/blog-posts) — kv-blog-posts
 * Raster und Karten folgen dem Muster der Archiv-Karten (kv-article-card,
 * vormals auch der Presse-Karten), die Spaltenanzahl steuert die
 * Inline-CSS-Variable --kv-blog-posts-columns (1–5, vom Render-Callback
 * gesetzt). Keine neuen Farben/Animationen; die Karten-Kompaktierung
 * ≤782px kommt automatisch aus .kv-article-card (siehe dort).
 */

/* Raster mit 1–5 Spalten über die CSS-Variable des Blocks (Default 3). */
.kv-blog-posts__grid {
	display: grid;
	gap: 40px;
	grid-template-columns: repeat(var(--kv-blog-posts-columns, 3), minmax(0, 1fr));
}

.kv-blog-posts__grid > * + * {
	margin-block-start: 0;
}

.kv-blog-posts-card .wp-block-post-title a {
	color: inherit;
	text-decoration: none;
}

/* Hover/Fokus am Titel-Link selbst — Spiegel der Archiv-Karte
 * (.kv-article-card .wp-block-post-title a:hover, Auftrag 12.09.): kein
 * Vollflächen-Overlay mehr, die Karte klickt nur noch über Titel-Link,
 * Badge und Button wie auf der Seite "Aktuelles". */
.kv-blog-posts-card .wp-block-post-title a:hover,
.kv-blog-posts-card .wp-block-post-title a:focus-visible {
	color: var(--wp--preset--color--blue);
	text-decoration: underline;
}

/* Fallback-Medienbereich für Beiträge ohne Beitragsbild. */
.kv-blog-posts-card__media--fallback {
	align-items: center;
	aspect-ratio: 352 / 198;
	display: flex;
	justify-content: center;
}

/* Gradkreis-Platzhalter im Fallback (Klasse wird per PHP gerendert, siehe
 * inc/blog-posts.php klima_vor_acht_blog_posts_card_media; seit Auftrag
 * 12.09. nur noch für das Motiv 'gradkreise' relevant, aktiv ist
 * 'kv8-logo'): wie beim Presse-
 * Karten-Fallback eine 352:198-Vollflächen-Komposition aus vier kleinen
 * Gradkreisen (rein ink, dekorativ), die die Bildfläche komplett ausfüllen
 * und am Rand gewollt angeschnitten sind. Der ink-Kontrast auf allen zehn
 * hellen Tint-Flächen der Fallback-Palette liegt zwischen 6.35:1 und 11.85:1;
 * Ton-in-Ton-Kombinationen gibt es nicht, signal kommt in den Platzhaltern
 * nicht vor. height/width 100 % füllen die Fallback-Figur vollflächig,
 * object-fit: cover schneidet außen passend an, display: block vermeidet
 * Inline-Gap; die flex-Zentrierung der Fallback-Figur
 * (.kv-blog-posts-card__media--fallback) greift dadurch nicht mehr. */
.kv-blog-posts-card__gradkreis {
	display: block;
	height: 100%;
	object-fit: cover;
	width: 100%;
}

/* Kv8-Wortmarke im Karten-Fallback (temporär 11.09./12.09., Klasse wird per
 * PHP gerendert: Archiv-Fallback functions.php
 * klima_vor_acht_card_logo_fallback_markup und Blog-Posts-Block inc/
 * blog-posts.php, Motiv KV8_CARD_FALLBACK_ART = 'kv8-logo'): die ink-Variante der
 * Wortmarke (kv8-logo-ink.svg, identische Geometrie zum Header-Logo) auf
 * fester paper-Fläche — immer Ink auf paper (Auftrag 11.09.), ohne
 * Palette-Wurf. object-fit: contain zeigt das rund 7.9:1-Logo vollständig
 * und zentriert in der 352:198-Media-Fläche, anstatt es wie Thumbnails/
 * Gradkreise am Format zu beschneiden; padding hält bewusst Luft, damit
 * die Marke die Fläche nicht kantenberührend füllt. box-sizing: border-box
 * ist bewusst explizit: Im Archiv liefert sie das Core-CSS des
 * wp:post-featured-image-Blocks (.wp-block-post-featured-image :where(img)),
 * der Blog-Posts-Pfad rendert dieselben Klassen aber ohne diesen Wrapper —
 * ohne explizite Angabe wäre das img dort content-box (100 % + 2×2.5rem
 * Padding = 80px Overflow über die Kartenbreite).
 * width/height 100% überschreiben die Bestandsregel
 * .kv-article-card__image img (aspect-ratio/object-fit cover) für dieses
 * img. */
.kv-article-card__image img.kv-article-card__logo-mark {
	box-sizing: border-box;
	display: block;
	height: 100%;
	object-fit: contain;
	padding: 2.5rem;
	width: 100%;
}

/* Kategorie-Badge (showCategory): Fläche/Position/Padding kommen aus den
 * bestehenden .kv-article-card__tag-Regeln; nur Mini-Regeln hier. Der Tag
 * bleibt absolut in der Media-Ecke positioniert (wie bei den Archiv-Karten).
 * Ohne Unterstreichung wie die Archiv-Badges; bei Hover/Fokus dicke
 * Unterstreichung (2px, Theme-Konvention der Content-Link-Hover). */
.kv-blog-posts-card__tag {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	position: absolute;
	text-decoration: none;
	text-transform: uppercase;
}

.kv-blog-posts-card__tag:hover,
.kv-blog-posts-card__tag:focus-visible {
	background: #ffd183;
	text-decoration: underline;
	text-decoration-thickness: 2px;
}

/* Textlink-Aktionsbereich (linkType 'text-link'), Spiegel der Buttons-
 * Fläche der Karte; bei linkType 'button' greifen die bestehenden
 * .kv-article-card > .wp-block-buttons-Regeln. */
.kv-blog-posts-card > .kv-blog-posts-card__actions {
	margin-block-start: auto;
	padding: 1.25rem 2.5rem 2.5rem;
}

.kv-blog-posts-card__textlink {
	color: var(--wp--preset--color--ink);
	font-weight: 600;
}

.kv-blog-posts-card__textlink:hover,
.kv-blog-posts-card__textlink:focus-visible {
	color: var(--wp--preset--color--blue);
	text-decoration: underline;
}

/* Einspaltiger Umbruch bei ≤781px für das Blog-Posts-Raster, nach dem
 * Muster der Archiv-Media-Query (die Karten des Tag-Archivs stapeln dort
 * ebenfalls auf minmax(0, 1fr)). Kein horizontaler Overflow, geprüft bei
 * 375px. Die Presse-Liste kv-presse-list ist einspaltig und braucht hier
 * keinen Eintrag. */
@media (max-width: 781px) {
	.kv-blog-posts__grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/*
 * ---------------------------------------------------------------------------
 * Spenden-CTA über dem Footer (Beitragsseiten) — kv-post-cta
 * ---------------------------------------------------------------------------
 * Serverseitig gerenderter Aufruf (Block `klima-vor-acht/spendenaufruf`,
 * functions.php) auf Beitrags- und Seiten, unmittelbar über dem Footer. Layout
 * nach Figma "module-cta":
 * kv-section-Shell (1440px/1136px, Breakout), zentrierter Stack, schmalere
 * vertikale Padding als die Standard-Sektion (Min 40px vs 48px, Obergrenze
 * 80px). Fluid-Rampe seit 14.09. an den Sektionsstandard angeglichen
 * (8vw statt 5.5vw): beide Clamps konvergieren bei 1440px auf exakt 80px,
 * im Fluid-Band skaliert der CTA damit exakt wie jede andere Sektion.
 * Farbvarianten wechseln nur die Grundfläche; Textfarbe ist immer ink
 * (Kontraste: ink auf signal 7.40:1, auf leaf 6.91:1, auf paper 11.35:1 —
 * WCAG AA/AAA). Der Button nutzt die Systemvariante is-style-primary-ink
 * (ink-Fill/paper-25-Text, Hover dunkelblau-75), die globale signal-Fokus-
 * Outline wäre auf der Gelb-Variante unsichtbar, daher wird sie hier auf
 * ink umgestellt (auf allen drei Flächen ≥ 6.91:1).
 */

.kv-post-cta .kv-section__inner {
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	padding-block: clamp(2.5rem, 8vw, 5rem);
	text-align: center;
}

/* Kinder abstandsfrei (h2/p-UA-Margins neutralisieren), Stack-Gap wie im
 * Pattern: 40px Figma-Abstand, responsive gestaucht. */
.kv-post-cta .kv-section__inner > * {
	margin-block: 0;
}

.kv-post-cta .kv-section__inner > * + * {
	margin-block-start: clamp(1.5rem, 3vw, 2.5rem);
}

/* Claim als prägnante Überschrift (Display-Look, systemweit für
 * Überschriften); der Fließtext bleibt normale Fließgröße. */
.kv-post-cta__claim {
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 700;
	letter-spacing: -0.025em;
	line-height: 1.25;
}

/* CTA-Fließtext (Auftrag 05.09.): Intro-Groesse (normal-Preset-Clamp,
 * 18-24px fluid, Zeilenhoehe wie Body 1.55) — derselbe Wert wie die
 * .has-normal-font-size-Intros der Seiten (p hat hier keinen Core-Utility-
 * Konflikt, da der serverseitige Block ohne fontSize-Klasse rendert).
 * Unterzeile (.kv-post-cta__subline) traegt weiterhin bewusst keine eigene
 * Groessenregel und erbt die Body-Schriftgroesse. */
.kv-post-cta__text {
	font-size: var(--wp--preset--font-size--normal);
}

/* Der servergerenderte Block bringt kein is-layout-flex mit; die
 * Button-Gruppe und der Wrapper zentrieren explizit. */
.kv-post-cta__actions,
.kv-post-cta__actions .wp-block-buttons {
	display: flex;
	justify-content: center;
}

/* Farbvarianten: Gelb (signal), Türkis (leaf, Default), Warmweiß (paper).
 * Nur die Grundfläche wechselt, Text/Button bleiben ink-basiert. */
.kv-post-cta--gelb {
	background: var(--wp--preset--color--signal);
}

.kv-post-cta--tuerkis {
	background: var(--wp--preset--color--leaf);
}

.kv-post-cta--warmweiss {
	background: var(--wp--preset--color--paper);
}

/* Fokus: ink-Outline auf allen drei Grundflächen (auf signal wäre die
 * globale signal-Outline unsichtbar). */
.kv-post-cta :focus-visible {
	outline-color: var(--wp--preset--color--ink);
}

/* Auf ≥1440px exakt 80px Paddings (Figma "module-cta"). */
@media (min-width: 1440px) {
	.kv-post-cta .kv-section__inner {
		padding-block: 80px;
	}
}

/*
 * ---------------------------------------------------------------------------
 * Gradkreise (Designelement) — Sektions-Deko + Testimonial-Utility
 * ---------------------------------------------------------------------------
 * Das Gestaltungselement "Gradkreis" (gefüllter Ring, siehe Morphologie
 * unten) liegt als `background-image`-Schicht auf den Sektionsklassen,
 * nicht als DOM-Element (Plan .weave/plans/gradkreise.md,
 * Architektur-Entscheidung 13.08.):
 *
 * - Die CSS-Mal-Reihenfolge platziert die Background-Layer einer Sektion
 *   exakt zwischen deren Hintergrundfarbe und dem Inhalt ("über dem Grund,
 *   immer hinter Text/Bildern") — ohne z-index, ohne isolation, ohne Markup.
 * - Die Startseiten-Sektionen .kv-angebote/.kv-aktuelles sind editoriale
 *   Kopien in post_content; Deko über Pattern-Markup würde sie nicht
 *   erreichen. Die Block-Klassen has-paper-background-color /
 *   has-ink-background-color bleiben unverändert: background-image liegt bei
 *   gleichem Element per CSS-Reihenfolge über der background-color, genau
 *   gewollt.
 * - .kv-section und alle Sektionen bleiben un-positioniert (kein
 *   position/z-index/isolation): Der Hero-Overlay (bottom -40px, z-index 2,
 *   .kv-hero__overlay) hängt weiter über "Unser Ansatz". Background-Layer
 *   ändern daran nichts.
 *
 * Morphologie der Felder (finaler Stand 13.08., Korrekturstand I/L — fest
 * im Generator, Projekt-Root .weave/tmp/gradkreise/generate.mjs, der
 * deterministisch mit minGap 24 und 0 Randbeschnitt erzeugt; Belege in
 * .weave/tmp/gradkreise/ und .weave/learnings/gradkreise.md):
 *   - Ein Gradkreis ist ein GEFÜLLTER RING: ein <path> mit zwei
 *     gegenläufigen Kreisbögen (außen R, innen rIn = R × (1 − band), band
 *     thin 0,156 / medium 0,30 / regular 0,62), fill = Farbe, KEIN Stroke.
 *     KEINE Ticks, KEINE <line>-Elemente, KEINE Punkte.
 *   - "kontur" (Ausnahme, max. 1 je Feld): derselbe Pfad, aber fill="none"
 *     + stroke = Farbe, rIn = 0,4 × R, stroke-width 7,7 (≈ 0,375 % der
 *     Feldbreite). Gefüllt ist der Normalfall, kontur die Ausnahme.
 *   - paper-Feld (auf hellem Grund): 2048 × 4096, Höhe verdoppelt seit
 *     13.08. I, damit auf schmalen Bildschirmen keine großen leeren
 *     Flächen entstehen. 14 Kreise (13× grad + 1× kontur) in 5 Reihen über
 *     die volle Höhe.
 *   - ink-Feld (auf dunklem Grund): 2048 × 2048, 8 Kreise (7× grad + 1×
 *     kontur), gleichmäßig über die Fläche verteilt (oberes/unteres
 *     Viertel, linke/rechte Hälfte, Band um die Mitte). Dichte: max. 1
 *     "kontur" je Feld, Mindest-Kantenabstand 24, 0 Randbeschnitt.
 *
 * Farbwelt paper (auf hellem Grund, ".kv-angebote"): ink #052B8E
 *   (dominant, 2 Ringe), blue #317FE3, leaf #2ADCBA, signal #FFC04E,
 *   tuerkis-75 #7AE6CB (1× grad + 1× kontur), tuerkis-50 #95EEDD,
 *   mittelblau-50 #98BFF1, mittelblau-25 #CCDFF8. Kontrast: nie Ton-in-Ton
 *   zum hellen Grund, das dunkle ink bleibt der stärkste Kontrast-Anker.
 *   (signal ist seit Korrektur J fest im paper-Feld, oben rechts.)
 * Farbwelt ink (auf dunklem Grund, ".kv-aktuelles"): paper-25 #FEFDFA
 *   (dominant), signal #FFC04E (1× grad + 1× kontur), tuerkis-75 #7AE6CB,
 *   mittelblau-50 #98BFF1.
 *
 * (Startseite, volle Fläche — Deko seit 17.08. entfernt, siehe unten),
 * .kv-darum (Startseite, volle Fläche, gespiegeltes paper-Feld),
 * .kv-archive (Blog-/Kategorie-/Tag-Archive, volle Fläche,
 * ink-Archiv-Feld), .kv-gradkreis-deco (Utility für die künftige
 * Testimonial-Komponente, unten).
 * (Startseite, volle Fläche), .kv-gradkreis-deco (Utility für die
 * künftige Testimonial-Komponente, unten).
 * Die Sektion .kv-wirkung (Startseite: der Slider "Unsere Wirkung" auf
 * ink; die künftige Wirkungsseite trägt dieselbe Klasse) bleibt BEWUSST
 * ohne Gradkreis-Deko — Entscheid des Auftraggebers 13.08. E ("Keine
 * Gradkreise in der section kv-wirkung!"). Erneute Aktivierung wäre eine
 * reine CSS-Aufgabe: einfach eine Regel mit background-image (ink-Feld)
 * plus background-position/-size an die Sektion hängen, wie bei den
 * beiden anderen Sektionen unten.
 *
 * Feste Ausschnitte (Crops) statt Zufall: pro Sektion eigene
 * background-position/-size auf dem Feld-SVG. Ein Ausschnittswechsel ist
 * reine CSS-Änderung, wenn ein Crop unpassend wirkt. Die Werte unten sind
 * KALIBRIERT 13.08.: angebote Desktop auf das verdoppelte paper-Feld
 * (Korrektur I; Belege .weave/tmp/gradkreise/corrH-verify.mjs, 26 Checks,
 * Screenshots corrI/), aktuelles plus Mobile unverändert seit Korrektur E
 * (corrE-verify.mjs). Pixel-Nachweise: Deko-Pixel in Textboxen ≈ 0,
 * Geometrie-Proben, Screenshots; siehe auch
 * .weave/learnings/gradkreise.md. Geändert wird nur
 * background-position/-size, keine Hintergrundfarbe.
 */

/* Paper-Feld-Split (13.09.): gradkreise-field-paper.svg (Ringe nur in einem
 * Teil des Feldes) bleibt der Startseiten-Sektion .kv-angebote vorbehalten.
 * Alle übrigen paper-Sektionen (Seite 38 Veranstaltungen, Spenden-Seite 39,
 * Seite 33 Erkenntnis — Baseline UND ≥1920-rot90) nutzen die Vollflächen-
 * Kopie gradkreise-field-paper-full.svg (Auftraggeber: Ringe ueber die
 * ganze Flaeche); rot90-Dateien analog: -full-rot90cw / -full-rot90ccw.
 * Die je Sektion kalibrierten background-position/-size bleiben unangetastet. */

/* Startseite "Unsere Angebote": Breiten-Skalierung, Deko ragt ~10–20 % in die
 * blauen Panels (kv-offer-card) hinein (Auftraggeber 31.08.: "etwa 15 % in
 * die Panels reinragen", Toleranz 10–20 %; danach erhöht auf ~20 %:
 * "Erhöhe das Reinragen auf 20 %!" und danach auf 25 %.
 * background-size: X% auto —
 * die Bildbreite = X% der Sektionsbreite, die Höhe folgt dem 1:2-paper-Feld
 * (Höhe = 2× Breite, überdeckt die Sektionshöhe). X ist gestuft, weil die
 * Panel-Position nicht linear mit der Breite wandert (Grid-Umbruch
 * ~1050–1300): ≥1301 px sind die Panels zentriert (Start = W/2−160, Breite
 * 729) → calc(50% + 22px) = exakt ~25 % Reinrage (gedeckelt mit
 * min(..., 1150px): Ringe nie größer als Skala 0.56 — Auftraggeber
 * 31.08.: "Nur zu groß sollen sie nicht werden"); darunter feste Stufen
 * (62/58/55 %), gemessen gegen die echten Panel-Positionen
 * (Messung 31.08., 783–2560 px). Rotation unnötig: das ungedrehte Feld
 * deckt Höhe UND Reinrage. `cover` wäre falsch (volle Breite). Position 0%
 * 34% wie bisher. Der has-paper-background-color-Grund bleibt unterste
 * Schicht. Kontrast-Check: check-angebote-contrast-31-08.mjs. */
.kv-angebote {
	background-image: url("assets/images/gradkreise/gradkreise-field-paper.svg");
	background-position: 0% 34%;
	background-repeat: no-repeat;
	background-size: min(calc(50% + 22px), 1150px) auto;
}

/* Stufen für den Grid-Umbruch-Bereich (Panel-Position wandert dort mit der
 * Sektionsbreite, nicht zentriert): ~25 %-Reinrage laut Messung. */
@media (min-width: 783px) and (max-width: 1050px) {
	.kv-angebote {
		background-size: 62% auto;
	}
}

@media (min-width: 1051px) and (max-width: 1150px) {
	.kv-angebote {
		background-size: 58% auto;
	}
}

@media (min-width: 1151px) and (max-width: 1300px) {
	.kv-angebote {
		background-size: 55% auto;
	}
}

/* Archiv-Sektionen (Blog-Übersicht /aktuelles/, Kategorie- und Tag-Archive,
 * Template category.html/home.html/tag.html, 24.08.): dieselbe Architektur
 * auf der dunkelblauen ink-Fläche mit dem separaten ink-Archiv-Feld
 * gradkreise-field-ink-archive.svg — anfangs byte-identische Kopie des
 * ink-Felds (Stand 24.08.); seit 25.08. eigene, vom Auftraggeber
 * nachbearbeitete Komposition (nicht mehr ink-identisch).
 * background-size: cover (31.08.): skaliert das 4:1-Feld gleichmäßig so,
 * dass die Sektion in Höhe UND Breite immer vollständig bedeckt ist —
 * auch bei sehr hohen Mobile-Sektionen (390 px Sektionsbreite → 1560 px
 * Bandhöhe bei 100% auto reichte nicht); Überlauf wird beschnitten, die
 * Ringe bleiben rund (kein 100% 100%-Stretch). background-position 50% 50%
 * zentriert den sichtbaren Ausschnitt. Die opaken weißen Artikel-Karten
 * maskieren die Deko; offene Textboxen (Kategorie-Pillen, H1) bleiben nach
 * Kontrastmessung über 4.5:1 (bzw. 3:1 ab 24 px) — Deko-Anteil hinter dem
 * Text ist zu gering, um den paper-Text auf ink zu drücken (Check
 * .weave/tmp/gradkreise/check-archive-contrast-31-08.mjs, 320–2560 px). */
.kv-archive {
	background-image: url("assets/images/gradkreise/gradkreise-field-ink-archive.svg");
	background-position: 50% 50%;
	background-repeat: no-repeat;
	background-size: cover;
}

/* Ressourcen-Seite "Klimaberichterstattung im ÖRR" (Seite 33), Abschnitt
 * "KI gestützt und Real-Time": Diese Sektion trägt seit 13.09. BEWUSST
 * KEINE Gradkreis-Deko mehr (Auftraggeber: "Gradkreise entfernen";
 * Präzedenz .kv-wirkung, siehe oben). Frühere Deko: Original-ink-Feld
 * gradkreise-field-ink.svg (100% auto + 50% 0%), ab 1920px gedreht
 * -ink-rot90cw (250% auto + 0% 0%). Reaktivierung wäre eine reine
 * CSS-Aufgabe: Regel mit background-image (ink-Feld bzw. -rot90cw) plus
 * background-position/-size wieder an die Sektion hängen — Scope wie
 * damals über body.page-id-33 + has-ink-background-color (auf Seite 33
 * eindeutig; .kv-panel-section ist ein generisches Mehrmuster). */
/* Ressourcen-Seite "Materialien" (Seite 37), Abschnitt "Klimaquartett"
 * (24.08.): Volllfächen-Deko auf der weißen Fläche mit dem separaten
 * weiß-Feld gradkreise-field-white.svg — anfangs Kopie des ink-Felds
 * (Stand 24.08.); seit 25.08. stark nachbearbeitete, eigene
 * Auftraggeber-Komposition. Scope über body.page-id-37 +
 * has-white-background-color — das Panel-Sections-Muster ist generisch.
 * 100 % auto + 50% 0% zeigt bei 1440 px die oberen Ring-Reihen des
 * 4:1-Felds (Feld-y ≈ 29–1050 → Sektions-y ≈ 20–739, Stand 24.08.). */
body.page-id-37 .kv-panel-section.has-white-background-color {
	background-image: url("assets/images/gradkreise/gradkreise-field-white.svg");
	background-position: 50% 0%;
	background-repeat: no-repeat;
	background-size: 100% auto;
}
/* Ressourcen-Seite "Speaker buchen" (Seite 38), Abschnitt "Vergangene
 * Veranstaltungen" (24.08.): Volllfächen-Deko auf der paper-Fläche mit
 * dem Vollflächen-Feld gradkreise-field-paper-full.svg (auf warmweiß
 * abgestimmt; das gespiegelte Feld bleibt der Darum-Sektion vorbehalten).
 * Scope über body.page-id-38 + has-paper-background-color. 13.09. auf
 * FULL-BLEED umgestellt (Auftraggeber): background-size: cover bedeckt die
 * Sektion vollständig. Desktop nutzt das QUERFORMAT der rot90-Variante
 * (Feld 2:1 ≈ Sektionsformat 783–1919px — cover zeigt die ganze Komposition);
 * das Hochformat-Feld (1:2) zeigt bei cover auf flachen Sektionen nur einen
 * ringfreien Papierstreifen. Mobile ≤782px: Hochformat-Feld, siehe unten. */
body.page-id-38 .kv-panel-section.has-paper-background-color {
	background-image: url("assets/images/gradkreise/gradkreise-field-paper-full-rot90ccw.svg");
	background-position: 50% 50%;
	background-repeat: no-repeat;
	background-size: cover;
}

/* Spenden-Seite (39), Abschnitt "Jetzt online spenden":
 * Das Widget-iframe (id^=twingleframe, von Twingle ohne Klasse eingesetzt)
 * bekommt abgerundete Ecken. Vorsicht: assets/css/twingle.css laeuft IM
 * iframe-Dokument und erreicht das iframe-Element selbst NICHT — der Radius
 * gehoert hierher (Frontend-CSS der Seite). */
[id^="twingleframe"] {
	border-radius: 1.5rem;
}

/* Spenden-Seite (39), Abschnitt "Jetzt online spenden" (13.09.):
 * Volllaechen-Deko auf der paper-Flaeche mit dem Vollflächen-Feld
 * gradkreise-field-paper-full.svg (Ringe auf der ganzen Fläche). Scope ueber
 * .kv-spenden-online (im Seiten-Markup; die Sektion traegt bewusst KEINE
 * Hintergrundklasse — ihr Grund bleibt das page.html-paper, Praezedenz
 * fuer Sektionsklassen: .kv-erkenntnis/.kv-ueber-action).
 * Die Twingle-iframe-Konserve (bis 434px hoch) liegt blickdicht ueber der
 * Deko und ist in der Kalibrierung als Maske gerechnet.
 * 13.09. auf FULL-BLEED umgestellt (Auftraggeber): background-size: cover
 * bedeckt die Sektion vollständig; das blickdichte Twingle-iframe maskiert
 * die Mitte. Desktop nutzt das QUERFORMAT der rot90cw-Variante (2:1 ≈
 * Sektionsformat), Mobile das Hochformat — siehe Media-Query unten. */
.kv-spenden-online {
	background-image: url("assets/images/gradkreise/gradkreise-field-paper-full.svg");
	background-position: 0% 50%;
	background-repeat: no-repeat;
	background-size: cover;
}

/* Ressourcen-Seite "Klimaberichterstattung im ÖRR" (Seite 33), Abschnitt
 * "Die wichtigste Erkenntnis" (28.08.): Volllfächen-Deko auf der paper-Fläche
 * mit dem Vollflächen-Feld gradkreise-field-paper-full.svg. Die Seite trägt
 * eine ZWEITE paper-Sektion ("Programmbeschwerden"), die bewusst un dekoriert
 * bleibt; Scope daher über die Sektionsklasse .kv-erkenntnis (im Seiten-
 * Markup) statt body.page-id-33 + has-paper-background-color.
 * 13.09. auf FULL-BLEED umgestellt (Auftraggeber): background-size: cover
 * bedeckt die Sektion vollständig. Desktop nutzt das QUERFORMAT der
 * rot90cw-Variante (2:1 ≈ Sektionsformat), Mobile das Hochformat — siehe
 * Media-Query unten. */
body.page-id-33 section.kv-panel-section.kv-erkenntnis {
	background-image: url("assets/images/gradkreise/gradkreise-field-paper-full-rot90cw.svg");
	background-position: 50% 50%;
	background-repeat: no-repeat;
	background-size: cover;
}

/* Ehrenamt-Seite (Seite 40), Abschnitt "Was du mitbringen solltest" / "Was dir
 * die Mitarbeit gibt" (28.08.): Volllfächen-Deko auf der weißen Fläche mit dem
 * weiß-Feld gradkreise-field-white.svg — dieselbe Kalibrierung wie die
 * white-Sektion auf Seite 37 (100 % auto + 50% 0%, Desktop in 800–1920 px
 * kollisionsfrei geprüft). Die white-Sektion ist auf der Seite eindeutig;
 * Scope analog zur Materialien-Präzedenz über body.kv-page-ehrenamt +
 * has-white-background-color. Mobile ≤782px siehe Media-Query unten
 * (200 % auto + 0% 0% hält den dunklen ink-Ring des weiß-Felds aus beiden
 * Listen; bei 100 % läge er hinter den Listentexten). */
body.kv-page-ehrenamt .kv-panel-section.has-white-background-color {
	background-image: url("assets/images/gradkreise/gradkreise-field-white.svg");
	background-position: 50% 0%;
	background-repeat: no-repeat;
	background-size: 100% auto;
}

/* ueber-uns-Seite (Seite 32), Abschnitt "KLIMA° vor acht in Action" (28.08.):
 * Volllfächen-Deko auf der weißen Fläche mit dem weiß-Feld
 * gradkreise-field-white.svg — dieselbe Kalibrierung wie die white-Sektionen
 * auf den Seiten 37 und 40 (100 % auto + 50% 0%). Scope über die semantische
 * Sektionsklasse .kv-ueber-action; die Klasse ist nur auf dieser Seite im
 * Einsatz (Präzedenz: .kv-ueber-action .kv-panel--card im Action-Block oben).
 * Die paper-Karten der drei Panels liegen blickdicht über der Deko; Ringe
 * bleiben in den Fugen und den Zonen über/unter dem Kartenraster sichtbar. */
.kv-ueber-action {
	background-image: url("assets/images/gradkreise/gradkreise-field-white.svg");
	background-position: 50% 0%;
	background-repeat: no-repeat;
	background-size: 100% auto;
}

/* ueber-uns-Seite (Seite 32), Newsletter-Pointer "Bleib auf dem Laufenden."
 * (14.09.): dezente Gradkreis-Deko auf der weißen Fläche mit dem weiß-Feld
 * in Querformat-Ausrichtung (gradkreise-field-white-rot90cw.svg, 4:1) — die
 * Sektion ist flach (zentrierter Stack nach dem "Werde aktiv!"-Muster), das
 * Hochformat-Feld würde nur einen schmalen Mittelstreifen zeigen. Kalibrierung
 * (14.09., Ringgeometrie exakt aus dem Feld geparst — Bogen-Mittelpunkte und
 * Bezier-Scheitel —, Sweep size×position gegen die gemessenen Blockzonen):
 * 350% auto + 4% 106% — Ring-Cluster links (3 Ringe, max r≈70px, unten an der
 * Kante geschnitten, gewollt), 48px Abstand zu allen vollen Text-Blockzonen
 * (H2/Intro/Note, Button schmal). A/B-Diff (background-image off) als
 * Verifikation. */
.kv-ueber-newsletter {
	background-image: url("assets/images/gradkreise/gradkreise-field-white-rot90cw.svg");
	background-position: 4% 106%;
	background-repeat: no-repeat;
	background-size: 350% auto;
}

/* Mobil (≤782px): die Sektion ist schmal und die Textblöcke spannen die
 * volle Breite auf — es gibt keinen kollisionsfreien Ring-Platz mit
 * sichtbarem Ertrag (Sweep: nur 2–3 Mini-Ringe ≤14px möglich). Deko bewusst
 * nur ab 783px; die Fläche bleibt mobil schlicht weiß. */
@media (max-width: 782px) {
	.kv-ueber-newsletter {
		background-image: none;
	}
}

/* Mobile (≤782px): die Sektionen sind hier hoch und schmal — das
 * HOCHFORMAT-Feld (gradkreise-field-paper-full.svg, 1:2) passt zum
 * Sektionsformat und zeigt bei cover die volle Komposition; das Querformat
 * würde nur einen schmalen Streifen zeigen. Erkenntnis behält zusätzlich
 * die Mobile-Ausrichtung 50% 100% (unterer Feldrand an Sektionsunterkante,
 * 28.08.-Präzedenz). */
@media (max-width: 782px) {
	body.page-id-33 section.kv-panel-section.kv-erkenntnis {
		background-image: url("assets/images/gradkreise/gradkreise-field-paper-full.svg");
		background-position: 50% 100%;
	}

	body.page-id-38 .kv-panel-section.has-paper-background-color,
	.kv-spenden-online {
		background-image: url("assets/images/gradkreise/gradkreise-field-paper-full.svg");
		background-position: 0% 50%;
	}
}


/* Gradkreise ab 1920px: 90° gedrehte Feldvarianten (Auftraggeber-Vorschlag
 * 31.08.: "When the window becomes 1920px wide (or wider), the Gradkreise
 * become very big. How about turning the images by 90 degrees then?").
 * Die Feld-SVGs sind Hochformate (paper 1:2, ink/archive/white 1:4); bei
 * background-size 100% auto auf breiten Sektionen heißt das: Ring-Durchmesser
 * skalieren MIT der Fensterbreite (1920 px -> Ringe bis ~250 px, 2560 px ->
 * bis ~330 px) und die Komposition füllt nie die Sektionshöhe. Die rot90-
 * Varianten sind dieselben Kompositionen, um 90° gedreht (Generator
 * .weave/tmp/gradkreise/rotate-90.mjs, beide Richtungen cw/ccw als Dateien;
 * die Ringe sind rotationsinvariant, nur ihre VERTEILUNG liegt jetzt quer
 * wie die Sektion). Damit bleibt der Ring-Durchmesser an die SektionsHÖHE
 * gekoppelt (auto 100% / moderates Oversize) statt an die Breite.
 * KALIBRIERT 31.08. (Scan .weave/tmp/gradkreise/select-rot90e-31-08.mjs:
 * alle Kandidaten × Breiten 1920/2100/2560 px gegen offene Textboxen;
 * Screenshots rot90e/). Regeln wie seit 28.08.: auf hellem Grund müssen
 * dunkle Ring-Töne (ink #052B8E 1.0:1, blue #317FE3 3.03:1) in offenen
 * Textboxen 0 Deko-Pixel haben; auf ink-Grund gilt das für die komplette
 * Deko (paper-Text auf hellem Ring < 3:1). Blickdichte Karten/Pills maskieren
 * wie bisher. Unter 1920px bleibt die bestehende Kalibrierung unverändert.
 * Richtung je Sektion nach Dichte-Bild (vis) + Sichtprüfung, Rotation cw/ccw
 * nur Dateien-Variante, kein Rendering-Unterschied. */
@media (min-width: 1920px) {
	/* Archiv-Sektionen ab 1920px: gedrehtes Archiv-Feld (8192×2048, 4:1 nach
	 * dem 2:1-Zwischenstand wieder auf halbe Breite zurückgesetzt 31.08.),
	 * background-size: cover — Sektion wird in Höhe und Breite immer
	 * vollständig bedeckt, Überlauf beschnitten, Ringe bleiben rund.
	 * background-position 50% 50% zentriert den Ausschnitt. Kontrastmessung
	 * (check-archive-contrast-31-08.mjs, 1920–2560): alle offenen Textboxen
	 * über 4.5:1 bzw. 3:1 ab 24 px; opake Karten maskieren die Deko. */
	.kv-archive {
		background-image: url("assets/images/gradkreise/gradkreise-field-ink-archive-rot90cw.svg");
		background-position: 50% 50%;
		background-size: cover;
	}

	/* Seite 33 "Die wichtigste Erkenntnis" (paper): gedrehtes paper-Feld,
	 * full-bleed (cover, 50% 50%). */
	body.page-id-33 section.kv-panel-section.kv-erkenntnis {
		background-image: url("assets/images/gradkreise/gradkreise-field-paper-full-rot90cw.svg");
		background-position: 50% 50%;
		background-size: cover;
	}

	/* Seite 37 "Klimaquartett" (white): gedrehtes weiß-Feld, 150% auto +
	 * 0% 0% (darkHit=0 in allen Breiten). */
	body.page-id-37 .kv-panel-section.has-white-background-color {
		background-image: url("assets/images/gradkreise/gradkreise-field-white-rot90cw.svg");
		background-position: 0% 0%;
		background-size: 150% auto;
	}

	/* Seite 38 "Vergangene Veranstaltungen" (paper): gedrehtes paper-Feld,
	 * full-bleed (cover, 50% 50%); Karten maskieren die Deko. */
	body.page-id-38 .kv-panel-section.has-paper-background-color {
		background-image: url("assets/images/gradkreise/gradkreise-field-paper-full-rot90ccw.svg");
		background-position: 50% 50%;
		background-size: cover;
	}

	/* Seite 40 "Was du mitbringen solltest"/"Was dir die Mitarbeit gibt"
	 * (white): gedrehtes weiß-Feld, 175% auto + 50% 100% (darkHit=0). */
	body.kv-page-ehrenamt .kv-panel-section.has-white-background-color {
		background-image: url("assets/images/gradkreise/gradkreise-field-white-rot90cw.svg");
		background-position: 50% 100%;
		background-size: 175% auto;
	}

	/* Spenden-Seite "Jetzt online spenden": gedrehtes paper-Feld (rot90cw),
	 * full-bleed (cover); das blickdichte iframe maskiert die Mitte. */
	.kv-spenden-online {
		background-image: url("assets/images/gradkreise/gradkreise-field-paper-full-rot90cw.svg");
		background-position: 0% 50%;
		background-size: cover;
	}

	/* Partner-Sektion (ueber-uns/partner-netzwerk): Hochformat-Feld,
	 * full-bleed (cover) — deckt bei der hohen Sektion die volle Breite,
	 * Mobile-Regel (≤782px) deckt denselben Fall ab: kein Override nötig. */
}

/* Startseite "Aktuelles von KLIMA° vor acht": ink-Feld. Die Gradkreis-Deko
 * (background-image gradkreise-field-ink.svg) wurde auf Wunsch des
 * Auftraggebers entfernt (17.08.): die Sektion zeigt nur noch die ink-Fläche
 * (has-ink-background-color aus dem Pattern), nicht mehr die Feld-Ringe.
 * padding-bottom bleibt 60px: die direkt folgende Abschluss-Sektion
 * (.kv-aktuelles-abschluss) übernimmt die untere Großzügigkeit — beide
 * gehören inhaltlich zusammen (gleiches ink, "Aktuelles" setzt sich fort).
 * Bewusst in allen Viewports fix (auch Mobile, kein eigener Mobile-Wert):
 * der knappe Abstand vor dem Abschluss-Banner wirkt überall gleich. */
.kv-aktuelles {
	padding-bottom: 60px;
}

/* Abschluss der "Aktuelles"-Sektion (.kv-aktuelles-abschluss, Block
 * "Aktuelles - Abschluss"): gehört optisch zur voranstehenden
 * kv-aktuelles-Sektion (gleiches ink). Sie erhält KEINE eigene
 * Gradkreis-Deko — background-image ist nie vererbbar, die Klasse hat also
 * automatisch keinen Kreis-Hintergrund. Korrektur 18.08. (user spec, Satz
 * + Button gehören ans Ende der Karten-Sektion): die zwei inner-Paddings
 * des generischen kv-section-Paddings werden neutralisiert, so dass nur
 * die fixen 60px von .kv-aktuelles (padding-bottom, siehe oben) den
 * Abstand zwischen Panels und Banner-Satz bilden:
 *  - .kv-aktuelles .kv-section__inner endet ohne Bottom-Padding (der Grid
 *    sitzt direkt am Sektionsende, 60px Sektion-Padding folgen),
 *  - .kv-aktuelles-abschluss .kv-section__inner startet ohne Top-Padding
 *    (der Satz beginnt direkt am Sektionsanfang).
 * Vorher griff `padding-top: 0` an der Sektion selbst nicht, weil das
 * Standard-Padding am inner liegt — der Banner saß dadurch ~265px (statt
 * 60px) unter den Panels, verstärkt durch die alte Separator-Linie. */
.kv-aktuelles .kv-section__inner {
	padding-block-end: 0;
}

.kv-aktuelles-abschluss .kv-section__inner {
	padding-block-start: 0;
}

/* Startseite "Unsere Wirkung" (Slider-Sektion): BEWUSST ohne Gradkreis-
 * Deko — .kv-wirkung wird hier absichtlich NICHT dekoriert (Entscheid des
 * Auftraggebers 13.08. E: "Keine Gradkreise in der section kv-wirkung!",
 * siehe Einsatzorte oben). Soll die Deko (ink-Feld) später wieder
 * aktiviert werden, einfach die Regel mit background-image/position/-size
 * hier einfügen. */

/* Mobile (≤782px): Deko reduziert und in die freien Zonen der gestapelten
 * Karten/Slides gelegt (Randstreifen x < 41, Lücken zwischen den Karten,
 * unterhalb des Sliders). KALIBRIERT 13.08. für 390px; die %-Werte skalieren
 * mit der Breite mit. Vorher zeigte .kv-aktuelles bei "auto 62%" gar keine
 * Deko (0 Deko-Pixel) und .kv-angebote nur ~144 Pixel. (.kv-wirkung fehlt
 * hier bewusst — deko-frei seit Korrektur E, siehe Einsatzorte oben.) */

/* =========================================================================
 * Ressourcen-Seite (Template `ressourcen`, Body-Klassen kv-header-inverted
 * + kv-header-tuerkis aus functions.php): Der Header erbt den kompletten
 * `.kv-header-inverted`-Block (Nav, Logo, Language-Switcher, Suche,
 * Ghost-Spenden-Button, :focus-visible-Outlines, Dropdown-Submenü – alles
 * auf ink umgestellt). Diese flankierende Flächen-Variante überlagert NUR
 * die Hintergrundfläche auf leaf #2ADCBA (Figma-Türkis), statt des Weissen,
 * das `.kv-header-inverted .kv-site-header.has-ink-background-color`
 * setzt. Bewusst KEIN Redundanz-Override des Invert-Blocks (DRY).
 * ====================================================================== */
body.kv-header-tuerkis .kv-site-header.has-ink-background-color {
	background-color: var(--wp--preset--color--leaf) !important;
}

/* Hover/Fokus der Text-Links (Nav + Language-Switcher) auf der leaf-Fläche:
 * Konsistent zum neuen Background-Change-Modell aller drei Header-Varianten
 * wechselt der Background auf tuerkis-75 #7AE6CB (helleres Grün als die
 * leaf-Fläche #2ADCBA); der ink-Text #052B8E bleibt unverändert (≈ 8:1 AAA)
 * und der frühere Textfarbwechsel ist entfernt. Die Unterstreichung kommt aus
 * der bestehenden generischen Top-Level-Unterstreichungs-Regel und ist der
 * nicht-farbabhängige Hover-Indikator auf allen drei Varianten. Buttons sind
 * NICHT betroffen (Figma-System: Hover-Fill dunkelblau-75 #3F62AD, Text
 * warmweiss-25 = 5,80:1 AA). */
body.kv-header-tuerkis .kv-site-header .wp-block-navigation__container >
	.wp-block-navigation-item > .wp-block-navigation-item__content:hover,
body.kv-header-tuerkis .kv-site-header .wp-block-navigation__container >
	.wp-block-navigation-item > .wp-block-navigation-item__content:focus-visible,
body.kv-header-tuerkis .kv-header-lang__link:hover,
body.kv-header-tuerkis .kv-header-lang__link:focus-visible {
	background: var(--wp--preset--color--tuerkis-75);
	color: var(--wp--preset--color--ink);
}

/* Mega-Panel-Einträge auf der leaf-Fläche: Bewusst KEINE eigene
 * tuerkis-Hover-Regel mehr. Die Mega-Panel-Einträge öffnen aus den
 * Mega-Menü-Regeln (Kopf-Sektion oben) direkt als ink auf signal #FFC04E
 * mit Unterstreichung und ink-Outline bei Fokus – unabhängig von der
 * Header-Flächen-Variante. Sie sehen auf der Ressourcen-Seite damit exakt
 * so aus wie auf allen anderen Seiten. Die frühere Regel hatte hier den
 * tuerkis-75-Highlight erzwungen (weil signal auf tuerkis-75 nur ~1,1:1
 * wäre); der Background-Wechsel der Top-Level-Nav-Regeln ist über den
 * Kind-Selektor (`__container > item > __content`) bewusst nur auf die
 * oberste Ebene gescoped, sodass er die Mega-Panel-Einträge nicht berührt.
 * Diese tuerkis-Submenü-Regel ist damit komplett redundant und ihre
 * Deklarationen (color: ink, outline-color: ink) werden bereits von der
 * Mega-Sektion geliefert. Das doppelte `.kv-site-header.kv-site-header` als
 * Spezifitäts-Hebel entfällt damit ebenfalls. */

/* ======================================================================
 * Kv8-paper Header (Aktiv-werden-Sektion, body class kv-header-paper,
 * ergänzend zum Invert-Block aus functions.php): Der Header der
 * Aktiv-werden-Hub-Seite und ihrer Unterseiten erbt den kompletten
 * `.kv-header-inverted`-Block (Nav, Logo, Language-Switcher, Suche,
 * Ghost-Spenden-Button, :focus-visible-Outlines, Dropdown-Submenü – alles
 * auf ink umgestellt). Diese flankierende Flächen-Variante überlagert NUR
 * die Hintergrundfläche auf paper #FCF8EC statt des Weissen, das
 * `.kv-header-inverted .kv-site-header.has-ink-background-color` setzt.
 * Damit läuft die helle Kopf-Fläche nahtlos in den paper-Seitenhintergrund
 * über (paper ist die globale Body-Basis). Hover/Fokus der Text-Links
 * erbt der Invert-Block (dunkelblau-75 #3F62AD auf paper = 5,55:1 AA);
 * das Dropdown-Submenü bleibt ink. Bewusst KEIN Redundanz-Override des
 * Invert-Blocks (DRY) – nur die Fläche plus die Trennlinie, deren
 * paper-25-Version des Basis-Headers auf paper unsichtbar wäre.
 * ====================================================================== */
body.kv-header-paper .kv-site-header.has-ink-background-color {
	background-color: var(--wp--preset--color--paper) !important;
}

body.kv-header-paper .kv-site-header::after {
	background: rgba(5, 43, 142, 0.16);
}

/* Ressourcen-Panels (scoped auf .kv-ressourcen = Section im Seiteninhalt):
 * - Weisse Kartenflächen: überschreibt das generische paper-25 der
 *   .kv-panel--card-Regel nur im Ressourcen-Kontext (ink auf white ≈ 12:1).
 * - Zentrierte, begrenzte Grafik: die Panel-Illustrationen (assets/images/icons/*,
 *   je 960×560-Canvas, Motive randlastig komponiert) werden auf max. 460px breit
 *   begrenzt und horizontal zentriert; Titel/Text/Button bleiben linksbündig
 *   (kein .kv-panel--center).
 * - Merch-Hinweis: volles ink (keine Opazitäts-Absenkung – opacity: .85
 *   würde die kleine 0.875rem-Schrift unter AA drücken; ink auf white ≈ 12:1).
 * - Karten-Abgrenzung: 1px-Rahmen in tuerkis-75, weil White vs. leaf nur
 *   ≈1,74:1 ist – keine Text-Kontrast-Pflicht, erhöht die visuelle
 *   Erkennbarkeit der Karten auf der leaf-Fläche. */
.kv-ressourcen .kv-panel--card {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--tuerkis-75);
}

.kv-ressourcen .kv-panel__media {
	width: 100%;
	max-width: 376px;
	margin-inline: auto;
}

/* Die SVGs tragen seit 15.09. ein einheitliches 720×419-Canvas (Ratio 1.718,
 * Motiv zentriert via <g transform>, 91 % Füllhöhe): img folgt der Figure-
 * Breite, die Hoehe der Canvas-Ratio — alle Slots einer Zeile sind dadurch
 * exakt gleich hoch und die H3/Copy/Button-Reihen sitzt bündig. */
.kv-ressourcen .kv-panel__media img {
	width: 100%;
	height: auto;
}

.kv-ressourcen .kv-merch-hinweis {
	color: var(--wp--preset--color--ink);
}

/* ======================================================================
 * Quellen-Panels "Fakten und Argumente" (Seite 34, scoped auf .kv-fakten;
 * Layout wie /aktuelles/ laut User-Vorgabe 15.09.: 3 Karten pro Zeile,
 * Logo oben zentriert als Link, Titel, Meta-Zeile, Zusammenfassung,
 * "Link zur Website" als Secondary-Button unten.
 * - Flaechen: Intro-Sektion leaf (nahtlos unter dem leaf-Header des
 *   ressourcen-Templates, sichtbarer H2-Titel im Intro), die vier
 *   Gruppen-Sektionen paper, der Abschluss-CTA signal — der CTA kommt
 *   nicht aus dem Seiteninhalt, sondern aus dem CTA-Set "Fakten und
 *   Argumente" (Term 280, kv8_spenden_cta, Variante gelb, mailto-Button)
 *   via klima-vor-acht/spendenaufruf am Template-Ende.
 * - Kartenflaeche wie /aktuelles/ (.kv-article-card): white, 16px-Radius,
 *   ohne Border (White vs. paper ≈ 1,74:1).
 * - Logo oben zentriert als Link (kv-source__media, Bild marged und
 *   auf max-height 90px begrenzt — object-fit:contain via width/height
 *   auto bewahrt die Marke, kein Verzerren; Hochformate bleiben klein).
 * - Meta-Zeile (Herausgeber und Jahr) in dunkelblau-75 auf der weissen
 *   Karte ≈ 5,9:1 AA (auf paper 5,55:1); 0.9375rem.
 * - Button-Zeile unten links (wie .kv-article-card > .wp-block-buttons):
 *   margin-block-start:auto drueckt sie an den Kartenboden, damit alle
 *   Karten einer Grid-Zeile bündig schliessen; 3 Spalten via Panel-Group-
 *   Layout (columnCount 3 im Content), mobile 1 Spalte generisch.
 * ====================================================================== */
.kv-fakten .kv-panel--card {
	background: var(--wp--preset--color--white);
	border-radius: 16px;
	border: none;
}

.kv-fakten .kv-panel-group {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Logo oben als Link, vollbreit (User-Vorgabe 15.09.): die Figure läuft
 * auf die volle Karten-Innenbreite, das Bild skaliert proportional über
 * width:100% (kein Verzerren, kein Beschneiden). Der Link-Anker MUSS
 * display:block sein: als inline-block shrink-to-fit kann width:100%
 * nicht aufgelöst werden — Bilder mit kleinerer Naturbreite (UBA 114px,
 * CORRECTIV 176px, Climate Feedback 202px …) blieben sonst auf
 * Naturgröße, statt die volle Breite zu füllen. Als Block-Anker ist die
 * Breite definit und jedes Logo füllt sie (SVGs skalieren dabei
 * verlustfrei; die drei kleinen SVG-Logos werden hochskaliert). */
.kv-fakten .kv-source__media {
	margin-block: 0;
}

.kv-fakten .kv-source__media a {
	display: block;
	line-height: 0;
}

.kv-fakten .kv-source__media img {
	display: block;
	width: 100%;
	height: auto;
}

/* CCNow-Rund-Badge (Footer-Logo, 1:1): das 1line-Logo (10,7:1) ware als
 * Vollbreite nur 27px hoch — die Karte faehrt stattdessen das runde
 * Gradient-Badge auf der 7rem-Kante, die CCNow selbst im Footer nutzt;
 * zentriert im Medienbereich (Block-Anker, margin-inline auto). */
.kv-fakten .kv-source__media--badge img {
	width: 7rem;
	height: auto;
	margin-inline: auto;
}

/* Titel-Link wie /aktuelles/ (.kv-blog-posts-card .wp-block-post-title
 * a): Default ohne Underline in ink, Hover/Fokus blau + Underline. */
.kv-fakten .kv-source h3 a {
	color: var(--wp--preset--color--ink);
	text-decoration: none;
}

.kv-fakten .kv-source h3 a:hover,
.kv-fakten .kv-source h3 a:focus-visible {
	color: var(--wp--preset--color--blue);
	text-decoration: underline;
}

.kv-fakten .kv-source__meta {
	font-size: 0.9375rem;
	color: var(--wp--preset--color--dunkelblau-75);
	margin-block-start: 0.25rem;
}

/* Titelgroesse wie /aktuelles/ (User-Vorgabe 15.09.): kein Preset — die
 * UA-h3-Defaultgroesse (1.17em) auf der 18px-Basis liefert exakt die
 * 21.06px der Aktuelles-Kartentitel; die 1.15-Zeilenhoehe ist der
 * Spiegel zu .kv-article-card .kv-article-card__title. overflow-wrap
 * bricht unteilbare Titel-Token (z. B. "CORRECTIV.Faktencheck"), die
 * als Grid-Items mit min-width:auto sonst die 1-Spalten-Mindestbreite
 * anheben wuerden; hyphens trennt lange deutsche Woerter sauber. */
.kv-fakten .kv-source h3 {
	line-height: 1.15;
	overflow-wrap: anywhere;
	hyphens: auto;
}

/* Button-Zeile unten links (Anatomie .kv-article-card >
 * .wp-block-buttons): margin-block-start:auto drueckt sie an den
 * Kartenboden, damit alle Karten einer Grid-Zeile bündig schliessen. */
.kv-fakten .kv-source__actions {
	margin-block-start: auto;
	padding-block-start: 1.25rem;
}

@media (max-width: 1024px) {
	.kv-fakten .kv-panel-group {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 781px) {
	.kv-fakten .kv-panel-group {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Folgen-Kacheln (scoped auf .kv-folgen = Section im Seiteninhalt):
 * - Kartenflaeche warmweiss-25 ohne Rahmen (Figma-Vorgabe 11.09.: keine
 *   Abgrenzungslinie); der warme Ton traegt allein die Abgrenzung zum
 *   leaf-Hintergrund. Text bleibt ink ≈ 12:1.
 * - Media 16:9 vollbreit (YouTube-maxresdefault-Thumbnails, object-fit).
 * - Teaser-Embed: zentriert, max. 720px. */
.kv-folgen .kv-panel--card {
	background: var(--wp--preset--color--warmweiss-25);
}

.kv-folgen .kv-panel__media {
	width: 100%;
	aspect-ratio: 16 / 9;
	margin-inline: auto;
}

.kv-folgen .kv-panel__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.kv-folgen .wp-block-embed {
	max-width: 720px;
	margin-inline: auto;
}

/* Folgen-Sektion – Button-Zeilen & Sektionsabstände (Kundenwunsch 16.08.):
 * - Desktop: erster Button links, zweiter rechtsbündig. Die Verteilung kommt
 *   seit dem Nachzug (16.08.) generisch aus .kv-panel-section .kv-panel
 *   .wp-block-buttons (justify-content: space-between); die frühere scoped
 *   Desktop-Regel .kv-folgen .kv-panel .wp-block-buttons ist entfernt
 *   (redundant, der Container ist Block-Flex und damit voll breit,
 *   width: 100% unnötig).
 * - Mobil ≤782px: die mobile Regel in der @media-Query unten bleibt und
 *   zentriert. Sie hat dieselbe Spezifität (0,3,0) wie die generische Regel,
 *   steht aber später im File, daher gewinnt sie; die gemessene Einzelbreite
 *   von ~196px in der 242px-Kachel lässt keine gemeinsame Zeile zu,
 *   flex-wrap stapelt die Buttons, justify-content: center zentriert.
 * - Sektionsabstände (Kundenwunsch 16.08.): vor einer Sektions-Überschrift
 *   (H2) groß, clamp(3rem, 8vw, 5rem) ≈80px ab 1440px, gleicher Rhythmus
 *   wie das .kv-section-Padding auf /unsere-wirkung/; direkt dahinter klein
 *   als Anbindung an die Panels (Folgeregel: H2 + direkt folgendes Grid bzw.
 *   Embed, clamp(1.5rem, 3vw, 2.5rem)). So hat „Folgen 1–6“ deutlich
 *   mehr Luft darüber als darunter (~3:1). Intro-Paragraphen
 *   P1–P3 bleiben kompakt (1rem). Der Geschwister-Selektor schlägt den
 *   Core-Flow-Gap (is-layout-flow, 1.25rem, :where-Spezifität 0), Vorbild:
 *   body.page-id-108 .kv-newsletter-hint + h2. */
.kv-folgen > .wp-block-heading:not(:first-child),
.kv-folgen > .wp-block-embed:not(:first-child),
.kv-folgen > .kv-panel-group:not(:first-child) {
	margin-block-start: clamp(3rem, 8vw, 5rem); /* Sektions-Rhythmus wie .kv-section (≈80px ab 1440px) */
}

/* Überschrift gehört zu ihren Panels: kleiner Abstand zwischen H2 und
 * direkt folgendem Content (Kundenwunsch 16.08.). */
.kv-folgen > .wp-block-heading + .kv-panel-group,
.kv-folgen > .wp-block-heading + .wp-block-embed {
	margin-block-start: clamp(1.5rem, 3vw, 2.5rem);
}

.kv-folgen > p + p {
	margin-block-start: 1rem;
}

@media (max-width: 782px) {
	.kv-folgen .kv-panel .wp-block-buttons {
		justify-content: center;
	}
}

/* Buch-Seite (Scopes: .kv-buch = leaf-Einstiegssektion,
 * .kv-buch-cta = die beiden vollflaechigen Kombi-Bestell-CTAs inkl. des
 * inc/buch-suche.php-Renders):
 * - Suche: Label, Input und Button in einer Zeile mit Wrap; der Input nutzt
 *   die Formular-Optik des Themes (white, 1px --kv-border) und behält den
 *   visible :focus-visible-Ring (signal 3px, Fokus-Philosophie wie
 *   .kv-newsletter-page-form/.kv-contact-form). Seine flex-Basis lässt das
 *   Feld wachsen und auf schmalen Viewports sauber umbrechen (kein
 *   eigener ≤782px-Override nötig).
 * - Ergebnisliste: Reset + kompaktes Grid; die Einträge stapeln Name,
 *   Adresse und Entfernung als eigene Zeilen.
 * - OSM-Attribution bewusst klein und dezent; ink bei 0.8-Opacity bleibt
 *   auf leaf 4.72:1 und auf paper 6.54:1 (AA). */
/* Vollflächige Bestell-CTAs (05.09., Kombi-Auftrag: Lokalsuche +
 * Online-Buttons in EINER Sektion, zweimal auf der Seite — nach der
 * Einstiegs-Sektion und am Seitenende). Die Flächengeometrie (100vw-Shell
 * + Innensäule) liefert .kv-section/.kv-section__inner wie in jeder
 * anderen Sektion; das kompaktere Vertikal-Padding folgt dem
 * Abschluss-CTA-Präzedenz .kv-post-cta. Signal-Hintergrund/ink-Text trägt
 * das Markup (has-signal-background-color/has-ink-color). */
.kv-buch-cta .kv-section__inner {
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	padding-block: clamp(2.5rem, 8vw, 5rem);
}

@media (min-width: 1440px) {
	.kv-buch-cta .kv-section__inner {
		padding-block: 80px;
	}
}

/* Online-Block der Kombi-CTA: durchtrennt die beiden Kaufwege (ink-16 wie
 * die Theme-Trennlinien); der Lokal-Weg steht bewusst zuerst. */
.kv-buch-cta__online {
	border-top: 1px solid var(--kv-border);
	margin-block-start: clamp(2rem, 4vw, 3rem);
	padding-block-start: clamp(2rem, 4vw, 3rem);
}

/* Vier Online-Buttons als gleichmaessiges Raster in der vollen
 * Innensäule (Vorbild: das vorige gelbe Bestell-Band): 4er-Reihe, ab
 * Tablet-Breite 2x2, im schmalsten Bereich einspaltig; Spalten-min
 * max-content verhindert Namen-Umbruch (Hugendubel). */
.kv-buch-cta__online .wp-block-buttons {
	display: grid;
	grid-template-columns: repeat(4, minmax(max-content, 1fr));
	gap: 0.75rem;
}

.kv-buch-cta__online .wp-block-button {
	max-width: none;
}

.kv-buch-cta__online .wp-block-button__link {
	display: block;
}

@media (max-width: 782px) {
	.kv-buch-cta__online .wp-block-buttons {
		grid-template-columns: repeat(2, minmax(max-content, 1fr));
	}
}

@media (max-width: 479px) {
	.kv-buch-cta__online .wp-block-buttons {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Suche (05.09. Inline-Auftrag): Der sichtbare Hinweissatz
 * span.kv-buch-suche__hint (im Render des Blocks, endet auf „:“) steht
 * neben der Gruppe div.kv-buch-suche__controls (Feld + Button); Text und
 * Gruppe stehen vertikal zueinander mittig (align-items: center,
 * Auftrag 05.09.; zuvor flex-end). Die Gruppe ist EIN flex-Kind — sie
 * darf nie
 * auf getrennte Zeilen reiessen (Nachtrag-Auftrag: Button bleibt immer
 * rechts neben dem Feld); wenn kein Platz bleibt, wrappt sie als Ganzes
 * unter den Satz. Schmal (≤782px) erhaelt der Satz bewusst eine eigene
 * Zeile (flex-basis 100%). */
.kv-buch-suche__form {
	align-items: center;
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
}

/* Waehrend des Wrap-Tests: die ganze Gruppe (min-width:0 erlaubt
 * mitschrumpfen bis Feld-min + Button); der Hinweissatz (flex-shrink
 * per Default) gibt zuerst nach und umbucht in mehrere Zeilen. */
/* Fusion wie das Newsletter-Formular des Footers (05.09., Auftrag):
 * .kv-newsletter-form kennt keinen gap — Feld + Button teilen sich eine
 * Kante (komplementaere Radien, naive border-Fusion). */
.kv-buch-suche__controls {
	align-items: stretch;
	display: flex;
	flex: 1 1 auto;
	min-width: 0;
}

@media (max-width: 782px) {
	.kv-buch-suche__hint {
		flex-basis: 100%;
	}
}

/* Deutschland-Scope-Hinweis (20.09., Inline-Auftrag): kleines flex-Kind
 * mit flex-basis:100% -> eigene Zeile unter dem Hinweissatz-/Feld-Paar.
 * Bewusst ohne Opacity-Trick (Signal-Hintergrund): volle ink-Farbe haelt
 * den Kontrast auf jeder der beiden CTA-Flaechen stabil (a11y). */
.kv-buch-suche__scope {
	flex-basis: 100%;
	font-size: 0.8125rem;
}

.kv-buch-cta .kv-buch-suche__scope {
	color: var(--wp--preset--color--ink);
}

/* 17.08. iOS-Zoomschutz: Das Feld hatte keinen font:-Shorthand und bekam
 * bisher nur den UA-Default (~13px); die Clamp (16–18px) hält es über dem
 * iOS-Zoom-Schwellwert. max-width 300px (20.09., Inline-Auftrag): der
 * englische Placeholder "Enter your postcode or town" war bei 240px
 * abgeschnitten. */
.kv-buch-suche__form input[type="text"] {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--kv-border);
	border-radius: 6px 0 0 6px;
	box-sizing: border-box;
	color: var(--wp--preset--color--ink);
	flex: 1 1 160px;
	font-size: clamp(1rem, 1.6vw, 1.125rem);
	max-width: 300px;
	min-width: 6rem;
	padding: 0.65rem 0.875rem;
}

/* Button wachst nie, schrumpft nicht, bricht nie intern um — er bleibt
 * als Ganzes rechts neben dem Feld (05.09. Nachtrag). Fusion mit dem
 * Feld wie .kv-newsletter-form button (05.09. Auftrag): rechte Radien,
 * linke Kante teilt sich mit der Feld-Border (margin-left: -1px, wie es
 * die Newsletter-Fusion nativ ohne gap erreicht); min-height 2.75rem wie
 * das Newsletter-Feld, stretch in der Gruppe -> gleiche Haehe. */
.kv-buch-suche__controls button[type="submit"] {
	border-radius: 0 6px 6px 0;
	flex: 0 0 auto;
	margin-left: -1px;
	min-height: 2.75rem;
}

.kv-buch-suche__form input[type="text"]:focus-visible {
	border-color: var(--wp--preset--color--ink);
	outline: 3px solid var(--wp--preset--color--signal);
	outline-offset: 2px;
	z-index: 1;
}

/* Submit auf Signal: der Theme-Default des wp-element-button
 * (elements.button: signal-Fill) waere signal-auf-signal unsichtbar —
 * hier Primary-Auftritt wie is-style-primary-ink (ink-Fill,
 * paper-25-Text 11.85:1, Hover #3F62AD). */
.kv-buch-cta .kv-buch-suche__form button[type="submit"] {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

.kv-buch-cta .kv-buch-suche__form button[type="submit"]:hover,
.kv-buch-cta .kv-buch-suche__form button[type="submit"]:focus-visible {
	background: #3F62AD;
	color: var(--wp--preset--color--paper-25);
}

/* Signal-Outline des globalen :focus-visible ist auf der Signal-Karte
 * unsichtbar — ink-Ring wie .kv-post-cta/.kv-buch-autoren (7.4:1). */
.kv-buch-cta :focus-visible {
	outline-color: var(--wp--preset--color--ink);
}

/* Ergebnisliste auf Signal: Store-Name (Website-Link),
 * OSM-Kartenlink und Attributions-Link in ink statt Browser-Blau
 * (Kontrast auf signal 11.85:1 AAA; Unterstreichung/Hover-Dicke
 * uebernimmt die globale a-Regel). Der Kartenlink ist eine eigene
 * Grid-Zeile im li (das li stapelt schon; justify-self:start haelt die
 * Klickflaeche am Text). */
.kv-buch-cta .kv-buch-suche__results a {
	color: var(--wp--preset--color--ink);
}

.kv-buch-suche__store-map {
	justify-self: start;
}

/* Ergebnisliste (05.09., Auftrag): zweispaltiges Raster — Spalten-grosser
 * Gap (1.5rem), li-Stapel bleiben kompakt; schmal (≤782px) einspaltig. */
.kv-buch-suche__results ul {
	column-gap: 1.5rem;
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	list-style: none;
	margin-top: 1rem;
	padding-left: 0;
	row-gap: 1.5rem;
}

@media (max-width: 782px) {
	.kv-buch-suche__results ul {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Eintrag (05.09. Nachtrag): Die Zeilen (Name/Adresse/Entfernung/Karten-
 * link) ruecken mit Zeilenhoehe 1.33 dichter zusammen; die Luft ZWISCHEN
 * den Eintraegen kommt ueber den row-gap des Ul (siehe oben), nicht ueber
 * hohe Zeilen. align-content: start (05.09., Auftrag): Kuerzere Ein-
 * traege (z. B. ohne Strasse -> 3 Zeilen) werden in ihrer Grid-Zeile
 * sonst ueber den Zeilenabstand gestreckt (align-content normal = stretch
 * auf auto-Zeilen); start haelt den Stapel oben, sodass alle Namen auf
 * einer horizontalen Kante beginnen. */
.kv-buch-suche__results li {
	align-content: start;
	display: grid;
	gap: 0.15rem;
	line-height: 1.33;
}

/* Store-Namen hervorheben (05.09., Auftrag): groesser + fett — sie sind
 * die Suchtreffer-Schluessel; Adresse/Entfernung/Kartenlink bleiben in
 * Body-Groesse darunter. */
.kv-buch-suche__store-name {
	font-size: clamp(1.0625rem, 1.7vw, 1.25rem);
	font-weight: 700;
}

.kv-buch-suche__attribution {
	font-size: 0.75rem;
	opacity: 0.8;
	margin-top: 0.5rem;
}

/* Lade-Feedback der Lokalsuche (Progressive-Enhancement via
 * assets/js/buch-lokalsuche.js): Das Status-Element startet mit `hidden`
 * unsichtbar und wird erst im submit-Handler eingeblendet (role="status"
 * = Live-Region, von Screenreadern beim Einblenden angesagt). Spinner ist
 * reines CSS; reduced-motion schaltet nur die Rotation aus, der
 * Status-Text bleibt sichtbar. Ohne JS greift [hidden] (UA + Fallback) und
 * der GET-Submit arbeitet unverändert. */
.kv-buch-suche__status {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	margin-top: 0.75rem;
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}

.kv-buch-suche__status[hidden] {
	display: none;
}

.kv-buch-suche__spinner {
	width: 1.1rem;
	height: 1.1rem;
	border: 3px solid var(--wp--preset--color--tuerkis-50, #95EEDD);
	border-top-color: var(--wp--preset--color--ink);
	border-radius: 50%;
	animation: kv-buch-suche-spin 0.8s linear infinite;
}

@keyframes kv-buch-suche-spin {
	to {
		transform: rotate(360deg);
	}
}

.kv-buch-suche__form button[type="submit"]:disabled {
	opacity: 0.6;
	cursor: wait;
}

@media (prefers-reduced-motion: reduce) {
	.kv-buch-suche__spinner {
		animation: none;
	}
}

@media (max-width: 782px) {
	/* <=782px entfaellt der freie Bereich links neben den Panels (Grid
	 * kollabiert auf 1 Spalte, die ink-Panels stapeln sich) — die Deko
	 * soll dann die volle Sektion abdecken: cover (beide Dimensionen,
	 * Ueberlauf beschnitten; Auftraggeber 31.08.). Die opaken
	 * kv-offer-card-Panels maskieren die Deko; die H2 "Unsere Angebote"
	 * (Gross-Text >= 24 px, 3:1) bleibt laut Kontrastmessung
	 * (check-angebote-cover-mobile-31-08.mjs, 320-782 px) ueber der
	 * Schwelle. Darueber (>782px) gilt weiterhin auto 100% (nur Hoehe). */
	.kv-angebote {
		background-position: 50% 50%;
		background-size: cover;
	}

/* Testimonial-Utility (Zukunft, keine aktive Anwendung — die Komponente
 * existiert noch nicht; dieses Muster zeigt die geplante Nutzung):
 *
 *   <div class="kv-testimonial" style="position: relative;">  ← Wrapper
 *     <svg class="kv-gradkreis-deco" aria-hidden="true">…</svg>  ← zwei
 *     <svg class="kv-gradkreis-deco" aria-hidden="true">…</svg>  ← Deko-SVGs
 *     …Foto, Zitat, Karte…
 *   </div>
 *
 * Die künftige Testimonial-Komponente setzt ihren Wrapper auf
 * position: relative; die zwei Deko-SVGs liegen dann absolut an der Foto-Kante.
 * z-index: -1 platziert sie über dem Karten-Hintergrund, aber unter der
 * Foto-Fläche — hier funktioniert der negative Index, weil die Kartenfläche
 * sichtbar ist (anders als bei den soliden Sektionsflächen oben, wo
 * z-index: -1 hinter der Sektionsfarbe verschwände). pointer-events: none
 * hält die Deko aus jeder Interaktion; die SVGs sind rein dekorativ und
 * tragen aria-hidden="true". Diese Klasse ist die EINZIGE hier, die
 * position/z-index nutzt — die Sektionen oben bleiben un-positioniert. */
.kv-gradkreis-deco {
	pointer-events: none;
	position: absolute;
	z-index: -1;
}
} /* Ende @media (max-width: 782px) – Brace-Fix 16.08.: fehlende schließende Klammer ergänzt (war ungeschlossen) */

/* Aktiv-werden-Panels (scoped auf .kv-activate): Illustration begrenzt + zentriert.
 * Die Sektion liegt auf leaf (grüne Fläche, siehe KV-Konvention Ressourcen);
 * die Karten sind deshalb weiss (nicht paper-25, das auf leaf kaum
 * kontrastiert) mit einem tuerkis-75-Rahmen zur Abgrenzung auf der
 * leaf-Fläche – identisch zur Ressourcen-Präzedenz. Slot 376px gleich
 * Ressourcen (seit 16.09.): einheitlicher 720×419-Canvas, Motiv 91 %
 * Füllhöhe — Slot-Höhe in jeder Zeile deckungsgleich. */
.kv-activate .kv-panel__media {
	width: 100%;
	max-width: 376px;
	margin-inline: auto;
}

.kv-activate .kv-panel__media img {
	width: 100%;
	height: auto;
}

.kv-activate .kv-panel--card {
	background: var(--wp--preset--color--white);
	border: 1px solid var(--wp--preset--color--tuerkis-75);
}

/* Aktiv-werden (page-id-31 + EN-Zwilling page-id-99198): kein Weißraum nach
 * der letzten Sektion, Abstand nach dem Intro-Absatz. Nur diese Seite (beide
 * Sprachen) betroffen. */
body.page-id-31 main .wp-block-group.alignwide,
body.page-id-99198 main .wp-block-group.alignwide {
	/* page.html setzt das Bottom-Padding der Content-Group inline
	 * (clamp(3rem, 8vw, 6rem)); !important schlägt Inline-Styles.
	 * Der Selektor ist auf main gescoped, weil auch Header
	 * (kv-header-top) und Footer (kv-footer-main/-bottom)
	 * alignwide-Gruppen sind – deren Klassen-Paddings bleiben unberührt. */
	padding-bottom: 0 !important;
}

body.page-id-31 .kv-section.kv-activate,
body.page-id-99198 .kv-section.kv-activate {
	/* Kleines optisches Air zur CTA-/Footer-Fläche, kein großer Leerraum
	 * (Entscheidung: Air beibehalten statt 0 – die Ressourcen-Präzedenz
	 * belässt der Sektion ihr Bottom-Padding und lässt den Rest-Whitespace
	 * aus page.html wirken; hier ersetzt dieser kompakte Wert ihn). */
	margin-bottom: 0;
}

/* Das kompakte Bottom-Air gehört auf die Innen-Spalte, nicht auf den
 * 100vw-Shell. */
.kv-activate .kv-section__inner {
	padding-bottom: clamp(2rem, 4vw, 3.5rem);
}

body.page-id-31 .wp-block-post-content > .kv-wirkung-intro,
body.page-id-99198 .wp-block-post-content > .kv-wirkung-intro {
	/* Abstand nach der Intro-Gruppe (Copy-Absatz + Bild) zur Panel-Sektion:
	 * zwischen theme.json medium (max 2.5rem) und large (max 7rem) –
	 * sichtbar, aber nicht dominant. Vorlage war der alte Direkt-Absatz
	 * („…Dafür brauchen wir dich.") mit identischem Clamp; seit der
	 * Absatz mit dem Bild in der .kv-wirkung-intro-Gruppe liegt, trägt
	 * die Gruppe den Abstand. Der Flow-Gap (1.25rem) greift hier nicht
	 * (Section-Top-Margin wird themenseitig auf 0 gesetzt), der Wert
	 * ist also die effektive Lücke. */
	margin-bottom: clamp(2rem, 5vw, 4rem);
}

/* Ueber-uns-Seite – FAQ-Sektion (ink) */

/* Der ink-Flaeche: heller Text erbt auf alle ungefärbten Kinder (Chevron,
   H2). Heading/textColor-Support gibt es am core/accordion-Wrapper nicht,
   daher Steuerung ueber die Section-Klasse. Die Antwort-Paragraphen tragen
   ihre Farbe bereits explizit (backgroundColor ink + textColor paper). */
.kv-faq {
	color: var(--wp--preset--color--paper);
}

/* Fragen fett (Absicherung; die h3 erben bereits elements.heading 700). */
.kv-faq .wp-block-accordion-heading__toggle-title {
	font-weight: 700;
}

/* Chevron down/up am Zeilenende: Core speichert ein "+"-Icon (Text) und
   dreht es bei .is-open um 45° (Plus->X). Gewünscht ist ein Chevron: das
   Icon wird ausgeblendet und am Toggle-Button ein Border-Chevron (::after)
   gezeichnet. state.isOpen setzt serverseitig die .is-open-Klasse am Item. */
.kv-faq .wp-block-accordion-heading__toggle-icon {
	display: none;
}

/* Rechte Einrückung für die gedrehte Box: Core setzt am Toggle-Button
   overflow:hidden (Gutenberg 23.7.2, accordion-heading/style.css). Die um
   45° gedrehte Border-Box überragt ihre Breite um die halbe Diagonale; läge
   sie bündig am Content-Ende, würde die rechte Spitze über die Padding-Kante
   ragen und durch overflow:hidden abgeschnitten (~4 px, in beiden
   Zuständen). margin-right: 0.3em zieht das Chevron so weit nach innen,
   dass die gedrehte Box vollständig sichtbar bleibt; em skaliert mit der
   Chevron-Größe mit (die 0.75rem-Lücke zur Frage bleibt unverändert). */
.kv-faq .wp-block-accordion-heading__toggle::after {
	content: "";
	width: 0.55em;
	height: 0.55em;
	flex-shrink: 0;
	margin-left: 0.75rem;
	margin-right: 0.3em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg) translateY(-0.1em);
}

.kv-faq .wp-block-accordion-item.is-open .wp-block-accordion-heading__toggle::after {
	transform: rotate(225deg) translateY(0.1em);
}

@media (prefers-reduced-motion: no-preference) {
	.kv-faq .wp-block-accordion-heading__toggle::after {
		transition: transform 0.2s ease-in-out;
	}
}

/* Spenden-Seite – helles Pendant zur dunklen kv-faq-FAQ (Ueber-uns).
 * Derselbe Aufriss: natives core/accordion, das "+"-Icon wird ausgeblendet
 * und am Toggle-Ende ein Border-Chevron gezeichnet (state.isOpen setzt
 * serverseitig .is-open am Item). Fuer die hellen .kv-panel-section-Sektionen
 * hier ist die Flaeche paper und der Text ink (erbt der Toggle ohnehin,
 * die explizite Farbe ist nur Absicherung gegen den has-* Vererbungsfall).
 * Die Titelgroesse folgt der Ueberschriftenebene des Blocks, nicht mehr der
 * Sektionsklasse (28.08., Auftraggeber: Hierarchie soll sichtbar sein; wo ein
 * Akkordeon kontextbedingt h2 ist, erhaelt es die Sektionsgroesse): h2 =
 * x-large wie die umliegenden Sektionsueberschriften, h3 eine Stufe darunter
 * (large). Scoped auf .kv-accordion-light: die dunkle .kv-faq (Ueber-uns)
 * behaelt ihr geprueftes Layout (Fragen in Fliesstextgroesse), ihre Regeln
 * weiter unten bleiben unberuehrt. */
.kv-accordion-light h2.wp-block-accordion-heading .wp-block-accordion-heading__toggle-title {
	font-size: var(--wp--preset--font-size--x-large);
}

.kv-accordion-light h3.wp-block-accordion-heading .wp-block-accordion-heading__toggle-title {
	font-size: var(--wp--preset--font-size--large);
}

.kv-accordion-light .wp-block-accordion-heading__toggle {
	color: var(--wp--preset--color--ink);
}

.kv-accordion-light .wp-block-accordion-heading__toggle-title {
	font-weight: 700;
}

.kv-accordion-light .wp-block-accordion-heading__toggle-icon {
	display: none;
}

/* Chevron down/up: analog kv-faq, Rand-Chevron am Zeilenende in currentColor
 * (ink). margin-right 0.3em zieht das bei 45° gedrehte Border-Box-Chevron
 * innerhalb des core-Toggle-overflow:hidden sichtbar nach innen. */
.kv-accordion-light .wp-block-accordion-heading__toggle::after {
	content: "";
	width: 0.55em;
	height: 0.55em;
	flex-shrink: 0;
	margin-left: 0.75rem;
	margin-right: 0.3em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg) translateY(-0.1em);
}

.kv-accordion-light .wp-block-accordion-item.is-open .wp-block-accordion-heading__toggle::after {
	transform: rotate(225deg) translateY(0.1em);
}

/* Ein-/Ausrollen der Antwort seidenweich wie beim Auro-Accordion (Alaska
 * Airlines): dieselbe grid-template-rows-Technik (0fr→1fr, ITEM als
 * 2-Zeilen-Raster Ueberschrift auto / Panel 0fr→1fr), mit dem geschmeidigen
 * Ease-Out-Bezier der Auro Motion Scale fuer lange, gleichmaessige
 * Beschleunigung und ein sanftes Ausrollen am Ende. Bewusst langsame Dauer,
 * damit man dem Oeffnen/Schliessen gut folgen kann. Nur ohne
 * prefers-reduced-motion angewendet. */
@media (prefers-reduced-motion: no-preference) {
	.kv-accordion-light .wp-block-accordion-item,
	.kv-faq .wp-block-accordion-item {
		transition: grid-template-rows 1s cubic-bezier(0.22, 1, 0.36, 1);
	}
}

/* Das Item ist ein 2-Zeilen-Raster: erste Zeile (auto) = Ueberschrift,
 * zweite Zeile (0fr → 1fr) = Antwort-Panel. Nur weil das Panel als
 * animierbare Grid-Zeile eingebunden ist (nicht display:none via [hidden]),
 * kann grid-template-rows die Hoehe wirklich aus- und einfahren. Das
 * [hidden]-Attribut der Gutenberg-Frontend-Logik wird fuer die Accordions
 * ueberschrieben (display: block statt none), sonst sprunghafter Wechsel.
 * align-content: start verhindert, dass die auto-Zeile (Ueberschrift)
 * waehrend der 0fr→1fr-Interpolation aufgeblaeht wird und die Antwort
 * nach unten verschoben erscheint. */
.kv-accordion-light .wp-block-accordion-item,
.kv-faq .wp-block-accordion-item {
	align-content: start;
	display: grid;
	grid-template-rows: auto 0fr;
}
.kv-accordion-light .wp-block-accordion-item.is-open,
.kv-faq .wp-block-accordion-item.is-open {
	grid-template-rows: auto 1fr;
}

/* Panel: fuellt die zweite Grid-Zeile mit der Antwort; min-height: 0
 * erlaubt das Kollabieren auf 0, overflow: hidden schneidet den Inhalt
 * waehrend der Animation ab (Auro/cubic-bezier-Muster).
 *
 * Der Abstand Frage→Antwort liegt NICHT am Panel, sondern als
 * margin-bottom an der Ueberschrift (erste, nie animierte Grid-Zeile).
 * Ein margin-top/Padding am Panel wuerde als Teil der (animierten)
 * 0fr-Zeile beim Oeffnen/Schliessen anders aufgeloest und die Antwort
 * wuerde um ~20px springen. An der Ueberschrift bleibt der Abstand in
 * jedem Zustand konstant. */
.kv-accordion-light .wp-block-accordion-panel,
.kv-faq .wp-block-accordion-panel {
	margin-top: 0;
	min-height: 0;
	overflow: hidden;
}
.kv-accordion-light .wp-block-accordion-heading,
.kv-faq .wp-block-accordion-heading {
	margin-bottom: 20px;
}

/* Beim Schliessen setzt die Gutenberg-Frontend-Logik das [hidden]-Attribut
 * (until-found) — dessen UA-Defaults (display:none + content-visibility:
 * hidden) wuerden die Grid-Zeile sofort kollabieren lassen und jede Ausfahr-
 * Animation unterbinden. Beide werden deshalb fuer die Accordions
 * ueberstimmt: Anzeige bleibt block und die Zeile bleibt layouted, die Hoche
 * steuert allein die (animierte) Grid-Zeile 0fr, der Inhalt ist ueber
 * overflow:hidden unsichtbar. */
.kv-accordion-light .wp-block-accordion-item .wp-block-accordion-panel[hidden],
.kv-faq .wp-block-accordion-item .wp-block-accordion-panel[hidden] {
	content-visibility: visible;
	display: block;
}

/* Gruppierung FAQ-Frage + Antwort (helle Accordion UND dunkle FAQ): eine
 * permanente, dezente untere Linie trennt jede FAQ-Gruppe ab, damit Frage
 * und Antwort als eine Einheit gelesen werden — die Linie ist im
 * geschlossenen wie im offenen Zustand sichtbar. Das zusaetzliche
 * Bottom-Padding im offenen Zustand haelt den Inhalt sichtbar von der
 * Linie ab. Kein Border-left mehr. */
.kv-accordion-light .wp-block-accordion-item,
.kv-faq .wp-block-accordion-item {
	border-bottom: 1px solid var(--wp--preset--color--ink-16, rgba(5, 43, 142, 0.16));
}

/* Helle Accordion: untere Linie aus dem --kv-border-Token. */
.kv-accordion-light .wp-block-accordion-item.is-open {
	padding-block-end: 1.5rem;
}

/* Dunkle FAQ: hellere Papier-Linie auf der ink-Sektion. */
.kv-faq .wp-block-accordion-item {
	border-bottom-color: rgba(252, 248, 236, 0.22);
}

.kv-faq .wp-block-accordion-item.is-open {
	padding-block-end: 1.5rem;
}

/* FAQ-Antworten: linksbündig zur Frage + Lesebreite in `em`.
 * Die Lesebreite begrenzen wir mit max-width in `em` auf den Antwort-<p>
 * SELBST: em loest bei Breitenangaben gegen die eigene font-size des
 * Elements auf, hier also gegen die tatsaechliche Antwort-Schrift
 * (18px auf /ueber-uns/, 24px auf /spenden/ via has-normal-font-size -
 * die unterschiedliche Schriftgroesse ist laut Auftraggeber o.k.).
 * 40em (= ~720px bei 18px, ~960px bei 24px) sind auf 80-100 Zeichen pro
 * Zeile kalibriert: Ausmessung der gerenderten Zeilenlaengen ergab
 * max. 97 Zeichen (/ueber-uns/) bzw. 94 (/spenden/), Median ~87-93.
 * (43.4em/781px landeten bei bis zu 104 Zeichen - zu breit.)
 * Auf schmaleren Viewports begrenzt die Spaltenbreite;
 * max-width wirkt dann nicht. Kein Media-Query, kein margin-right.
 * Gilt in beiden Accordion-Varianten.
 * Zusaetzlich neutralisieren wir das WP-Core-Padding der .has-background-
 * Klasse (die den Antwort-Absaetzen der dunklen FAQ mitgegeben wird, sobald
 * deren Hintergrund auf ink gesetzt ist; hier 22.5px 42.75px). Dadurch waren
 * die Antworten gegenueber der Frage um ~43px eingerueckt - gewuenscht ist
 * Flucht mit der Frage. Die hellen Antworten auf /spenden/ tragen kein
 * .has-background und sind bereits buendig. */
.kv-faq .wp-block-accordion-panel p,
.kv-accordion-light .wp-block-accordion-panel p {
	max-width: 40em;
}

.kv-faq .wp-block-accordion-panel .has-background {
	padding: 0;
}

/* Spenden-Seite – vertikales Padding der beiden Accordion-Sektionen halbiert
 * (31.08.): Die letzten beiden Sektionen von /spenden/ (Spendenbescheinigung,
 * Geld überweisen) bestehen nur je aus einem Akkordeon; der .kv-section__inner-
 * Standard (clamp(3rem, 8vw, 5rem) -> 80px ab 1440px) wirkt dort als doppelter
 * Leerraum um eine einzige Frage-Antwort-Gruppe. Nur das vertikale Padding
 * wird halbiert (Vorbild: .kv-ueber-hero-Kopfzeilen-Regel, 3rem->1.5rem,
 * 8vw->4vw, 5rem->3.75rem); horizontales Padding und die beiden oberen
 * Sektionen bleiben unveraendert. Scoped ueber :has(.kv-accordion-light) –
 * die Accordion-Klasse traegt auf der Seite nur diese zwei Sektionen, das
 * Intro und der Twingle-Block behalten den Standard. */
.kv-panel-section:has(.kv-accordion-light) .kv-section__inner {
	padding-top: clamp(1.5rem, 4vw, 3.75rem);
	padding-bottom: clamp(1.5rem, 4vw, 3.75rem);
}

/* Ueber-uns-Seite – Sektionsabstaende halbiert (Hero, Vision, Mission)
 * Design-Nachkorrektur (17.08.): die ersten drei Sektionen von Seite 32
 * tragen zu viel vertikalen Leerraum. Die .kv-section-Basis setzt
 * padding: clamp(3rem, 8vw, 5rem) (80/152px ab 1440px). Fuer die drei
 * Kopf-Sektionen wird nur das vertikale Padding halbiert (3rem->1.5rem,
 * 8vw->4vw, 7.5rem->3.75rem -> 57.6px bei 1440px statt 80px); das
 * horizontale Padding und die folgenden Sektionen (CTA, Action, FAQ)
 * bleiben unveraendert. Scoped auf die drei Klassen, kein Seiten-Markup. */
.kv-ueber-hero .kv-section__inner,
.kv-ueber-vision .kv-section__inner,
.kv-ueber-mission .kv-section__inner {
	padding-top: clamp(1.5rem, 4vw, 3.75rem);
	padding-bottom: clamp(1.5rem, 4vw, 3.75rem);
}

/* Ueber-uns Hero (Auftrag 04.09.): Header und Intro gemeinsam auf ink. Die
 * Kopf-Sektion traegt im Seiten-Markup has-white-background-color; die Core-
 * Utility dekretiert mit !important, die Override folgt dem Muster
 * .kv-site-header.has-ink-background-color (0,2,0 + !important schlaegt
 * 0,1,0 + !important). Die Textfarbe erbt wie die dunkle FAQ-Sektion
 * .kv-faq (paper #FCF8EC auf ink #052B8E = 11,85:1, WCAG AA/AAA). Scoped
 * ueber die white-Utility-Klasse: Kein Markup-/DB-Umbau, und die Regel
 * wirkt von selbst nicht mehr, sollte der Inhalt je auf ink umgestellt
 * werden. */
.kv-ueber-hero.has-white-background-color {
	background-color: var(--wp--preset--color--ink) !important;
	color: var(--wp--preset--color--paper);
}

/* Ueber-uns "KLIMA° vor acht in Action": die drei Panels (Team, Kooperationen,
 * Transparenz) untereinander statt nebeneinander, auch auf grossen Screens.
 * Die Core-Grid-Klasse wp-container-core-group-is-layout-* setzt
 * repeat(3, minmax(0,1fr)) mit Spezifitaet (0,1,0); die scoped Regel hier ist
 * (0,2,0) und schlaegt sie ohne !important. row-gap der Basisregel
 * (clamp(2rem,4vw,3rem)) liefert den vertikalen Panel-Abstand. */
.kv-ueber-action .kv-panel-group {
	grid-template-columns: 1fr;
}

/* Ueber-uns "In Action"-Sektion: die drei Karten (Team, Kooperationen,
 * Transparenz) liegen auf white; das generische paper-25 der
 * .kv-panel--card (rgb 254,253,250) ist dort gegen 255,255,255 fast
 * unsichtbar, die Karten lesen sich als Fliesstext. Deutliche Panel-
 * Flaeche in paper (Creme) setzt sie als Karten ab. */
.kv-ueber-action .kv-panel--card {
	background: var(--wp--preset--color--paper);
}

/* Rueckbau 05.09.: Die Korrektur vom 28.08. (die drei Mission-/Ansatz-
 * Panels per Scoped CSS mit !important auf Fließtextgröße normal
 * gezwungen) ist entfallen — Panel-Absätze nutzen wie auf /aktuelles/
 * die Body-Basisgröße (15–18px fluid). Die Zentrierung der Mission-
 * Panels ueberlebt im naechsten Block (.kv-ueber-mission .kv-panel),
 * die Geometrie-Anpassung (Spalten-Gap 20px, Karten-Padding-inline)
 * in den Regeln darunter. */

.kv-ueber-mission .kv-panel {
	align-items: center;
	text-align: center;
}

.kv-ueber-mission .kv-panel-group {
	column-gap: 20px;
}

.kv-ueber-mission .kv-panel--card {
	padding-inline: 20px;
}

/* ueber-uns "Unsere Mission" (01.09.): Die drei Missions-Panels sitzen in
 * der gemergten paper-Sektion; weiße blickdichte Karten setzen sie von der
 * paper-Fläche ab (der paper-25-Standard ist auf paper fast unsichtbar). */
.kv-ueber-mission .kv-panel--card {
	background: var(--wp--preset--color--white);
}

/* Gemergte Sektion "Vision & Mission" (01.09.): Der Abstand vor der
 * zweiten Überschrift ("Unsere Mission") wird reduziert; dafür endet die
 * Sektion mit 60px Padding (Sektions-Rhythmus wie sonst). Beide
 * Hier wird gezielt nachpositioniert: erster Stapel padding-top 80px /
 * padding-bottom 40px; zweiter Stapel erhält ein moderates Top-Padding
 * (Vergrößerung des Abstands zwischen den Innenstapeln) und 80px
 * padding-bottom; das Sektionsende (80px) liegt auf der Sektion selbst
 * (section.kv-ueber-mission). */
.kv-ueber-mission .kv-section__inner:first-child {
	padding-top: 80px;
	padding-bottom: 40px;
}
.kv-ueber-mission .kv-section__inner:last-child {
	padding-top: clamp(1rem, 2vw, 1.5rem);
	padding-bottom: 80px;
}
section.kv-ueber-mission {
	padding-bottom: 80px;
}

/* Ueber-uns CTA "Werde aktiv!": Die lange Ueberschrift laesst den Button
 * stets in eine eigene Zeile umbrechen (Content-Spalte ~1008px reicht fuer
 * Titel + Button ~1009px nicht). Sektionsinhalt ist deshalb durchgehend
 * zentriert. Die Basis-space-between-Anordnung der Flex-Zeile bleibt im
 * Markup bestehen und greift fuer kuerzere Titel, die neben dem Button
 * passen. */
.kv-ueber-cta .alignwide {
	justify-content: center;
}
.kv-ueber-cta .alignwide > .wp-block-heading {
	text-align: center;
}

/* Editor-Canvas: Top-Level-Sektionen über die volle verfügbare Breite
 * (18.08.): Die KV-Sektionen sind im Frontend Full-Bleed-Bands (100vw-
 * Breakout, siehe .kv-section oben). Im Block-Editor deckelt Gutenbergs
 * Layout-Regel `.is-root-container > :not(.alignleft):not(.alignright):
 * not(.alignfull)` die Top-Level-Blöcke jedoch auf
 * `--wp--style--global--content-size` (752px) und zentriert sie mit
 * `margin-inline: auto !important` – bei breiten Fenstern entstehen dadurch
 * riesige Ränder links/rechts (bei 1600px Fenster und ausgeblendeter
 * Sidebar exakt 424px). Diese Regel setzt für die Sektions-Shells
 * `.kv-section`/`.kv-hero` im Editor-Canvas die volle Breite durch (Kaskade
 * gegen die Gutenberg-Layout-Regel, .editor-styles-wrapper existiert nur im
 * Editor) und spiegelt damit das Frontend-Verhalten im Editor. Die
 * Innen-Spalte `.kv-section__inner` behält ihre 1440px-Deckelung, der
 * Frontend-Breakout bleibt unverändert. */
.editor-styles-wrapper .is-root-container > .kv-section,
.editor-styles-wrapper .is-root-container > .kv-hero {
	margin-inline: 0 !important;
	max-width: none !important;
	width: 100%;
}

/* Impressum: Tabelle "Gestaltung und technische Umsetzung"
 * Automatische Breite
 * Kein Rahmen */
.noBorders table{
	width: auto;
}
.noBorders td {
	border: none;
	padding: 4px;
}

/* Impressum/Datenschutz (page-id-96/97): Content-Hintergrund weiß statt
 * paper. Die Seiten haben keinen Sektions-Hintergrund im Markup; der
 * body zieht sonst das globale paper (theme.json). Die Regel (0,1,1)
 * schlägt die Global-Styles-body-Regel (0,0,1); Header (weiß via
 * .kv-header-inverted) und Footer (ink) behalten ihre eigenen Flächen. */
body.page-id-96,
body.page-id-97 {
	background-color: var(--wp--preset--color--white);
}

/* Rechtsseiten Impressum/Datenschutz: Inhalts-Links dunkelblau (ink),
 * fester Unterstreichungs-Offset (Textlink-Konvention 0.1em, hier
 * explizit für die beiden Seiten gesetzt). */
body.page-id-96 .wp-block-post-content a,
body.page-id-97 .wp-block-post-content a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

/* Ehrenamt-Seite: Inhalts-Links (Mail-Link im CTA) dunkelblau (ink),
 * fester Unterstreichungs-Offset (Textlink-Konvention 0.1em). */
body.kv-page-ehrenamt .wp-block-post-content a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

/* Presse-Seite: Inhalts-Links (die beiden Intro-Anker auf
 * #pressemitteilungen / #medien) dunkelblau (ink),
 * fester Unterstreichungs-Offset (Textlink-Konvention 0.1em). */
body.page-id-46 .wp-block-post-content a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

/* Spenden-Seite: Inhalts-Links (PDF-Textlink) dunkelblau (ink),
 * fester Unterstreichungs-Offset (Textlink-Konvention 0.1em). */
body.page-id-39 .wp-block-post-content a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

/* Newsletter-Seite: Inhalts-Links (Textlinks im Content + Titel-Links des
 * serverseitig angehängten Newsletter-Archivs; der ul hängt als letztes
 * Kind in derselben .wp-block-post-content) dunkelblau (ink),
 * fester Unterstreichungs-Offset (Textlink-Konvention 0.1em). */
body.page-id-108 .wp-block-post-content a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

/* Folgen-Seite (35): Inline-Textlink im Intro-Absatz (Playlist, 05.09.);
 * Ruhe-Farbe ink statt Browserblau, Konvention wie die anderen Seiten. */
body.page-id-35 .wp-block-post-content a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

/* Ehrenamt-Seite: kein Weißraum zwischen letzter Sektion und Footer
 * (page.html setzt das Bottom-Padding der Content-Group inline mit
 * clamp(3rem, 8vw, 6rem); !important schlägt Inline-Styles. Der
 * Spendenaufruf ist auf dieser Seite deaktiviert, es folgt direkt der
 * Footer – wie auf der Aktiv-werden-Seite (page-id-31).) */
body.kv-page-ehrenamt main .wp-block-group.alignwide {
	padding-bottom: 0 !important;
}

/* Verbreite-die-idee: Der Untergrund-Abstand des Content-Wrappers
 * (page.html, Inline-Padding bottom clamp(3rem,8vw,6rem)) liegt als
 * paper-Streifen zwischen der letzten Sektion (leaf) und dem ink-Footer.
 * Das Padding unten am Wrapper entfaellt und wird in die letzte Sektion
 * verlagert — der Abstand ist dann leaffarben, der Uebergang zum Footer
 * schliesst bündig an. */
body.page-id-41 main > .alignwide {
	padding-bottom: 0 !important;
}

body.page-id-41 .wp-block-post-content > .kv-section:last-child {
	padding-bottom: clamp(3rem, 8vw, 6rem);
}

/* Ehrenamt-Seite: Listen-Einträge in 24px (wie die Absätze). */
body.kv-page-ehrenamt .wp-block-post-content li {
	font-size: 24px;
}

/* Spenden-Seite: Listen-Einträge in 24px (wie die regulären Absätze). */
body.page-id-39 .wp-block-post-content li {
	font-size: 24px;
}

/* Spenden-Seite: Intro gehört zum Titel – kein Top-Padding des
 * Intro-.kv-section__inner, damit der Abstand Titel→Intro klein bleibt. */
body.page-id-39 .wp-block-post-content > :first-child .kv-section__inner {
	padding-top: 0;
}

/* Ehrenamt-Seite: Luft zwischen den beiden Abschnitts-Divs (H2 + Liste).
 * Gemessen 1280px: ul/h2-Block-Margins kollabieren hier zu 0, der Abstand
 * ul_1-Unterkante -> h2_2-Oberkante entspricht exakt diesem margin-top.
 * 3.75rem ergibt ~60px (Ziel ~60px, >= 55px). */
body.kv-page-ehrenamt .wp-block-post-content .kv-section__inner > .wp-block-group + .wp-block-group {
	margin-top: 3.75rem;
}

/* Ehrenamt-Seite: einheitliches Bottom-Padding (120px) für alle
 * Sektionen – Intro-Div, leaf-, white- und signal-Sektion. */
body.kv-page-ehrenamt .wp-block-post-content > div.wp-block-group,
body.kv-page-ehrenamt .kv-section.kv-activate .kv-section__inner,
body.kv-page-ehrenamt section.has-white-background-color .kv-section__inner,
body.kv-page-ehrenamt section.has-signal-background-color .kv-section__inner {
	padding-bottom: 120px;
}

/* Ehrenamt-Seite: im Intro-Div greift allein das Div-Padding (letzter
 * Absatz ohne eigenes Bottom-Margin, damit exakt 120px wirken). */
body.kv-page-ehrenamt .wp-block-post-content > div.wp-block-group > p:last-child {
	margin-bottom: 0;
}

/* Ehrenamt-Seite (Auftrag 14.09.): Intro-Bild exakt panel-breit — gemessen
 * an der Panel-Sektion direkt darunter. Beide liegen in verschiedenen
 * Spaltensystemen: Das Intro sitzt im alignwide-Stream (max-width 1136px
 * zuzueglich Body-Gutter), die Panel-Sektion bricht als .kv-section__inner
 * auf 100vw aus und begrenzt ihren Inhalt über das eigene Padding
 * (clamp(1rem, 10.5vw, 9.5rem)). Zufaellig identisch nur bei ≥1440px
 * (1136px); darunter driftet die rechte Bildkante von der Panel-Kante ab
 * (1200px: Intro 1128px vs Panel-Inhalt 948px). Das Intro bekommt deshalb
 * denselben Full-Bleed-Breakout wie die Sektionen (etabliertes Muster
 * margin-inline calc(50% - 50vw) + width 100vw) und Copy + Bild je
 * calc(50% - 20px) — 2 Panel-Spalten, 40px Gap, also bei jedem Viewport
 * ab 783px exakt panel-breit. Ueber 1440px klemmt min(50vw, 720px) den
 * Box-Umriss auf das 1440px-Innenmass (Aequivalent zur max-width des
 * .kv-section__inner); Padding-Clamp ist identisch, die Inhalte decken
 * sich dadurch pixelgenau. Unter 782px greift KEINE der Regeln (Media-
 * Query): die bestehende Stapel-Regel setzt Copy und Bild auf volle
 * Content-Breite wie bisher (Auftrag 14.09.: <782px volle Breite). */
@media (min-width: 783px) {
	body.kv-page-ehrenamt .wp-block-post-content > .kv-wirkung-intro {
		box-sizing: border-box;
		margin-inline: calc(50% - min(50vw, 720px));
		padding-inline: clamp(1rem, 10.5vw, 9.5rem);
		width: min(100vw, 1440px);
	}

	body.kv-page-ehrenamt .wp-block-post-content > .kv-wirkung-intro > .kv-wirkung-intro__copy,
	body.kv-page-ehrenamt .wp-block-post-content > .kv-wirkung-intro > .kv-wirkung-intro__image {
		flex-basis: calc(50% - 20px);
		max-width: calc(50% - 20px);
	}
}

@media (min-width: 1440px) {
	body.kv-page-ehrenamt .wp-block-post-content > .kv-wirkung-intro {
		/* Fixwert wie .kv-section__inner (Padding-Klemme greift ab hier
		 * nicht mehr; ohne Override bliebe 10,5vw = 151,2px und die
		 * Kanten stünden 0,8px versetzt). */
		padding-inline: 9.5rem;
	}
}

/* Team-Seite – Einblicke-Sektion (ink) */
/* Die Einblicke-Sektion (Block klima-vor-acht/team-einblicke) ist eine
   durchgehende ink-Fläche; die ungefärbten Sektionstexte erben die helle
   Textfarbe. Geometrie und Slider kommen von .kv-section bzw. der
   zentralen Slider-Chrome. */
.kv-team-einblicke {
	box-sizing: border-box;
	color: var(--wp--preset--color--paper-25);
}

/* Team-Seite – Bildecken: Gruppenfoto (Hero-Sektion) und Vorstands-
 * Porträts bekommen 16px wie die Kartenbilder auf Papier/Weiß (Auftrag
 * 11.09.); die Slider-Kartenbilder behalten ihre Figma-24px. */
.kv-team-vorstand .kv-panel__media {
	width: 100%;
	margin-inline: auto;
}

.kv-team-vorstand .kv-panel__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 16px;
}

.kv-team-hero .kv-panel__media img {
	border-radius: 16px;
}

/* === Profilbildgenerator (pbg) – scoped auf .pbg-container ===========
 * Die Library `profile-picture-generator` rendert ihren Generator unter
 * .pbg-container.fff-profile-picture-generator (max-width: 350px) und
 * bringt Eigen-CSS mit (Upload-/Download-Button standardmäßig grün
 * #1da64a mit !important). Die folgenden Regeln überstimmen das scoped,
 * damit Upload- und Download-Button wie der Theme-Primary-Button
 * is-style-primary-ink aussehen (ink #052B8E, Text paper-25, Hover
 * #3F62AD, Radius 8px) und der Generator samt Ergebnis horizontal
 * zentriert wird. Der Datenschutzhinweis der Library wird ausgeblendet –
 * der Hinweis steht bereits im Seiteninhalt unter dem Generator und die
 * zugehörigen Config-Werte sind in pbg-init.js geleert. */

/* Generator horizontal in der Inhalts-Spalte zentrieren und inneres
 * Layout als zentrierte Spalte (Button-Gruppe, Vorschau, Ergebnis). */
.pbg-container.fff-profile-picture-generator {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	margin-left: auto;
	margin-right: auto;
}

/* Upload-Button (label) als Theme-Primary-Button primary-ink.
 * Die Library nutzt background:#1da64a !important – daher spezifischerer
 * Selektor + !important zum Überstimmen (dokumentiert). */
.pbg-container .fff-profile-picture-generator--button-group label.fff-profile-picture-generator--button.special-link {
	background-color: var(--wp--preset--color--ink) !important;
	color: var(--wp--preset--color--paper-25) !important;
	border-radius: 8px;
	padding: 0.75rem 1rem;
}

.pbg-container .fff-profile-picture-generator--button-group label.fff-profile-picture-generator--button.special-link:hover {
	background-color: #3F62AD !important;
	color: var(--wp--preset--color--paper-25) !important;
}

/* Der Upload-Button ist ein <label> um ein ausgeblendetes
 * input[type=file>; der Tastatur-Fokus liegt im Input. :focus-within
 * garantiert einen sichtbaren Fokusring am Button. */
.pbg-container .fff-profile-picture-generator--button-group label.fff-profile-picture-generator--button.special-link:focus-within {
	outline: 3px solid var(--wp--preset--color--ink);
	outline-offset: 2px;
}

/* Download-Button (a) ebenfalls als primary-ink halten, damit kein
 * grüner Library-Stil mehr durchschlägt – bleibt so auf Desktop
 * erkennbar und klickbar. Sichtbarer :focus-visible-Fokus. */
.pbg-container > a.fff-profile-picture-generator--button.special-link {
	background-color: var(--wp--preset--color--ink) !important;
	color: var(--wp--preset--color--paper-25) !important;
	border-radius: 8px;
	padding: 0.75rem 1rem;
}

.pbg-container > a.fff-profile-picture-generator--button.special-link:hover,
.pbg-container > a.fff-profile-picture-generator--button.special-link:focus-visible {
	background-color: #3F62AD !important;
	color: var(--wp--preset--color--paper-25) !important;
	outline: 3px solid var(--wp--preset--color--ink);
	outline-offset: 2px;
}

/* Datenschutzhinweis der Library ausblenden (Hinweis ist im
 * Seiteninhalt unter dem Generator vorhanden und wird zusätzlich in
 * pbg-init.js geleert). */
.pbg-container .fff-profile-picture-generator--privacy-note {
	display: none !important;
}

/* Profilbildgenerator-Seite (Unterseite der Aktiv-werden-Sektion):
 * Inhalts-Links dunkelblau (ink), fester Unterstreichungs-Offset
 * (Textlink-Konvention 0.1em) – analog zu den Rechtsseiten/Ehrenamt/Spenden.
 * Die Share-Leiste (.kv-share-link) wird ausgenommen, damit ihr eigenes
 * Design (inkl. Hover-Fill) erhalten bleibt. Der Scope nutzt die stabile
 * Body-Class `kv-paper-child` statt der Post-ID, da die Seiten-IDs lokal
 * (1515) und auf dem Staging (1412) voneinander abweichen. */
body.kv-paper-child .wp-block-post-content a:not(.kv-share-link) {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

/* pbg / Kindern der Aktiv-werden-Sektion: Luft unterhalb des Absatzes vor
 * einer full-bleed Leaf-Sektion (standard content gap, ~120px @≥1440).
 * Gezielt auf den Top-Level-Absatz direkt vor der Leaf-Sektion; der
 * Share-Titel (.kv-share-title) wird ausgenommen, damit sein eigener
 * margin-block-end (0.75rem) erhalten bleibt. */
body.kv-paper-child .wp-block-post-content > p:not(.kv-share-title) {
	margin-bottom: clamp(3rem, 8vw, 7.5rem);
}

/* === 404 – Sendepause unter Wasser =================================
 * Konzept "Land unter im Studio": groesse "404" in IBM Plex Sans 700 auf
 * ink; die Null ist ein Gradkreis-Ring (Anulus-Morphologie, signal) mit
 * Zeigerstand 19:52 = acht Minuten vor acht. Aus dem unteren Rand der
 * Sektion steigt gestaffeltes Wasser (drei nahtlos kachelnde Wave-Tiles
 * assets/images/404/welle-*.svg, Periode 480px = 2 Sinuswellen a 240px,
 * repeat-x stossfrei, erzeugt von .weave/tmp/404/waves.mjs): hinten blau,
 * mitte tuerkishaum, vorn paper-Flaeche, die optisch in die paper-Suche
 * unterhalb der Sektion uebergeht. Der Ring taucht halb unter (water
 * z-index ueber dial, unter copy – Text bleibt immer lesbar).
 *
 * Geometrie: .kv-404__inner ist ein Grid (mobile 1 Spalte, ab 1024px
 * Copy links / Dial rechts); das padding-bottom der Shell ist die
 * Wasserzone, in der die Ziffernhälfte versinkt. Die Deko-Blocke stammen
 * aus wp:html-Freeform und sind aria-hidden; der Status-Satz "Fehler 404"
 * steht als sichtbarer Kicker (Screenreader-Hinweis kommt zusaetzlich
 * ueber die section-aria-label).
 *
 * Motion: background-position-x-Drift pro Bahn (ein Tile = ein Loop,
 * damit lückenlos), Rise-In der Flut beim Laden; unter
 * prefers-reduced-motion keine Animation – der Ruhezustand IST die
 * bereits gestiegene Flut ohne Drift (die Animationen starten erst aus
 * dem versenkten Zustand, ihr Wegfall zeigt also den Endzustand).
 *
 * Fokus: auf der paper-Suche-Sektion waere die globale signal-Outline
 * unsichtbar (signal auf paper ~1.7:1) – sie wird hier auf ink gesetzt
 * (Vorbild .kv-post-cta). */

/* Shell: water-clipping + eigener Layout-Kontext (die 404-Sektion steht
 * fur sich; der Hero-Overlay-Hang der Startseite betrifft sie nicht). */
.kv-404 {
	overflow: hidden;
	position: relative;
}

/* Raster: Copy + Dial; unten die Wasserzone als padding-bottom. */
.kv-404__inner {
	align-items: center;
	display: grid;
	gap: clamp(2rem, 5vw, 4.5rem);
	justify-items: start;
	padding-bottom: clamp(210px, 24vw, 290px);
}

@media (min-width: 1024px) {
	.kv-404__inner {
		grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
	}
}

.kv-404__copy {
	position: relative;
	z-index: 4; /* Flut bleibt unter dem Text */
}

.kv-404__kicker {
	color: var(--wp--preset--color--signal);
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.12em;
	margin-block: 0 1rem;
	text-transform: uppercase;
}

.kv-404__headline {
	text-wrap: balance;
}

.kv-404__lead {
	max-width: 46ch;
}

/* Hashtag in der Lead-Zeile (Auftraggeber 28.08.; Farb-Vorgabe 08.09.): keine
 * farbliche Hervorhebung mehr – erbt die Lead-Farbe (paper auf ink). Eigene
 * Klasse, damit der render_block-Swap den kompletten Lead-String inkl.
 * span-Markup findet. inline-block + margin-top, damit der Abstand zur
 * Lead-Zeile wirkt (auf rein inline-Elements greift margin-top im Zeilensatz
 * nicht); 0.625rem ueber dem 1.55-Zeilenabstand des Leads als bewusste
 * 'minimale' Atemluft (Nachzieh 28.08.). */
.kv-404__hashtag {
	display: inline-block;
	font-weight: 600;
	margin-top: 0.625rem;
}

/* "Wir schalten um:" fuehrt die Buttons-Zeile ein (Auftraggeber 28.08.):
 * 1rem Abstand zu den Buttons wie der Kicker-Rhythmus ueber der H1.
 * Nach oben 1,75rem (~28px; der Lead-Absatz endet margin-los, die
 * Flow-Regel :where(.is-layout-flow) > * setzt nur margin-block-end 0 —
 * der Top-Margin steht also allein): der Satz eroeffnet ein neues Thema
 * (Call-to-Action) und loest sich optisch vom Lead darueber (28.08.). */
.kv-404__switch {
	margin-block: 1.75rem 1rem;
}

/* Buttons auseinanderruecken: die Zeile fuellt die Copybreite der Spalte –
 * Primary links, Secondary rechtsbuendig an derselben Kante wie der Lead.
 * Eigene ch-Deckelung entfaellt (die 46ch des Leads gelten relativ zu
 * dessen groesserer Schrift und haerden die Buttonszeile schmaler). */
.kv-404__actions {
	/* Core richtet Buttons-Zeilen an der Grundlinie aus; mit dem
	 * randlosen Primary links und dem 1,5px-Rahmen des Secondary rechts
	 * entsteht dabei ein paar-pixeliger Vertikalversatz – mittig setzen. */
	align-items: center;
	justify-content: space-between;
}

/* Ausnahme 28.08. (Auftraggeber): Der Secondary-Button der 404-Gruppe
 * wirkt gegenueber dem groesser gesetzten Primary duenner (beide stehen
 * systemseitig auf 600; der Primary-Clamp geht bis 24px, Secondary erbt
 * 17px). Fuer harmonische Paare hier ausnahmsweise auf 700 (Bold ist im
 * Source-Sans-3-Stack geladen); scoped auf .kv-404__actions, damit die
 * Button-Systemregeln unveraendert bleiben. */
.kv-404__actions .is-style-secondary-paper .wp-block-button__link {
	font-weight: 700;
}

.kv-404__clock-label {
	color: var(--wp--preset--color--paper-25);
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-weight: 600;
	margin-block: 1.25rem 0;
	opacity: 0.85;
}

/* --- Die 404: Ziffern + Gradkreis-Uhr als Null ---------------------- */
.kv-404__dial {
	align-self: end;
	/* Der Ziffernsockel sinkt in die Flut: die Unterkannte bleibt 85px ueber
	 * der Sektionsunterkante – genau auf Hoehe des tuerkis-Kamms der mittleren
	 * Bahn (93.5px), der paper-Schaum (48px) steht weiter unten. Die Tiefe
	 * rechnet gegen die Wasserzone (padding-bottom von .kv-404__inner), damit
	 * der Einsinkgrad an jedem Viewport gleich aussieht. */
	justify-self: center;
	margin-block-end: calc(clamp(210px, 24vw, 290px) * -1 + 85px);
	position: relative;
	z-index: 2; /* unter der Flut (water: z-index 3) */
}

.kv-404__dial-stack {
	align-items: center;
	display: flex;
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: clamp(7rem, 24vw, 13rem);
	font-weight: 700;
	justify-content: center;
	letter-spacing: -0.04em;
	line-height: 0.9;
}

.kv-404__digit {
	color: var(--wp--preset--color--paper-25);
}

.kv-404__clock {
	color: var(--wp--preset--color--signal); /* currentColor fuellt den Anulus */
	flex: none;
	height: 0.92em;
	margin-inline: -0.045em; /* Ziffern ruecken dicht an den Ring */
	width: 0.92em;
}

.kv-404__clock-ring {
	fill: currentColor;
}

.kv-404__clock-hand {
	stroke: var(--wp--preset--color--paper-25);
	stroke-linecap: round;
	stroke-width: 8;
}

.kv-404__clock-pin {
	fill: var(--wp--preset--color--paper-25);
}

/* --- Die Flut -------------------------------------------------------- */
/* Am Sektionsboden verankert; Hoehe = eine Kachel. Die Ziffern tauchen per
 * Negativ-Margin des Dial in diese Zone ein, der Text bleibt darueber. */
.kv-404__water {
	bottom: 0;
	height: clamp(140px, 18vw, 190px);
	left: 0;
	pointer-events: none;
	position: absolute;
	right: 0;
	z-index: 3;
}

/* Alle drei Bahnen bodenbuendig; die gestaffelte Kamm-Hoehe steckt in den
 * Tiles selbst (Kamm ueber Grund: hinten 130px, mitte 100px, vorn 70px) –
 * dadurch skaliert der Stapel ohne Proportional-Offsets. Der paper-Kamm der
 * vorderen Bahn liegt bewusst UNTER dem tuerkis-Kamm, damit die Schaumkante
 * wie eine echte Wasserlinie wirkt und der paper-Sockel buendig in die
 * paper-Suche unterhalb der Sektion uebergeht. */
.kv-404__wave {
	background-position: 0 bottom;
	background-repeat: repeat-x;
	background-size: 480px 160px;
	bottom: 0;
	height: 160px;
	left: 0;
	position: absolute;
	right: 0;
}

.kv-404__wave--back {
	background-image: url("assets/images/404/welle-hinten.svg");
}

.kv-404__wave--mid {
	background-image: url("assets/images/404/welle-mitte.svg");
	bottom: 6px;
}

.kv-404__wave--front {
	background-image: url("assets/images/404/welle-vorn.svg");
}

@media (prefers-reduced-motion: no-preference) {
	/* Rise-In: die Flut steigt beim Laden auf ihre Ruhelage. */
	.kv-404__water {
		animation: kv-404-rise 1.4s cubic-bezier(0.22, 1, 0.36, 1) both;
	}

	@keyframes kv-404-rise {
		from { transform: translateY(40%); }
		to { transform: translateY(0); }
	}

	/* Drift: ein Tile (480px) pro Loop = lueckenlose Wellenwanderung;
	 * gegenlaeufige Richtungen fuer Tiefe. */
	.kv-404__wave--back {
		animation: kv-404-drift 42s linear infinite;
	}

	.kv-404__wave--mid {
		animation: kv-404-drift 30s linear infinite reverse;
	}

	.kv-404__wave--front {
		animation: kv-404-drift 22s linear infinite;
	}

	@keyframes kv-404-drift {
		from { background-position-x: 0; }
		to { background-position-x: 480px; }
	}
}

/* --- Suche unter Wasser (paper-Flaeche) ------------------------------ */
/* Abschluss-Luft zum Footer: 60px wie der Standard-Abschnittsrhythmus der
 * Seitenabschluesse (.kv-aktuelles padding-bottom 60px, Ressourcen-
 * Praeedenz); das Standard-Sektionspadding (80px ab 1440px) waere zu viel. */
.kv-404__search-inner {
	margin-inline: auto;
	max-width: 752px;
	padding-bottom: 60px;
	text-align: center;
}

.kv-404__search-kicker {
	color: var(--wp--preset--color--dunkelblau-75);
	font-family: var(--wp--preset--font-family--ibm-plex-sans);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.12em;
	margin-block: 0 0.75rem;
	text-transform: uppercase;
}

.kv-404__search-block {
	justify-content: center;
	margin-inline: auto;
	max-width: 420px;
}

.kv-404__search .wp-block-search__inside-wrapper {
	background: var(--wp--preset--color--white);
	border: 1.5px solid var(--wp--preset--color--ink);
	border-radius: 8px;
}

.kv-404__search .wp-block-search__input {
	background: transparent;
	color: var(--wp--preset--color--ink);
	min-height: 52px; /* Gesamtfeld-Hoehe 54px (inkl. 2×1,5px Rahmen) wie
	 * vor dem Flush-Umbau; der fruehere 4px-Button-Rand stellte sie ueber
	 * die Flex-Zeilenhoehe her, jetzt traegt der Input sie selbst */
	padding-block: 0.6rem;
	padding-inline: 1rem;
}

.kv-404__search .wp-block-search__button {
	/* Footer-Newsletter-Variante (Auftraggeber 28.08.): Button direkt an
	 * den Input, füllt die Feldhöhe (Vorbild .kv-newsletter-form:
	 * input 6px|0|0|6px + Button 0|6px|6px|0). Gesamtfeld-Geometrie
	 * unveraendert: 420px × ~54px. Rechte Ecken 6,5px = Wrapper-Radius
	 * 8px minus 1,5px Rahmen. */
	align-self: stretch;
	background: var(--wp--preset--color--ink);
	border: 0;
	border-radius: 0 6.5px 6.5px 0;
	color: var(--wp--preset--color--paper-25);
	font-weight: 600;
	margin: 0;
	padding: 0.55rem 1rem;
}

.kv-404__search .wp-block-search__button:hover,
.kv-404__search .wp-block-search__button:focus-visible {
	background: #3F62AD;
}

/* Core setzt search-input:focus outline:none – den Tastatur-Fokus
 * zurueckholen; signal ist auf paper unsichtbar, hier also ink. */
.kv-404__search .wp-block-search__input:focus-visible {
	outline: 3px solid var(--wp--preset--color--ink);
	outline-offset: 2px;
}

.kv-404__search :focus-visible {
	outline-color: var(--wp--preset--color--ink);
}

/* Textlink im Suche-Absatz ("Kontakt zu unserer Redaktion"): ink wie die
 * Inhaltslinks der Standardseiten (Konvention 0.1em Offset, dickerer Strich
 * im Hover aus der globalen a:hover-Regel). Nötig, weil die 404-Seite
 * weder page-id-* noch .wp-block-post-content trägt — die bestehenden
 * Linkfarb-Regeln greifen hier strukturell nicht, der Link lief bisher in
 * Browser-Standardblau. */
.kv-404__search a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}


/* Autor:innen-Sektion der Buch-Seite (05.09.). Karten-Raster mit nativen
 * core/accordion-Disclosures pro Person (dieselbe Slide-Technik wie die
 * Spenden-FAQ: kv-accordion-light in style.css — Chevron, 0fr/1fr-Glide,
 * align-content: start, [hidden]-Override greifen ueber die Akkordeon-
 * Klasse); die letzte Karte unten ist ein Akkordeon „Weitere Autor:innen“
 * mit den Beitrager:innen ohne Portraet. Anlehnung an die Karten-Optik der
 * alten Website, umgesetzt mit Theme-Palette (paper-Flaeche, ink-Text). */
.kv-buch-autoren .kv-author-grid {
	column-gap: 40px;
	row-gap: clamp(2.5rem, 4vw, 3.5rem);
}

/* Fluss (Auftrag 05.09.): unter 640px eine Person pro Zeile, ab 640px
 * zwei, ab 1024px drei. Core schreibt die columnCount (3) als Inline-/
 * Head-Style am Grid — nur !important schlaegt ihn, Praezedenz
 * .kv-panel-group. */
.kv-buch-autoren .kv-author-grid {
	grid-template-columns: minmax(0, 1fr) !important;
}

@media (min-width: 640px) {
	.kv-buch-autoren .kv-author-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}
}

@media (min-width: 1024px) {
	.kv-buch-autoren .kv-author-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
	}
}

/* Bildzeile (Figma-Maße 05.09., Praezisierung: „98px together, 49px on each
 * side of the image"): Grid 49px | 198px | 49px, linksbuendig am Kartenrand.
 * Das Portraet sitzt mittig zwischen zwei je 49px breiten Gutter-Spalten;
 * der Copyright-Hinweis der Alt-Originale steht vertikal im LINKEN Gutter,
 * mittig darin — lesbar von unten nach oben: DOM-Reihenfolge img ->
 * figcaption wird per grid-column vertauscht, writing-mode vertical-rl +
 * rotate(180deg) dreht den Text gegen den Uhrzeigersinn; als Flex-Container
 * mit vertical-rl haelt align-items (Kreuzachse = horizontal) den Streifen
 * mittig in der Spalte und justify-content (Hauptachse = vertikal) mittig
 * zur Bildhoehe. Das rechte Gutter bleibt leer. Karten ohne figcaption
 * lassen das linke Gutter bewusst leer (Auftrag: "leave empty") — alle
 * Portraets starten dadurch auf derselben X-Position und sind
 * spaltenweise vertikal ausgerichtet. */
.kv-author-card__media {
	align-items: center;
	display: grid;
	grid-template-columns: 49px 198px 49px;
	justify-content: start;
	margin: 0 0 0.75rem;
}

.kv-author-card__media img {
	aspect-ratio: 1;
	border-radius: 50%;
	grid-column: 2;
	grid-row: 1;
	object-fit: cover;
	width: 198px;
}

/* 14px (Auftrag 05.09.; war 0.75rem) — Streifendicke = Zeilenhoehe. */
.kv-author-card__media figcaption {
	align-items: center;
	color: var(--wp--preset--color--dunkelblau-75);
	display: flex;
	font-size: 0.875rem;
	grid-column: 1;
	grid-row: 1;
	justify-content: center;
	line-height: 1;
	margin: 0;
	position: static;
	text-align: initial;
	text-orientation: sideways;
	transform: rotate(180deg);
	writing-mode: vertical-rl;
}

/* Name: max. 24px (Auftrag 05.09.; das large-Preset waren bis ~34px). */
.kv-author-card__name {
	font-size: clamp(1.25rem, 2.2vw, 1.5rem);
	margin-block: 0 0.25rem;
}

.kv-author-card__job {
	font-style: italic;
	margin-block: 0 0.5rem;
}

/* Pro-Person-Akkordeon: die kv-accordion-light-Chrome (Chevron, Slide,
 * border) gilt ueber die Klasse; hier die Karten-Feinjustierung. Die
 * Trennlinie der kv-accordion-light-Gruppe ist fuer Liste-FAQs — Karten
 * brauchen sie nicht; ebenso entfaellt das is-open-Padding (es wuerde den
 * Karteninhalt am Animationsende springen lassen). Core gibt dem Toggle
 * 1em vertikales Padding — fuer eine kompakte Zeile unter der Job-Zeile
 * auf 0.35rem reduziert. */
.kv-author-acc {
	margin-block: 0;
}

.kv-author-acc .wp-block-accordion-item {
	border-bottom: 0;
}

.kv-author-acc .wp-block-accordion-item.is-open {
	padding-block-end: 0;
}

.kv-author-acc .wp-block-accordion-heading__toggle {
	padding-block: 0.35rem;
}

.kv-author-acc .wp-block-accordion-heading {
	margin-bottom: 0.25rem;
}

/* Chevron direkt nach dem Text (Auftrag 05.09., Vorbild Alt-Site): der
 * Core richtet die Toggle-Zeile mit space-between aus — fuer die Karten
 * auf flex-start, sonst klebt das Chevron am Zeilenende. */
.kv-author-card .kv-author-acc .wp-block-accordion-heading__toggle {
	justify-content: flex-start;
}

/* Core streckt den Titel mit flex: 1 ueber die ganze Zeile — das Chevron
 * klebt damit am rechten Rand. Zurueck auf normale Flex-Breite, dann sitzt
 * das Chevron (kv-accordion-light::after, currentColor) direkt hinter dem
 * Text (Auftrag 05.09., Vorbild Alt-Site). */
.kv-author-card .kv-author-acc .wp-block-accordion-heading__toggle-title {
	flex: none;
}

/* Toggle-ZEILE UNTER der Bio (Auftrag 05.09.): das Panel laeuft in
 * Grid-Zeile 1 (0fr↔1fr), die Ueberschrift steht optisch in Zeile 2.
 * DOM-Reihenfolge bleibt Heading -> Panel, der Tab-Fokus folgt weiter
 * zuerst dem Button; grid-row stellt die sichtbare Reihenfolge um. */
.kv-author-card .kv-author-acc > .wp-block-accordion-item {
	grid-template-rows: 0fr auto;
}

.kv-author-card .kv-author-acc > .wp-block-accordion-item.is-open {
	grid-template-rows: 1fr auto;
}

.kv-author-card .kv-author-acc > .wp-block-accordion-item > .wp-block-accordion-panel {
	grid-row: 1;
}

.kv-author-card .kv-author-acc > .wp-block-accordion-item > .wp-block-accordion-heading {
	grid-row: 2;
	margin-bottom: 0;
}

/* h4-Titel in der Karte: feste 18px (Auftrag 05.09.: „max. 18px“ fuer
 * mehr/weniger anzeigen; das normal-Preset ging bis 24px). */
.kv-author-acc h4.wp-block-accordion-heading .wp-block-accordion-heading__toggle-title {
	font-size: 1.125rem;
	font-weight: 700;
}

/* Beschriftungs-Swap des Toggles: offen zeigt nur „weniger anzeigen“.
 * Zwingend mit Kind-Kombinatoren (> item > heading) scoped: Das
 * „Weitere Autor:innen“-Akkordeon traegt ebenfalls .kv-author-acc/-light;
 * ein Nachfahren-Selektor liesse dessen .is-open-Item auf alle inneren
 * Karten greifen ( LABEL-BUG: alles waere auf einmal „weniger anzeigen“).
 * Der Swap gilt nur fuer das Item desselben Akkordeon-Wurzelknotens. */
.kv-author-card__less {
	display: none;
}

.kv-author-acc > .wp-block-accordion-item.is-open > .wp-block-accordion-heading .kv-author-card__more {
	display: none;
}

.kv-author-acc > .wp-block-accordion-item.is-open > .wp-block-accordion-heading .kv-author-card__less {
	display: inline;
}

/* Chevron-Rotation analog strukturell zurueckgeholt: Die generische
 * kv-accordion-light-Regel (Nachfahren) wuerde im geoeffneten Aeusseren
 * auch die Chevron-Pfeile aller inneren Karten drehen. Geschlossene
 * innere Items erzwingen hier den Ruhewinkel (hoehere Spezifitaet,
 * Praezedenz Spendieren-FAQ/Nesting-Bug 05.09.). */
.kv-author-card .kv-author-acc > .wp-block-accordion-item:not(.is-open) > .wp-block-accordion-heading .wp-block-accordion-heading__toggle::after {
	transform: rotate(45deg) translateY(-0.1em);
}

/* Unterer Bio-Abstand: haengt an der Bio SELBST (innen in der animierten
 * Panel-Zeile) und waechst sanft mit; ein Margin/Padding am Toggle oder
 * Panel wuerde beim Slide springen (Praezedenz Spenden-FAQ). */
.kv-author-card__bio {
	margin: 0 0 0.75rem;
}

/* Bio-Links (extern, nofollow aus Alt-Markup): ink wie die Textlink-
 * Konvention der Content-Seiten (statt Browser-Standardblau auf paper). */
.kv-buch-autoren .kv-author-card__bio a {
	color: var(--wp--preset--color--ink);
	text-underline-offset: 0.1em;
}

/* „Weitere Autor:innen“: Akkordeon unter dem Bild-Raster (Auftrag 05.09.,
 * ueberarbeitet): geschlossen EIN zentrierter GHOST-Button oben
 * („Weitere Autor:innen“); geoeffnet versteckt der sich und am ENDE der
 * Liste steht der passende Ghost-Button „Weniger Autor:innen“ zum
 * Schliessen. Beide Buttons teilen denselben core/accordion-Zustand: der
 * untere ist ein natives <button> mit data-wp-Direktiven im Item
 * (actions.toggle loest dasselbe state.isOpen aus wie der Core-Toggle
 * oben); assets/js/buch-autoren-more.js gibt nach dem Swap den
 * Tastatur-Fokus zurueck. Ghost-Optik = secondary-ink-Geometrie
 * (transparent, 1,5px ink-Border, Hover ink-Fill/paper-25-Text).
 * Slide-Animation und Chevron bleiben die der kv-accordion-light-Technik
 * (currentColor => Chevron folgt der Button-Textfarbe). Alle Selektoren
 * mit Kind-Kombinator (> item > heading) auf die aeussere Zeile scoped;
 * die inneren 11 Text-Karten behalten ihr Zeilen-Layout. */
.kv-author-acc--more {
	margin-block-start: clamp(2.5rem, 4vw, 3.5rem);
}

/* Zentrierte Button-Zeile; der Abstand Button->Raster haengt an der
 * Ueberschrift (erste, nie animierte Grid-Zeile), NICHT als margin-top am
 * Panel — das wuerde innerhalb der animierten 0fr-Zeile springen
 * (Praezedenz Spenden-FAQ). Das Panel mit den Text-Karten haelt
 * linksbuendige Kartentexte wie die Bild-Gruppe. */
.kv-author-acc--more > .wp-block-accordion-item > .wp-block-accordion-heading {
	margin-bottom: 1.5rem;
	text-align: center;
}

.kv-author-acc--more > .wp-block-accordion-item > .wp-block-accordion-panel {
	text-align: start;
}

/* Oben der Core-Toggle, unten sein Gegenstueck — beide als Ghost-Button
 * (secondary-ink), kompakt in medium-Stufe. */
.kv-author-acc--more > .wp-block-accordion-item > .wp-block-accordion-heading .wp-block-accordion-heading__toggle,
.kv-author-less-btn {
	align-items: center;
	background: transparent;
	border: 1.5px solid var(--wp--preset--color--ink);
	border-radius: 8px;
	color: var(--wp--preset--color--ink);
	display: inline-flex;
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 700;
	justify-content: center;
	padding: 0.5rem 1rem;
	width: auto;
}

/* Titel erbt NICHT die x-large-Stufengroesse der kv-accordion-light-
 * h2-Regel (weiter oben, identische Spezifitaet, spaetere Regel gewinnt). */
.kv-author-acc--more > .wp-block-accordion-item > .wp-block-accordion-heading .wp-block-accordion-heading__toggle-title {
	font-size: var(--wp--preset--font-size--medium);
	font-weight: 700;
}

.kv-author-acc--more > .wp-block-accordion-item > .wp-block-accordion-heading .wp-block-accordion-heading__toggle:hover,
.kv-author-acc--more > .wp-block-accordion-item > .wp-block-accordion-heading .wp-block-accordion-heading__toggle:focus-visible,
.kv-author-less-btn:hover,
.kv-author-less-btn:focus-visible {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper-25);
}

/* Core unterstreicht den Titel im Toggle-Hover — auf einem Button fehlt
 * diese Textlink-Gestik (nur die aeussere Zeile). */
.kv-author-acc--more > .wp-block-accordion-item > .wp-block-accordion-heading .wp-block-accordion-heading__toggle:hover .wp-block-accordion-heading__toggle-title,
.kv-author-acc--more > .wp-block-accordion-item > .wp-block-accordion-heading .wp-block-accordion-heading__toggle:focus-visible .wp-block-accordion-heading__toggle-title {
	text-decoration: none;
}

.kv-author-acc--more > .wp-block-accordion-item {
	border-bottom: 0;
}

/* Anzeige-Swap: geschlossen nur der obere Button sichtbar, geoeffnet nur
 * der untere (er sitzt im Panel, deshalb Nachfahren-Selektor).
 * display:none nimmt beide jeweils auch aus der Tab-Reihenfolge; den
 * Fokus-Rueckwechsel uebernimmt assets/js/buch-autoren-more.js. */
.kv-author-less-wrap {
	display: none;
	justify-content: center;
	margin-top: clamp(2rem, 3vw, 2.5rem);
}

.kv-author-acc--more > .wp-block-accordion-item.is-open > .wp-block-accordion-heading {
	display: none;
}

.kv-author-acc--more > .wp-block-accordion-item.is-open .kv-author-less-wrap {
	display: flex;
}

/* Chevron hoch am unteren Button (Zeiger-Optik des oberen Toggles, nur im
 * geoeffnet-Zustand; currentColor folgt der Button-Textfarbe). */
.kv-author-less-btn::after {
	border-bottom: 2px solid currentColor;
	border-right: 2px solid currentColor;
	content: "";
	flex-shrink: 0;
	height: 0.55em;
	margin-left: 0.6rem;
	transform: rotate(225deg) translateY(0.1em);
	width: 0.55em;
}

/* signal-Outline des globalen focus-visible ist auf paper kaum sichtbar
 * (1,5:1) — wie bei der 404-Suche ink (Praezedenz .kv-404__search);
 * auf der ghost-Kante ist die ink-Outline gut sichtbar. */
.kv-buch-autoren :focus-visible {
	outline-color: var(--wp--preset--color--ink);
}

/* ======================================================================
 * Kooperationen (Seite /ueber-uns/partner-netzwerk/, body class page-id-44):
 * Sektion "Kooperationspartner" als Panel-Sektion auf paper. Drei
 * Partner-Karten (kv-partner-card) im einspaltigen Panel-Grid: Logo
 * links in der Karte, der Text (H3, Fakten-Tabelle, Absaetze) rechts.
 * Das Zeilenmass des Texts steuert das Spaltenverhaeltnis bzw. der
 * Freiraum um das Logo: Logo-Spalte 18rem (Logo-Box 12rem im 2:1-
 * Format, contain-zentriert, Praezedenz Folgen-Kacheln mit object-fit;
 * Rest = Atemraum) + 3rem Luecke, Text-Spalte nimmt den Rest (~44rem
 * = ~85-100 Zeichen/Zeile). Unter 960px stapelt der Card-Grid um
 * (Logo oben, Text darunter), damit die Textspalte auf Tablets nicht
 * unter das Lesemass faellt.
 * ====================================================================== */

/* Gradkreise auf der paper-Sektion "Kooperationspartner" (13.09.):
 * Volllächen-Deko wie die paper-Sektionen Seite 33 (kv-erkenntnis) und
 * Spenden (kv-spenden-online) — Full-Bleed (background-size: cover).
 * Die Sektion ist mit ~1440×1856 HOCH (kein 2:1-Querformat wie Spenden),
 * daher das HOCHFORMAT-Feld gradkreise-field-paper-full.svg (1:2): bei
 * cover deckt es die volle Sektionsbreite und schneidet nur vertikal
 * beschnitt (rot90-Querfeld würde nur einen schmalen Mittelstreifen
 * zeigen — 14.09. verworfen). Das Feld passt in ALLEN Breakpoints
 * (Hochformat überall); der ≥1920-Override ist entfallen. Scope über
 * .kv-partner (exklusiv, nur Seite /ueber-uns/partner-netzwerk/;
 * Präzedenz .kv-erkenntnis/.kv-ueber-action). Die Sektion enthält KEINE
 * offenen Textboxen (H2 + Intro liegen in der ink-Hero davor) — die
 * opaken paper-25-Karten maskieren die Deko, Ringe bleiben in Fugen und
 * an den Sektionsrändern sichtbar. */
.kv-partner {
	background-image: url("assets/images/gradkreise/gradkreise-field-paper-full.svg");
	background-position: 50% 50%;
	background-repeat: no-repeat;
	background-size: cover;
}

.kv-partner-card__media {
	width: 12rem;
	aspect-ratio: 2 / 1;
	margin-inline: auto;
}

.kv-partner-card__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

/* Fakten-Zeilen als schlanke Tabelle (Praezedenz Impressum, Block-Klasse
 * noBorders): Label-Spalte links, Wert daneben; Label-Zellen
 * mit dunkelblau-75 abgesetzt. Die Tabelle bleibt linksbuendig schmal
 * (width auto) statt die Textspalte zu spreizen. Abstand oberhalb der
 * Tabelle = Block-Gap (1.25rem, 13.09.): margin-block: 0 hatte auch den
 * Flow-Gap zur H3 genullt (Gap unterhalb = 20px zum Folge-Absatz) —
 * auf Wunsch des Auftraggebers gleicher Abstand oben wie unten.
 * Schrift im Standard-Umfang (16.09., Auftrag): kein fixer Kleinwert
 * mehr — die Tabelle erbt die Body-Groesse wie die Karten-Absaetze. */
.kv-partner .wp-block-table {
	margin-block: 1.25rem 0;
}

.kv-partner .wp-block-table table {
	width: auto;
}

.kv-partner .wp-block-table td {
	padding: 2px 0;
	vertical-align: top;
}

.kv-partner .wp-block-table td:first-child {
	color: var(--wp--preset--color--dunkelblau-75);
	padding-inline-end: 1rem;
	white-space: nowrap;
}

/* Stapeln unter 960px: Logo-Box zentriert oben, Text volle Breite
 * (mobile Lesemass kommt vom Viewport, nicht vom Cap). */
@media (max-width: 960px) {
	.kv-partner-card {
		grid-template-columns: minmax(0, 1fr);
		row-gap: 1.5rem;
	}

	.kv-partner-card__media {
		margin-block-end: 0.25rem;
	}
}


/* Speaker-buchen-Galerie (15.09., Figma-Abstimmung; 16.09. zuerst
 * 25/75, danach zurueck auf 33/67): Portraet links 1/3 Spaltenbreite,
 * Quadratformat rechts 2/3 — die rechte Karte beschneidet ihr Bild
 * (object-fit: cover), beide Karten teilen sich eine Hoehe und die
 * Galerie faellt kleiner aus als bei den frueheren 50%-Haelften
 * (columns-default 2er-Formel, hier als Referenz:
 * calc(50% - var(--wp--style--unstable-gallery-gap, 16px) * 0.5)).
 *
 * Gutenberg 23.9 (gallery-v2, dynamischer Renderer) uebertraegt das
 * className-Attribut des Galerie-Blocks NICHT ins Frontend-Markup —
 * die Regeln zielen deshalb direkt auf die (immer gerenderten)
 * Bildklassen der Bilder. Spezifitaet: Zu schlagen sind
 * ZWEI Core-Regeln — (a) .wp-block-gallery.has-nested-images
 * figure.wp-block-image:not(#individual-image) ((1,3,1), 50%-Basis)
 * und (b) die 2er-Regel .wp-block-gallery.has-nested-images
 * .columns-default figure.wp-block-image:not(#individual-image)
 * :first-child:nth-last-child(2) ((1,6,1)) plus ihre Sibling-Variante
 * :first-child:nth-last-child(2) ~ figure... ((1,7,1)) — :not() erbt
 * die ID-Spezifitaet seines Arguments. Die Theme-Selektoren spiegeln
 * daher die 2-Kinder-Waechter und landen bei (1,10,1) bzw. (1,11,1),
 * strikt ueber beiden Core-Regeln und unabhaengig von der
 * wp_head-Ladereihenfolge.
 *
 * Wichtig (live im Flex-Labor gemessen, 16.09.): Core setzt
 * flex-grow:1 auf jede Bild-Figur; mit width landet der Restraum
 * trotzdem im proportionalen Grow (40/60 statt 25/75). Die Figuren
 * brauchen deshalb flex:0 0 auto, damit width wie gewuenscht bindet. */
.wp-block-gallery.has-nested-images.columns-default.is-cropped figure.wp-block-image.kv-speaker-gallery__portrait:not(#individual-image):first-child:nth-last-child(2) {
	width: calc(33.333% - var(--wp--style--unstable-gallery-gap, 1.25rem) * 0.6666666667);
}


/* Land-Regel: Vor dem ~ steht Core-maessig die GENERISCHE erste Figur
 * (das erste Kind ist das Portrait, nicht das Land-Bild), nach dem ~
 * das klassierte Ziel. Gesamt (1,11,1) schlaegt die Core-Sibling-
 * Regel (1,7,1) strikt. */
.wp-block-gallery.has-nested-images.columns-default.is-cropped figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2) ~ figure.wp-block-image.kv-speaker-gallery__land:not(#individual-image) {
	width: calc(66.667% - var(--wp--style--unstable-gallery-gap, 1.25rem) * 0.3333333333);
}


.wp-block-gallery.has-nested-images figure.wp-block-image.kv-speaker-gallery__portrait:not(#individual-image),
.wp-block-gallery.has-nested-images figure.wp-block-image.kv-speaker-gallery__land:not(#individual-image) {
	flex: 0 0 auto;
}

/* 33/67 mit fixierten Breiten (flex:0 0 auto) laesst einen winzigen
 * Restraum (Gap-Abzug: 33.333+66.667=100 minus 2*Gap-Drittel-Residuum);
 * Core-Standard richtet ihn rechtsbuendig aus — justify-content:center
 * zentriert das Paar stattdessen im Sektionsrahmen (Nutzer:
 * "Bilder ggf. zentrieren"). Direkt-Selektor auf die Innengalerie. */
.kv-speaker-gallery {
	justify-content: center;
}


/* 10%-Zuschnitt oben am rechten Bild (16.09., Nutzerwunsch "mind.
 * 10% oben abschneiden"): Box-Verhaeltnis 5/3 statt des natuerlichen
 * 1030/687 (1,499) schneidet exakt 10,1% der Bildhoehe ab — unten
 * bündig (object-position bottom). Unter 600px ist der Zuschnitt aus
 * (Media-Query unten: aspect-ratio auto). */
.wp-block-gallery.has-nested-images.columns-default.is-cropped figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2) ~ figure.wp-block-image.kv-speaker-gallery__land:not(#individual-image) {
	aspect-ratio: 5 / 3;
}

.kv-speaker-gallery__land img {
	object-position: 50% 100%;
}

/* Abgerundete Ecken — Panel-Mass (Figma-Nachtrag 16.09.: groesserer
 * Radius wie bei den Karten, .kv-panel--card nutzt 16px). Diagnose
 * 16.09. (Pixel-Messung): Die Ecken unten wirkten hart, weil das
 * Core-Caption-Overlay (figcaption, bottom:0, Gradient 40% Schwarz,
 * volle Figurenbreite) die unten gerundete Bild-Ecke UEBERMALT —
 * Leaf*0.6 = die dunkelgruene Restfarbe in der Ecke. Deshalb: Figur
 * selbst mit Radius + overflow:hidden clippt ALLE Kinder (Bild,
 * Caption-Gradient, ::before) rund; img und figcaption tragen den
 * Radius zusätzlich explizit. */
.kv-speaker-gallery__portrait,
.kv-speaker-gallery__land {
	border-radius: 16px;
	overflow: hidden;
}

.kv-speaker-gallery__portrait img,
.kv-speaker-gallery__land img {
	border-radius: 16px;
	object-fit: cover;
}

.kv-speaker-gallery__portrait figcaption,
.kv-speaker-gallery__land figcaption {
	border-radius: 0 0 15px 15px;
}


/* Unter 600px stapelt die Galerie (Core-Breakpoint): beide Bilder
 * volle Breite (Nutzerwunsch 16.09.: Norman ebenso breit wie Laura,
 * darf entsprechend hoeher werden), jeweils in ihren natuerlichen
 * Formaten — der 5:3-Zuschnitt der Laura-Box dient nur der
 * nebeneinander-Hoehe und ist im Stapel sinnlos, deshalb
 * aspect-ratio-Reset. Der Core-Gap (0.5em) bleibt zwischen den
 * gestapelten Bildern. Die 2-Kinder-Waechter bleiben im Selektor,
 * damit die Regeln die Core-Formeln auch hier uebersteuern. */
@media (max-width: 599.98px) {
	.wp-block-gallery.has-nested-images.columns-default.is-cropped figure.wp-block-image.kv-speaker-gallery__portrait:not(#individual-image):first-child:nth-last-child(2),
	.wp-block-gallery.has-nested-images.columns-default.is-cropped figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2) ~ figure.wp-block-image.kv-speaker-gallery__land:not(#individual-image) {
		width: 100%;
	}

	.wp-block-gallery.has-nested-images.columns-default.is-cropped figure.wp-block-image:not(#individual-image):first-child:nth-last-child(2) ~ figure.wp-block-image.kv-speaker-gallery__land:not(#individual-image) {
		aspect-ratio: auto;
	}

	.kv-speaker-gallery__portrait img,
	.kv-speaker-gallery__land img {
		height: auto;
		object-position: 50% 50%;
	}
}
