/*
 * pvf-theme — supplemental front-end styles.
 *
 * Most styling lives in theme.json. This file holds what theme.json cannot
 * express (sticky behaviour, hover micro-interactions, aspect-ratio
 * placeholders, stretched-link rows, timeline grid).
 *
 * This file is loaded directly by functions.php — no build step required.
 * The mirror at src/style/index.scss exists for those who want to develop
 * with @wordpress/scripts; if `npm run build` produces build/index.css,
 * functions.php will load that on top to override.
 */

/* -------------------------------------------------------------------------- */
/*  Globals                                                                   */
/* -------------------------------------------------------------------------- */

html {
	scroll-behavior: smooth;
}

:where(a, button, .wp-block-button__link):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 3px;
	border-radius: 2px;
}

:where(h1, h2, h3) {
	text-wrap: balance;
}

/* ========================================================================== */
/*  Flush layout: zero gaps between full-width / wide bands and template parts */
/* ========================================================================== */
/*
 * The design relies on color transitions between bands, not on whitespace
 * gaps. WordPress's constrained-layout system inserts `margin-block-start:
 * var(--wp--style--block-gap)` on every non-first sibling, which produces
 * ~24px of white between every adjacent colour band. We override with broad
 * !important rules so it doesn't matter what wrapper WP puts around things.
 */

/* Every aligned band sits flush against its neighbours. The `:root` prefix
 * adds specificity so this beats anything WordPress-core ships. */
:root .alignfull,
:root .alignwide {
	margin-block-start: 0 !important;
	margin-block-end: 0 !important;
}

/* Top-level template parts and main: header → main → footer all flush. */
:root main.wp-block-group,
:root header.wp-block-template-part,
:root footer.wp-block-template-part,
:root .wp-block-template-part,
body > main.wp-block-group,
body > .wp-block-template-part {
	margin-block-start: 0 !important;
	margin-block-end: 0 !important;
}

/* Main carries no padding of its own — bands handle their own padding. */
main.wp-block-group {
	padding-block-start: 0 !important;
	padding-block-end: 0 !important;
}

/* The footer pattern's outer wrapper. */
.pvf-footer {
	margin-block-start: 0 !important;
}

/* Header should be exactly as tall as its logo + nav row. The Navigation
 * block has a 40-ish-px min-height for touch targets which can make the
 * header feel oversized. */
.site-header,
.site-header .wp-block-navigation,
.site-header .wp-block-navigation__container {
	min-height: 0;
}

/* -------------------------------------------------------------------------- */
/*  Header                                                                    */
/* -------------------------------------------------------------------------- */

.site-header {
	z-index: 50;
	transition: box-shadow 200ms ease, background-color 200ms ease;
}

.site-header[data-scrolled="true"] {
	box-shadow: 0 1px 0 var(--wp--preset--color--border),
		0 4px 12px -8px rgba(11, 21, 48, 0.12);
}

.site-header .wp-block-site-title a {
	text-decoration: none;
}

/* Nav hover (1.7. feedback): instead of a full-height tile, each link gets a
   neon (Accent Soft) highlight rectangle just slightly larger than the text
   itself — like a text marker — on hover/focus and on the current page.
   The link keeps its generous padding as the click/touch target and to define
   the bar height; the highlight is a ::before pseudo-element behind the label.
   Scoped to the closed (inline, desktop) nav so the mobile overlay menu keeps
   a plain colour hover. */
.site-header > .wp-block-group {
	min-height: 3.5rem;
}

.site-header .wp-block-navigation .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	padding: 1.5rem 0.9em;
	border-radius: 0;
	transition: color 160ms ease;
}

.site-header .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item__content {
	position: relative;
	z-index: 0;
}

.site-header .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item__content::before {
	content: "";
	position: absolute;
	z-index: -1;
	top: 50%;
	left: 0.45em;
	right: 0.45em;
	height: calc(1em + 0.55em);
	transform: translateY(-50%) scaleX(0.9);
	background-color: var(--wp--preset--color--accent-soft);
	opacity: 0;
	transition: opacity 160ms ease, transform 160ms ease;
	pointer-events: none;
}

.site-header .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item__content:hover::before,
.site-header .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item__content:focus-visible::before,
.site-header .wp-block-navigation__responsive-container:not(.is-menu-open) .current-menu-item > .wp-block-navigation-item__content::before,
.site-header .wp-block-navigation__responsive-container:not(.is-menu-open) .wp-block-navigation-item__content[aria-current="page"]::before {
	opacity: 1;
	transform: translateY(-50%) scaleX(1);
}

.site-header .wp-block-navigation .wp-block-navigation-item__content:hover,
.site-header .wp-block-navigation .wp-block-navigation-item__content:focus-visible,
.site-header .wp-block-navigation .current-menu-item > .wp-block-navigation-item__content,
.site-header .wp-block-navigation .wp-block-navigation-item__content[aria-current="page"] {
	color: var(--wp--preset--color--contrast);
}

/* Mobile overlay menu: keep a simple accent-soft colour treatment. */
.site-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover,
.site-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:focus-visible {
	background-color: var(--wp--preset--color--accent-soft);
	color: var(--wp--preset--color--contrast);
}

/* -------------------------------------------------------------------------- */
/*  Hero                                                                      */
/* -------------------------------------------------------------------------- */

/* Hero — core/cover block with .pvf-hero className. The wp-block-cover
 * defaults already give us the absolute-positioned background-image
 * span (.wp-block-cover__background) and an inner content container
 * (.wp-block-cover__inner-container); we just centre the content
 * vertically and keep the inner constrained layout. The legacy
 * .wp-block-group selector below stays for any non-cover hero usages
 * (none in seeded content but kept for safety). */
.wp-block-cover.pvf-hero,
.wp-block-group.pvf-hero {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	position: relative;
	overflow: hidden;
}

.pvf-hero .wp-block-cover__inner-container {
	width: 100%;
}

.pvf-hero .pvf-hero__inner {
	width: 100%;
}

.pvf-hero .wp-block-cover__image-background,
.pvf-hero .wp-block-cover__video-background {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 40%;
}

/* When a hero image is present (assets/images/hero.*) the dark navy
 * background is replaced by the photo. We layer a translucent dark overlay
 * on top so the headline + tagline stay legible no matter what the photo
 * looks like. The inner content sits above the overlay via z-index. */
.pvf-hero--has-image::before {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		rgba(11, 21, 48, 0.55) 0,
		rgba(11, 21, 48, 0.35) 100%
	);
	pointer-events: none;
}

.pvf-hero--has-image .pvf-hero__inner {
	position: relative;
	z-index: 1;
}

/* -------------------------------------------------------------------------- */
/*  Image placeholders                                                        */
/*                                                                            */
/*  Solid-colour blocks that stand in for real photography. They keep an      */
/*  aspect ratio so layouts don't shift when the user replaces them with an   */
/*  actual image, and they centre a small "Bildplatzhalter" label.            */
/* -------------------------------------------------------------------------- */

.wp-block-group.pvf-placeholder {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	min-height: 0;
	border-radius: 0;
	overflow: hidden;
}

.pvf-placeholder,
.pvf-placeholder--landscape {
	aspect-ratio: 4 / 3;
}

.pvf-placeholder--portrait {
	aspect-ratio: 4 / 5;
}

.pvf-placeholder--wide {
	aspect-ratio: 16 / 9;
}

.pvf-placeholder__label {
	margin: 0;
	pointer-events: none;
	user-select: none;
}

/* Resolved images from pvf_theme_image() inherit the placeholder shape:
 * same aspect-ratios (via .pvf-placeholder--landscape / --portrait / etc.)
 * and rounded corners. The img inside fills the figure with object-fit:
 * cover so any aspect-ratio mismatch is centre-cropped cleanly. */
.pvf-image {
	margin: 0;
	width: 100%;
	border-radius: 0;
	overflow: hidden;
}

.pvf-image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Featured images rendered straight from get_the_post_thumbnail() — the
 * issue rows on the front page (pvf_issue) and any other place where a
 * bare <img> needs the same rounded-corner / object-fit treatment as a
 * .pvf-image figure. Kept as separate classes so we don't have to wrap
 * every WP-rendered image in a figure. */
.pvf-issue__image {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: 0;
}

/* Native core/image blocks used inside topic-page rows. The seeded
 * content references a bundled SVG placeholder; the editor shows it
 * with a "Replace" toolbar button so editors swap to a real photo via
 * the Media Library. The figure forces a consistent 4:3 aspect ratio +
 * rounded corners regardless of the eventual image's dimensions
 * (object-fit:cover crops cleanly). */
.pvf-row__image {
	margin: 0;
	width: 100%;
	border-radius: 0;
	overflow: hidden;
	background: var(--wp--preset--color--base-2);
	aspect-ratio: 4 / 3;
}

.pvf-row__image--portrait {
	aspect-ratio: 4 / 5;
}

.pvf-row__image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* -------------------------------------------------------------------------- */
/*  Editorial image-text rows (alternating left/right)                        */
/*                                                                            */
/*  Used both on the front-page issue list (.pvf-row--linked = whole row is a */
/*  click target) and inside subpage compositions (decorative only).          */
/* -------------------------------------------------------------------------- */

.pvf-row {
	position: relative;
}

/* Transparent wrapper emitted by src/blocks/issue-rows/render.php. The block's
 * server render calls get_block_wrapper_attributes() which puts WordPress's
 * alignment / className attributes on this <div>; we don't want it to add
 * any visual chrome of its own — the inner .pvf-issue-grid handles layout
 * and the surrounding .pvf-front-issues group handles framing/padding.
 * Earlier this wrapper carried a white background and spacing--70/40/80
 * padding from the days when the block rendered as a full-bleed editorial
 * band; that's no longer the case (the homepage card grid sits inside
 * .pvf-front-issues at the 1320px rail), so any padding here just shows up
 * as visible gutters that prevent the grid from filling its container.
 */
.pvf-issue-rows-section {
	background: none;
	padding: 0;
}

.pvf-row__inner {
	display: grid;
	grid-template-columns: 58fr 42fr;
	gap: var(--wp--preset--spacing--60);
	align-items: center;
}

.pvf-row--image-right .pvf-row__inner {
	grid-template-columns: 42fr 58fr;
}

.pvf-row__image-col,
.pvf-row__text-col {
	min-width: 0;
}

.pvf-row__eyebrow {
	margin: 0 0 var(--wp--preset--spacing--30);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--primary);
}

.pvf-row__subtitle {
	margin: 0;
	font-size: 1.0625rem;
	line-height: 1.5;
	color: var(--wp--preset--color--muted);
	max-width: 36ch;
}

.pvf-issue__image-placeholder {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	background: linear-gradient(
		135deg,
		var(--wp--preset--color--primary-pale),
		var(--wp--preset--color--base-2)
	);
	border-radius: 0;
}

.pvf-row__title {
	max-width: 24ch;
	margin: 0 0 var(--wp--preset--spacing--30);
	font-size: clamp(1.625rem, 3vw, 2.5rem);
	font-weight: 700;
	line-height: 1.1;
	letter-spacing: -0.02em;
}

.pvf-row--linked .pvf-row__title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	transition: color 200ms ease;
}

/* Animated arrow CTA — sits inline at the end of the title, slides forward
 * when the row is hovered or keyboard-focused. Uses display:inline-block so
 * the transform doesn't break the title's line wrapping. The non-breaking
 * space before the arrow keeps it visually attached to the last word but
 * lets the heading wrap naturally above it on narrow screens. */
.pvf-row--linked .pvf-row__title a::after {
	content: "\00a0→";
	display: inline-block;
	transition: transform 250ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.pvf-row--linked:hover .pvf-row__title a::after,
.pvf-row--linked:focus-within .pvf-row__title a::after {
	transform: translateX(6px);
}

.pvf-row--linked .pvf-row__title a::before {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: 0;
	z-index: 1;
}

.pvf-row--linked .pvf-row__image {
	transition: transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
	will-change: transform;
}

.pvf-row--linked:hover .pvf-row__image,
.pvf-row--linked:focus-within .pvf-row__image {
	transform: scale(1.015);
}

/* Brand-accent (Limettengrün) underline on hover/focus. Matches the
   .pvf-media-row a:hover pattern on the Aktuelles list and the lime focus
   outlines used site-wide, so all interactive hover affordances share the
   same visual vocabulary. The title text stays in `contrast` (deep navy)
   for legibility — the lime is doing the "this is interactive" work, not
   colouring the text itself. */
.pvf-row--linked:hover .pvf-row__title a,
.pvf-row--linked:focus-within .pvf-row__title a {
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

.pvf-row--linked .pvf-row__title a:focus-visible {
	outline: none;
}

.pvf-row--linked .pvf-row__title a:focus-visible::before {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 4px;
}

@media (max-width: 781px) {
	.pvf-row .wp-block-columns {
		flex-direction: column;
	}
	.pvf-row .wp-block-column {
		flex-basis: 100% !important;
	}
	.pvf-row--image-right .wp-block-columns {
		flex-direction: column-reverse;
	}

	/* Server-rendered .pvf-row__inner grid: collapse to a single column
	 * with the image always on top, regardless of left/right alternation. */
	.pvf-row__inner,
	.pvf-row--image-right .pvf-row__inner {
		grid-template-columns: 1fr;
		gap: var(--wp--preset--spacing--40);
	}
	.pvf-row--image-right .pvf-row__image-col {
		order: -1;
	}
}

/* -------------------------------------------------------------------------- */
/*  Homepage issue card grid (rendered by pvf_theme_render_issue_rows)        */
/*                                                                            */
/*  2×2 grid of photographic tiles — each tile is a single 3:2 image with    */
/*  eyebrow + title + subtitle floated over the bottom of the photo on a     */
/*  gradient scrim. This is the standard editorial pattern for topic /        */
/*  category indexes (think Le Monde "Rubriques", NYT topic landing pages,   */
/*  IDEO case studies) and it solves two problems the previous stacked-card  */
/*  version had:                                                              */
/*                                                                            */
/*    1. Vertical footprint — stacked photo + text was ~600px tall per       */
/*       card at the 1320px rail; the overlay version is just the 3:2        */
/*       photo height (~427px), so the section is ~30% shorter.              */
/*    2. Visual cohesion — the photo IS the topic instead of "sitting next   */
/*       to" a paragraph, so each tile reads as one unit.                    */
/*                                                                            */
/*  Layout:                                                                  */
/*    - 2 columns from desktop down to tablet (≥640px)                       */
/*    - 1 column at mobile  (<640px)                                          */
/*                                                                            */
/*  Card structure (HTML in inc/render-helpers.php):                          */
/*    <article class="pvf-issue-card">         ← aspect-ratio 3/2 box        */
/*      <img class="pvf-issue-card__image">    ← absolutely positioned       */
/*      <div class="pvf-issue-card__body">     ← pinned to bottom            */
/*        eyebrow / title / subtitle                                          */
/*      </div>                                                                */
/*    </article>                                                              */
/*                                                                            */
/*  Whole card is clickable via an invisible ::before pseudo on the title's */
/*  <a>, but the semantic link target stays the title — screen readers      */
/*  only announce the title text, not the image or subtitle.                 */
/*                                                                            */
/*  Topic pages (Patricia, Wohnen, Wirtschaft, Gesellschaft,                  */
/*  Lebensqualität) are unaffected: they use the .pvf-row pattern in their   */
/*  seed markup, not the .pvf-issue-card class.                              */
/* -------------------------------------------------------------------------- */

.pvf-issue-grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: var(--wp--preset--spacing--50);
}

.pvf-issue-card {
	position: relative;
	overflow: hidden;
	border-radius: 0;
	aspect-ratio: 3 / 2;
	background-color: var(--wp--preset--color--contrast);
	isolation: isolate;
}

.pvf-issue-card__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 700ms cubic-bezier(0.2, 0.8, 0.2, 1);
	will-change: transform;
	z-index: 0;
}

.pvf-issue-card__image--placeholder {
	background: linear-gradient(
		135deg,
		var(--wp--preset--color--primary) 0%,
		var(--wp--preset--color--contrast) 100%
	);
}

/* Bottom-anchored gradient scrim that guarantees ~7:1 contrast between the
 * white overlay text and whatever photo sits behind it. Stops are tuned
 * to leave the top half of the photo unblemished (so the subject reads
 * cleanly) while ramping to ~85% opacity by the bottom edge. */
.pvf-issue-card::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		rgba(11, 21, 48, 0) 0%,
		rgba(11, 21, 48, 0) 35%,
		rgba(11, 21, 48, 0.45) 65%,
		rgba(11, 21, 48, 0.85) 100%
	);
	z-index: 1;
	pointer-events: none;
}

.pvf-issue-card__body {
	position: absolute;
	inset: auto 0 0 0;
	z-index: 2;
	padding: var(--wp--preset--spacing--40);
	color: #fff;
}

.pvf-issue-card__eyebrow {
	margin: 0 0 var(--wp--preset--spacing--20);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}

.pvf-issue-card__title {
	margin: 0 0 var(--wp--preset--spacing--20);
	font-size: clamp(1.25rem, 1.8vw, 1.625rem);
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: -0.01em;
	color: #fff;
	text-wrap: balance;
}

.pvf-issue-card__title a {
	color: inherit;
	text-decoration: none;
}

.pvf-issue-card__title a::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 3;
}

.pvf-issue-card__subtitle {
	margin: 0;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	line-clamp: 2;
	overflow: hidden;
	font-size: 1rem;
	line-height: 1.45;
	color: rgba(255, 255, 255, 0.88);
}

.pvf-issue-card:hover .pvf-issue-card__image,
.pvf-issue-card:focus-within .pvf-issue-card__image {
	transform: scale(1.05);
}

.pvf-issue-card:hover .pvf-issue-card__title a,
.pvf-issue-card:focus-within .pvf-issue-card__title a {
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 4px;
	text-underline-offset: 6px;
}

.pvf-issue-card:focus-within {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 3px;
}

.pvf-issue-card__title a:focus-visible {
	outline: none;
}

@media (max-width: 639px) {
	.pvf-issue-grid {
		grid-template-columns: 1fr;
		gap: var(--wp--preset--spacing--40);
	}

	.pvf-issue-card__body {
		padding: var(--wp--preset--spacing--30);
	}
}

/* -------------------------------------------------------------------------- */
/*  Homepage editorial sections (bio teaser + quote band)                     */
/*                                                                            */
/*  Both sections need their text content flush with the 1320px content      */
/*  rail (so eyebrows/headings line up vertically with the issue grid above  */
/*  and the Aktuelles list below) AND — for paragraph copy — capped at a   */
/*  readable line length so prose doesn't run the full 1320px.               */
/*                                                                            */
/*  Structure:                                                                */
/*   - .pvf-front-bio is an align:wide group (1320px wrapper, centered in    */
/*     viewport). We pin its direct children to the left edge of the         */
/*     wrapper, which IS the rail.                                            */
/*   - .pvf-front-quote is align:full (lime band edge-to-edge) with an       */
/*     inner align:wide .pvf-front-quote__inner that establishes the         */
/*     1320px rail inside the band. We pin THAT inner group's children to    */
/*     its left edge — not the outer band's, which would push them all the   */
/*     way to the viewport edge.                                              */
/*                                                                            */
/*  Quote heading intentionally has no max-width cap — it should wrap on    */
/*  the container the same way patterns/quote-large.php does (which also     */
/*  has no cap and just fills its 1080px contentSize). Capping it to ~22ch  */
/*  earlier forced it to break far earlier than the topic-page quote bands  */
/*  even though both use the same clamp(2rem, 5vw, 4rem) heading size.      */
/* -------------------------------------------------------------------------- */

.pvf-front-bio.is-layout-constrained
	> :where(:not(.alignleft):not(.alignright):not(.alignfull)),
.pvf-front-quote__inner.is-layout-constrained
	> :where(:not(.alignleft):not(.alignright):not(.alignfull)) {
	margin-left: 0 !important;
	margin-right: auto !important;
}

.pvf-front-bio > p {
	max-width: 56ch;
}

.pvf-front-quote__inner > p {
	max-width: 56ch;
}

/* Opt the homepage quote heading out of the global text-wrap: balance set on
   :where(h1, h2, h3). Balance equalises line lengths, which is great for hero
   titles but actively bad for a long two-line block quote — it forced the
   wrap after the second word ("«Sachpolitik braucht / Substanz, keinen Lärm.»")
   instead of letting line 1 fill the rail and break at the natural comma
   ("«Sachpolitik braucht Substanz, / keinen Lärm.»"). The topic-page quote
   in patterns/quote-large.php is short enough to fit on one line, so balance
   never triggered there — which is why this band looked inconsistent with
   the other quote blocks. */
.pvf-front-quote__inner > h2 {
	text-wrap: wrap;
}

/* -------------------------------------------------------------------------- */
/*  Editor-only placeholder cards for the three CPT-driven custom blocks      */
/*                                                                            */
/*  Patricia & her team see a clean labelled card in the page editor where    */
/*  the dynamic timeline / issue rows / Ehrenamt grid appear on the front     */
/*  end. The CSS is shared between front-end and editor (loaded via           */
/*  add_editor_style) but only blocks rendered by edit.js have the            */
/*  .pvf-block-card class, so the styles never leak onto the public site.    */
/* -------------------------------------------------------------------------- */

.pvf-block-card {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: 1.5rem 1.75rem;
	background: var(--wp--preset--color--primary-pale, #eef2fa);
	border: 1px dashed var(--wp--preset--color--primary, #1f3da6);
	border-radius: 0;
	color: var(--wp--preset--color--contrast, #0b1530);
}

.pvf-block-card__eyebrow {
	margin: 0;
	font-size: 0.7rem;
	font-weight: 600;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--primary, #1f3da6);
}

.pvf-block-card__title {
	margin: 0;
	font-size: 1.125rem;
	font-weight: 700;
	letter-spacing: -0.01em;
}

.pvf-block-card__body {
	margin: 0;
	font-size: 0.875rem;
	line-height: 1.5;
	color: var(--wp--preset--color--muted, #4a5878);
	max-width: 60ch;
}

.pvf-block-card__cta {
	margin: 0.25rem 0 0;
	font-size: 0.875rem;
	font-weight: 600;
}

/* -------------------------------------------------------------------------- */
/*  Timeline — scrollytelling stones + sticky image viewer                    */
/*                                                                            */
/*  Two-column layout: stepping-stone path on the left, sticky media panel    */
/*  on the right that cross-fades through one slide per milestone as the      */
/*  reader scrolls. The scroll-spy in functions.php toggles `--active` on     */
/*  the milestone closest to viewport centre AND on the matching slide       */
/*  (paired by data-pvf-timeline-index / data-pvf-timeline-slide), so both    */
/*  sides update in lockstep.                                                 */
/*                                                                            */
/*  Mobile (≤860px) collapses to a single full-width column and hides the    */
/*  sticky viewer — the meander reads on small screens as a plain stack.     */
/* -------------------------------------------------------------------------- */

/* Outer wrapper produced by the pvf/timeline custom block render.php.
 * The block sits below the eyebrow/heading/lead native blocks (which
 * already pad below themselves), so we only add bottom padding here
 * and let WordPress's wide-alignment handle horizontal constraints. */
.pvf-timeline-section {
	padding-block-end: var(--wp--preset--spacing--70);
}

.pvf-ehrenamt-section {
	padding-block-end: var(--wp--preset--spacing--70);
}

.pvf-timeline-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	column-gap: clamp(2rem, 4vw, 4rem);
	align-items: start;
}

.pvf-timeline {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: clamp(1.25rem, 2.4vw, 2rem);
}

/* Markers + connectors are part of the legacy markup; remove them entirely
 * from the visual layer so only the stones remain. */
.pvf-timeline__marker,
.pvf-timeline__milestone--right .pvf-timeline__card::before,
.pvf-timeline__milestone--left .pvf-timeline__card::before {
	display: none !important;
}

/* Each milestone is a full-width flex row holding one stone. Stones drift
 * slightly left/right within the left column so the path still meanders
 * naturally, but stays well clear of the viewer column on the right. */
.pvf-timeline__milestone {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
}

.pvf-timeline__milestone:nth-child(6n + 1) { padding-left: 14%; }
.pvf-timeline__milestone:nth-child(6n + 2) { padding-right: 12%; }
.pvf-timeline__milestone:nth-child(6n + 3) { padding-left: 8%; }
.pvf-timeline__milestone:nth-child(6n + 4) { padding-right: 16%; }
.pvf-timeline__milestone:nth-child(6n + 5) { padding-left: 10%; }
.pvf-timeline__milestone:nth-child(6n + 6) { padding-right: 8%; }

/* Sticky viewer column. Sits on the right at viewport-centre height while
 * the stones scroll past on the left. All slides are stacked absolutely
 * inside the stage; only the active slide is opaque. */
.pvf-timeline-viewer {
	position: sticky;
	top: clamp(4rem, 12vh, 7rem);
	align-self: start;
}

.pvf-timeline-viewer__stage {
	position: relative;
	width: 100%;
	aspect-ratio: 4 / 5;
	overflow: hidden;
	border-radius: 0;
	background: var(--wp--preset--color--base-2);
}

.pvf-timeline-slide {
	position: absolute;
	inset: 0;
	margin: 0;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	padding: clamp(1.5rem, 2.4vw, 2rem);
	opacity: 0;
	transition: opacity 0.45s ease;
	pointer-events: none;
}

.pvf-timeline-slide--active {
	opacity: 1;
	pointer-events: auto;
}

.pvf-timeline-slide__media {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
}

.pvf-timeline-slide--primary-pale .pvf-timeline-slide__media {
	background: var(--wp--preset--color--primary-pale);
}

.pvf-timeline-slide--accent-soft .pvf-timeline-slide__media {
	background: var(--wp--preset--color--accent-soft);
}

.pvf-timeline-slide--base-2 .pvf-timeline-slide__media {
	background: var(--wp--preset--color--base-2);
}

.pvf-timeline-slide__year {
	font-size: clamp(4rem, 9vw, 8rem);
	font-weight: 800;
	letter-spacing: -0.04em;
	line-height: 1;
	color: var(--wp--preset--color--primary);
	font-variant-numeric: tabular-nums;
	opacity: 0.35;
	mix-blend-mode: multiply;
}

/* When a slide has a real featured image (set via the Werdegang post in
 * WP-Admin), the <img> fills the media area completely — no
 * aspect-ratio, no border-radius (the stage already provides it), no
 * faded year overlay needed. Handles both the legacy <figure
 * class="pvf-image"> markup and the modern bare <img> rendered by
 * get_the_post_thumbnail(). */
.pvf-timeline-slide--has-image .pvf-timeline-slide__media {
	background: none;
}

.pvf-timeline-slide--has-image .pvf-timeline-slide__media > img,
.pvf-timeline-slide--has-image .pvf-timeline-slide__media .pvf-image,
.pvf-timeline-slide--has-image .pvf-timeline-slide__media .pvf-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	border-radius: 0;
	aspect-ratio: auto;
}

/* Stones are clearly portrait-shaped with generous interior padding so the
 * year + role + kicker sit comfortably inside the curves. The
 * eight-value border-radius gives each stone its own silhouette; values
 * range from 35–65% so the asymmetry reads at a glance. Five variants
 * cycle, paired with five matching min-heights so stones differ in both
 * shape and proportions — like real pebbles, no two the same. */
.pvf-timeline__card {
	position: relative;
	width: 100%;
	max-width: 19rem;
	min-height: 11rem;
	padding: clamp(2rem, 3vw, 2.75rem) clamp(2.25rem, 3.2vw, 3rem);
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 64% 36% 52% 48% / 44% 56% 38% 62%;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	justify-content: center;
	text-align: center;
	transition:
		background-color 0.35s ease,
		border-color 0.35s ease,
		color 0.35s ease,
		transform 0.35s ease;
}

.pvf-timeline__milestone:nth-child(5n + 2) .pvf-timeline__card {
	border-radius: 38% 62% 44% 56% / 60% 40% 56% 44%;
	min-height: 12.5rem;
}

.pvf-timeline__milestone:nth-child(5n + 3) .pvf-timeline__card {
	border-radius: 50% 50% 35% 65% / 65% 35% 50% 50%;
	min-height: 10rem;
}

.pvf-timeline__milestone:nth-child(5n + 4) .pvf-timeline__card {
	border-radius: 56% 44% 60% 40% / 38% 62% 46% 54%;
	min-height: 13rem;
}

.pvf-timeline__milestone:nth-child(5n + 5) .pvf-timeline__card {
	border-radius: 42% 58% 48% 52% / 56% 44% 64% 36%;
	min-height: 11rem;
}

/* Card content typography. Colors transition with the card so the scroll-spy
 * handoff feels like a single coordinated state change. */
.pvf-timeline__year,
.pvf-timeline__role,
.pvf-timeline__kicker {
	transition: color 0.35s ease;
}

.pvf-timeline__year {
	margin: 0 0 0.25rem !important;
	font-size: clamp(1.875rem, 3.4vw, 2.75rem);
	font-weight: 800;
	letter-spacing: -0.03em;
	line-height: 1;
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--primary);
}

.pvf-timeline__role {
	margin: 0 0 0.5rem !important;
	font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.25;
	color: var(--wp--preset--color--contrast);
}

.pvf-timeline__kicker {
	margin: 0 !important;
	font-size: 0.9375rem;
	line-height: 1.5;
	color: var(--wp--preset--color--muted);
}

/* -------------------------------------------------------------------------- */
/*  Active state — driven by the scroll-spy in functions.php inline script.   */
/*  Whichever milestone sits closest to the viewport centre gets `--active`,  */
/*  which flips the card to lime with dark text. The latest entry starts      */
/*  pre-activated so the section reads correctly before JS runs.              */
/* -------------------------------------------------------------------------- */

.pvf-timeline__milestone--active .pvf-timeline__card {
	background: var(--wp--preset--color--accent-soft);
	border-color: var(--wp--preset--color--accent-soft);
	transform: translateY(-2px);
}

.pvf-timeline__milestone--active .pvf-timeline__year,
.pvf-timeline__milestone--active .pvf-timeline__role {
	color: var(--wp--preset--color--contrast);
}

.pvf-timeline__milestone--active .pvf-timeline__kicker {
	color: var(--wp--preset--color--contrast);
	opacity: 0.78;
}

@media (prefers-reduced-motion: reduce) {
	.pvf-timeline__card,
	.pvf-timeline__year,
	.pvf-timeline__role,
	.pvf-timeline__kicker {
		transition: none;
	}

	.pvf-timeline__milestone--active .pvf-timeline__card {
		transform: none;
	}
}

/* Mobile / narrow desktop: drop the second column, hide the viewer, drop
 * the horizontal offsets so stones stack centred and full width. The
 * meander + scrollytelling don't read on narrow screens anyway. */
@media (max-width: 860px) {
	.pvf-timeline-layout {
		grid-template-columns: 1fr;
	}

	.pvf-timeline-viewer {
		display: none;
	}

	.pvf-timeline {
		gap: 1.25rem;
	}

	.pvf-timeline__milestone,
	.pvf-timeline__milestone:nth-child(6n + 1),
	.pvf-timeline__milestone:nth-child(6n + 2),
	.pvf-timeline__milestone:nth-child(6n + 3),
	.pvf-timeline__milestone:nth-child(6n + 4),
	.pvf-timeline__milestone:nth-child(6n + 5),
	.pvf-timeline__milestone:nth-child(6n + 6) {
		justify-content: center;
		padding-left: 0;
		padding-right: 0;
	}

	.pvf-timeline__card {
		max-width: none;
		width: 100%;
	}
}

/* -------------------------------------------------------------------------- */
/*  Ehrenamt + testimonial cards                                              */
/* -------------------------------------------------------------------------- */

/* -------------------------------------------------------------------------- */
/*  Ehrenamt list                                                             */
/*                                                                            */
/*  Editorial directory of mandates, grouped by category. Reads like a CV     */
/*  section: small uppercase category eyebrow on the left, mandate names      */
/*  stacked on the right, hairline rules separating groups. Intentionally     */
/*  card-less — the old white-tile grid felt like a SaaS dashboard. On        */
/*  narrow screens the two columns collapse to a single column with the       */
/*  category sitting above its mandates.                                      */
/* -------------------------------------------------------------------------- */

.pvf-ehrenamt-list {
	margin: 0;
	padding: 0;
	display: grid;
	border-block: 1px solid var(--wp--preset--color--border);
}

.pvf-ehrenamt-list__row {
	display: grid;
	grid-template-columns: minmax(160px, 220px) minmax(0, 1fr);
	column-gap: clamp(1.5rem, 4vw, 3.5rem);
	padding-block: clamp(1.25rem, 2.5vw, 1.75rem);
}

.pvf-ehrenamt-list__row + .pvf-ehrenamt-list__row {
	border-top: 1px solid var(--wp--preset--color--border);
}

.pvf-ehrenamt-list__category {
	margin: 0;
	padding-top: 0.5rem; /* Optical alignment with the larger mandate text. */
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--primary);
	line-height: 1.4;
}

.pvf-ehrenamt-list__mandates {
	margin: 0;
	display: grid;
	gap: 0.5rem;
}

.pvf-ehrenamt-list__name {
	margin: 0;
	font-size: 1.0625rem;
	font-weight: 600;
	letter-spacing: -0.01em;
	line-height: 1.55;
	color: var(--wp--preset--color--contrast);
	text-wrap: balance;
}

/* Mandate names link to the organisation's website when a URL is set
 * (1.7. feedback). Quiet by default, underline on hover. */
.pvf-ehrenamt-list__name a {
	color: inherit;
	text-decoration: none;
	transition: color 160ms ease;
}

.pvf-ehrenamt-list__name a:hover,
.pvf-ehrenamt-list__name a:focus-visible {
	color: var(--wp--preset--color--primary);
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
}

@media (max-width: 640px) {
	.pvf-ehrenamt-list__row {
		grid-template-columns: 1fr;
		row-gap: 0.5rem;
	}
	.pvf-ehrenamt-list__category {
		padding-top: 0;
	}
}


/*
 * Equal-height + bottom-pinned role label for testimonial cards.
 *
 *   height: 100%             — Pin each card to the grid row's height (= the
 *                              tallest sibling) so all cards share a bottom
 *                              edge. CSS grid's default align-items:stretch
 *                              doesn't kick in reliably here because the grid
 *                              items are themselves flex containers.
 *
 *   justify-content: …       — The block editor declares
 *                              layout.justifyContent:"space-between" on the
 *                              card and WP renders the matching
 *                              .is-content-justification-space-between class,
 *                              but the WP-core CSS rule for that class is
 *                              scoped to .wp-block-buttons only — it is NOT
 *                              applied to wp-block-group. Without this line
 *                              the flex column packs at flex-start and the
 *                              role label sits right under the quote on the
 *                              shorter (metrobasel) card instead of aligning
 *                              with its siblings at the bottom.
 */
.pvf-testimonial {
	height: 100%;
	justify-content: space-between;
	transition: transform 200ms ease;
}

.pvf-testimonial:hover {
	transform: translateY(-1px);
}

/* -------------------------------------------------------------------------- */
/*  Media link rows                                                           */
/* -------------------------------------------------------------------------- */

.pvf-media-row {
	transition: background-color 160ms ease;
}

.pvf-media-row:hover {
	background-color: var(--wp--preset--color--base-2);
}

.pvf-media-row a {
	text-decoration: none;
}

.pvf-media-row a:hover {
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

/* -------------------------------------------------------------------------- */
/*  Footer                                                                    */
/* -------------------------------------------------------------------------- */

/* Topic-page hero band (Gesellschaft, Wirtschaft, Wohnen, Lebensqualität).
 *
 * The pattern files give the wrapper an inline `min-height: 60vh` + symmetric
 * `spacing|80` padding, but pages that were inserted into the DB *before* that
 * change still carry the old short markup (no min-height, padding-bottom
 * spacing|60). Inline styles outrank normal CSS, so the !important rules
 * below defeat the stale inline values and make the section feel like a hero
 * rather than a band.
 *
 * We use `display: grid` (not flex) for vertical centering. Reason: WP's
 * constrained-layout sets `margin-left/right: auto` on every child to center
 * them inside the 1320px content size. In flexbox, any auto cross-axis margin
 * suppresses `align-items: stretch`, which would shrink each child to its
 * content width and then center it — visually indistinguishable from
 * `text-align: center` and definitely not what we want. Grid behaves the way
 * block layout does: items stretch to their grid-area width, max-width caps
 * them at 1320px, and the auto margins consume the leftover free space to
 * center them horizontally. `align-content: center` then centers the implicit
 * rows vertically within `min-height: 60vh`.
 *
 * The `:has(> .wp-block-heading)` scope ensures we only target topic-page
 * heroes — the Patricia page's `bio-intro` pattern uses the same wrapper
 * classes but has a `wp-block-columns` as its direct child, so it does not
 * match and stays untouched. Once existing pages have been re-saved with the
 * new pattern markup, the `!important` lines and the :has() fallback can be
 * dropped — `.pvf-page-hero` alone would suffice. */
.pvf-page-hero,
.has-primary-pale-background-color.alignfull:has(> .wp-block-heading) {
	display: grid;
	grid-template-columns: 1fr;
	align-content: center;
	min-height: 60vh !important;
	padding-bottom: var(--wp--preset--spacing--80) !important;
}

/* WP's constrained-layout sets `margin-left/right: auto !important` on every
 * child to center it within the 1320px content size. With our parent now in
 * grid (or in any flex container), an `auto` cross-axis margin combined with
 * an `auto` width makes the child resolve to its content's max-content width
 * — eyebrow shrinks to ~120px, lead shrinks to its single-line width — then
 * the auto margins center those shrunken blocks. The H1 looks left-aligned
 * only because its max-content exceeds 1320px so it caps + wraps; in reality
 * it's behaving the same way.
 *
 * Forcing `width: 100%` gives each child a definite cross-axis size, which
 * disables the auto-width-with-auto-margin shrinking. max-width: 1320px from
 * the WP rule then caps it, and the auto margins absorb the leftover to
 * center it — exactly the behavior block layout would produce. */
.pvf-page-hero > *,
.has-primary-pale-background-color.alignfull:has(> .wp-block-heading) > * {
	width: 100%;
}

/* Short accent rule sitting above the closing slogan. Reads as a deliberate
 * editorial bar rather than a default <hr>; reuses the accent palette token.
 *
 * The :not() chain mirrors WP core's default separator selector
 * (`.wp-block-separator:not(.is-style-wide):not(.is-style-dots)`) so this rule
 * out-specifies it — otherwise core's 100px / 1px-border defaults win. */
hr.pvf-footer__rule.wp-block-separator:not(.is-style-wide):not(.is-style-dots) {
	width: clamp(56px, 10vw, 112px);
	height: 4px;
	border: 0;
	margin-inline: auto;
	background-color: var(--wp--preset--color--accent);
	opacity: 1;
}

.pvf-footer__slogan {
	text-wrap: nowrap;
}

@media (max-width: 480px) {
	.pvf-footer__slogan {
		text-wrap: balance;
	}
}

.pvf-footer__row {
	gap: clamp(1rem, 4vw, 2.5rem);
}

.pvf-footer__link a {
	color: var(--wp--preset--color--base);
	text-decoration: none;
	transition: color 160ms ease;
}

.pvf-footer__link a:hover {
	color: var(--wp--preset--color--accent);
}

.pvf-footer__social {
	margin: 0;
}

.pvf-footer__social .wp-block-social-link {
	margin: 0;
}

/* Medien page "Patricia auf Social Media." bar: bump the icons beyond the
   built-in "huge" preset (48px) for a stronger presence in the accent band. */
.pvf-medien-social .wp-block-social-links.has-huge-icon-size {
	font-size: clamp(3.25rem, 6vw, 4.5rem);
}

/* Dark footer: lighten the muted meta row + soften the divider so they read
   against the navy background instead of inheriting the light-theme tones. */
.pvf-footer__meta,
.pvf-footer__meta .has-muted-color {
	color: var(--wp--preset--color--base);
}

.pvf-footer__meta a {
	color: var(--wp--preset--color--base);
	text-decoration: none;
}

.pvf-footer__meta a:hover {
	color: var(--wp--preset--color--accent);
}

.pvf-footer hr.wp-block-separator.is-style-wide {
	border-top-color: rgba(255, 255, 255, 0.15);
	color: rgba(255, 255, 255, 0.15);
	background-color: rgba(255, 255, 255, 0.15);
}

/* -------------------------------------------------------------------------- */
/*  Quote break (patterns/quote-break.php)                                     */
/*                                                                            */
/*  A full-bleed magenta band used as a flexible section divider (1.7.        */
/*  feedback: magenta statt Gelb, "zum ausprobieren"). Intentionally NOT      */
/*  placed directly under heroes — it reads as a pause between content        */
/*  sections. White text on the strong magenta keeps contrast high.           */
/* -------------------------------------------------------------------------- */

.pvf-quote-break {
	text-align: center;
}

.pvf-quote-break__text {
	margin-inline: auto;
	max-width: 28ch;
	color: var(--wp--preset--color--base);
	text-wrap: balance;
}

/* -------------------------------------------------------------------------- */
/*  Quote tiles — bold blue cards (patterns/testimonial-cards.php)             */
/*                                                                            */
/*  Stronger, more eye-catching than the old hairline-bordered testimonial    */
/*  list. Each tile is a solid primary-blue card with white text and a large  */
/*  lime opening quotation mark, so the section reads as a deliberate visual   */
/*  break and the words clearly belong to Patricia.                           */
/* -------------------------------------------------------------------------- */

.pvf-quote-tile {
	position: relative;
	height: 100%;
	justify-content: space-between;
	overflow: hidden;
	transition: transform 200ms ease, box-shadow 200ms ease;
}

.pvf-quote-tile::before {
	content: "\201C";
	position: absolute;
	top: 0.4rem;
	right: 1.1rem;
	font-size: 4.5rem;
	line-height: 1;
	font-weight: 800;
	color: var(--wp--preset--color--primary);
	opacity: 0.22;
	pointer-events: none;
}

.pvf-quote-tile:hover {
	transform: translateY(-2px);
	box-shadow: var(--wp--preset--shadow--lg);
}

.pvf-quote-tile__text {
	position: relative;
	z-index: 1;
	color: var(--wp--preset--color--contrast);
}

.pvf-quote-tile__attribution {
	position: relative;
	z-index: 1;
}

.pvf-quote-tile__name {
	position: relative;
	z-index: 1;
	color: var(--wp--preset--color--contrast);
	font-weight: 700;
}

.pvf-quote-tile__role {
	position: relative;
	z-index: 1;
	color: var(--wp--preset--color--primary);
}

/* Keep the legacy .pvf-testimonial selector working for any older saved
 * content that still references it. */
.pvf-testimonial {
	height: 100%;
	justify-content: space-between;
	transition: transform 200ms ease;
}

.pvf-testimonial:hover {
	transform: translateY(-1px);
}

/* -------------------------------------------------------------------------- */
/*  Bigger, more legible homepage issue tiles                                  */
/*                                                                            */
/*  Colleague feedback: "Kacheln: Schrift grösser, moderner besser lesbar."   */
/*  1.7. feedback: "Wichtiger ist der Text als das Bild" — another size step  */
/*  up for all texts, plus a thicker underline (see hover rule below).        */
/* -------------------------------------------------------------------------- */

.pvf-issue-card__body {
	padding: var(--wp--preset--spacing--50);
}

.pvf-issue-card__eyebrow {
	font-size: 1.0625rem;
	letter-spacing: 0.18em;
}

.pvf-issue-card__title {
	font-size: clamp(1.75rem, 2.8vw, 2.5rem);
	line-height: 1.12;
	margin-bottom: var(--wp--preset--spacing--30);
}

.pvf-issue-card__subtitle {
	font-size: 1.25rem;
	line-height: 1.5;
	-webkit-line-clamp: 3;
	line-clamp: 3;
}

@media (max-width: 639px) {
	.pvf-issue-card__body {
		padding: var(--wp--preset--spacing--40);
	}
}

/* -------------------------------------------------------------------------- */
/*  Large inline CTA link (e.g. "Mehr über Patricia →")                       */
/*                                                                            */
/*  Colleague feedback: make the "Mehr über Patricia →" link bigger. A        */
/*  reusable link treatment with an animated arrow, used wherever a section    */
/*  needs a prominent text CTA.                                               */
/* -------------------------------------------------------------------------- */

.pvf-cta-large a {
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	font-size: clamp(1.125rem, 1.6vw, 1.375rem);
	font-weight: 600;
	letter-spacing: -0.01em;
	text-decoration: none;
	color: var(--wp--preset--color--primary);
}

.pvf-cta-large a::after {
	content: "→";
	display: inline-block;
	transition: transform 250ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.pvf-cta-large a:hover {
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

.pvf-cta-large a:hover::after {
	transform: translateX(6px);
}

/* -------------------------------------------------------------------------- */
/*  Prose column                                                               */
/*                                                                            */
/*  Text sections (intro / "Haltung") sit on the SAME wide rail as the image  */
/*  rows so their left edge lines up — no centered, narrower column that reads */
/*  as jagged against the full-width sections above and below. Line length is  */
/*  still capped for readability, but the block stays flush-left.             */
/* -------------------------------------------------------------------------- */

.pvf-prose > * {
	max-width: 68ch;
	margin-right: auto;
}

/* The intro prose groups carry an inline left/right padding (var spacing 40)
   so they keep edge breathing room on mobile, where they fill the full-bleed
   colour band. On desktop that padding double-counts against the theme's
   root padding and pushes the text in by one step, so it no longer lines up
   with the wide image rows below. Drop it from ~tablet up: the block is then
   centred on the same wide rail as the rows and its children stay flush-left. */
@media (min-width: 782px) {
	.pvf-prose {
		padding-left: 0 !important;
		padding-right: 0 !important;
	}
}

/* -------------------------------------------------------------------------- */
/*  Dossier list (Gesellschaft — restyled .pvf-topic)                          */
/*                                                                            */
/*  Colleague feedback: dossier links need bigger type and direct links, and  */
/*  the section needs an intro. Bumps heading + link size and gives the link   */
/*  the same lime hover affordance used site-wide.                            */
/* -------------------------------------------------------------------------- */

.pvf-topic__title {
	font-size: clamp(1.625rem, 2.4vw, 2.125rem) !important;
	line-height: 1.15;
}

.pvf-topic__link a {
	font-size: 1.125rem;
	font-weight: 600;
	text-decoration: none;
	color: var(--wp--preset--color--primary);
}

.pvf-topic__link a:hover {
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

/* Dossiers (Gesellschaft): list left, sticky photo right. */
.pvf-dossiers__media {
	position: sticky;
	top: clamp(4rem, 12vh, 7rem);
}

@media (max-width: 781px) {
	.pvf-dossiers__media {
		position: static;
	}
}

/* "Mehr laden" toggle: JS hides dossiers past the threshold and reveals the
   button. Without JS every dossier shows and the button keeps its `hidden`
   attribute, so the section degrades gracefully. */
.pvf-topic.is-hidden {
	display: none;
}

.pvf-dossier-more[hidden] {
	display: none;
}

.pvf-dossier-more {
	margin-top: var(--wp--preset--spacing--40);
}

.pvf-dossier-more .wp-block-button__link {
	font-size: 1.125rem;
	font-weight: 600;
	color: var(--wp--preset--color--contrast);
	border: 1px solid var(--wp--preset--color--contrast);
	background: transparent;
	border-radius: 999px;
	padding: 0.6em 1.6em;
	cursor: pointer;
	transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease;
}

.pvf-dossier-more .wp-block-button__link:hover,
.pvf-dossier-more .wp-block-button__link:focus-visible {
	color: var(--wp--preset--color--contrast);
	background: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

/* Generic "Mehr laden" toggle (Medien article list). JS hides cards past the
   threshold and reveals the centered button; without JS all cards show and the
   button keeps its server-rendered `hidden` attribute. */
.pvf-media-card.is-hidden {
	display: none;
}

.pvf-loadmore[hidden] {
	display: none;
}

.pvf-loadmore {
	display: flex;
	justify-content: center;
	margin-top: var(--wp--preset--spacing--50);
}

.pvf-loadmore__btn {
	font-size: 1.125rem;
	font-weight: 600;
	color: var(--wp--preset--color--contrast);
	border: 1px solid var(--wp--preset--color--contrast);
	background: transparent;
	border-radius: 999px;
	padding: 0.6em 1.6em;
	cursor: pointer;
	transition: color 150ms ease, background-color 150ms ease, border-color 150ms ease;
}

.pvf-loadmore__btn:hover,
.pvf-loadmore__btn:focus-visible {
	color: var(--wp--preset--color--contrast);
	background: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

/* -------------------------------------------------------------------------- */
/*  Medien — press coverage cards (pvf_theme_render_media_list)                 */
/*                                                                            */
/*  Responsive card grid instead of a flat list: press photo (when set),      */
/*  outlet · date eyebrow and headline. The whole card is clickable via a     */
/*  stretched link on the headline (one link per card = a11y-friendly).       */
/*  Topic chips are intentionally omitted — the taxonomy still drives the      */
/*  per-topic blocks, but a visible tag is redundant on topic pages and       */
/*  noisy on the homepage.                                                     */
/* -------------------------------------------------------------------------- */

.pvf-media-cards {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
	gap: clamp(1.25rem, 2.5vw, 2rem);
}

.pvf-media-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--base);
	border: 1px solid var(--wp--preset--color--border);
	border-radius: 0;
	overflow: hidden;
	transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
}

.pvf-media-card:hover {
	transform: translateY(-3px);
	box-shadow: var(--wp--preset--shadow--lg);
}

.pvf-media-card:focus-within {
	border-color: var(--wp--preset--color--primary);
}

/* Text-only cards (no press photo yet) are filled with the matte accent
 * tone so they read as deliberate, on-brand cards rather than empty boxes
 * with a (dated-looking) top rule. */
.pvf-media-card--text {
	background: var(--wp--preset--color--accent-soft);
	border-color: transparent;
}

.pvf-media-card__media {
	margin: 0;
	aspect-ratio: 3 / 2;
	background: var(--wp--preset--color--base-2);
	overflow: hidden;
}

.pvf-media-card__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 400ms ease;
}

.pvf-media-card:hover .pvf-media-card__media img {
	transform: scale(1.04);
}

.pvf-media-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.65rem;
	padding: clamp(1.25rem, 2vw, 1.75rem);
}

.pvf-media-card__meta {
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--wp--preset--color--primary);
}

.pvf-media-card__title {
	margin: 0;
	font-size: clamp(1.125rem, 1.5vw, 1.375rem);
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: -0.01em;
}

.pvf-media-card__title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

/* Stretched link: makes the whole card clickable without nesting extra
 * interactive elements. */
.pvf-media-card__title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.pvf-media-card:hover .pvf-media-card__title a {
	text-decoration: underline;
	text-decoration-color: var(--wp--preset--color--accent);
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
}

/* Contact section on the Medien page. */
.pvf-contact {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	gap: var(--wp--preset--spacing--60);
	align-items: center;
}

.pvf-contact__photo {
	margin: 0;
	width: 100%;
	aspect-ratio: 4 / 5;
	overflow: hidden;
	background: var(--wp--preset--color--base-2);
}

.pvf-contact__photo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

@media (max-width: 781px) {
	.pvf-contact {
		grid-template-columns: 1fr;
	}
}

/* -------------------------------------------------------------------------- */
/*  Magenta title dot                                                         */
/*                                                                            */
/*  Feedback 1.7.: sentence periods in titles (hero + section headings) are   */
/*  rendered in magenta. Applied via <span class="pvf-dot">.</span> in the    */
/*  seeded heading markup and in the dynamic issue-card title helper.         */
/* -------------------------------------------------------------------------- */

.pvf-dot {
	color: var(--wp--preset--color--magenta);
}
