

/* ---------- TOKENS ---------- */
:root {
	/* Colors mapped to per-site presets (fallbacks are the blue palette) */
	--color-black: var(--wp--preset--color--contrast, #1a1a1a);
	--color-white: var(--wp--preset--color--base, #ffffff);
	--color-accent-dark: var(--wp--preset--color--primary, #35468c);
	--color-accent-light: var(--wp--preset--color--muted, #c5dced);

	/* Font weights (Sora) */
	--font-weight-light: 300;
	--font-weight-regular: 400;
	--font-weight-semibold: 600;
	--font-weight-bold: 700;

	/* Strokes */
	--stroke-button: 1px solid var(--color-black);
	--stroke-line: 2px solid var(--color-black);
	--stroke-accent: 2px solid var(--color-accent-dark);

	/* Arrow icon (used as a mask; color comes from currentColor) */
	/* Masked, so the arrow takes its color from currentColor wherever it is
	   used - dark accent on light rows, white on dark ones. */
	--icon-arrow: url("../images/arrow-right-solid-full.svg");
}

/* ---------- BASE ---------- */

/* The page ends in the footer, so anything below it - a short page, the rubber
   band at the end of a scroll - carries the footer's color instead of white. */
html {
	background-color: var(--wp--preset--color--primary, #35488c);
}
body {
	font-family: var(--wp--preset--font-family--sora, "Sora", sans-serif);
	color: var(--color-black);
	background-color: var(--color-white);
}

/* Cap the whole site at 1920px; full-width backgrounds span this width */
.wp-site-blocks {
	max-width: 120rem; /* 1920px */
	margin-inline: auto;
}

/* Custom block width option: "Kapea" = footer/content width, centered.
   "Leveä" uses the core alignfull + has-global-padding classes. */
.kaupunkivaikutus-width-narrow {
	max-width: var(--wp--style--global--content-size, 80.625rem);
	margin-inline: auto;
}
/* "Leipäteksti" – exactly like "Kaita" above, only wider: the element keeps its
   normal content width (so its left edge lines up with the heading / other
   content) and its inner blocks are narrowed to the 724px measure. */
.kaupunkivaikutus-width-body > :where(:not(.alignfull):not(.alignwide)) {
	max-width: 45.25rem !important; /* 724px */
	margin-left: 0 !important;
	margin-right: auto !important;
}
/* "Kaita" reading width – proportional to the content width (616 : 853).
   The element keeps its normal content width (so its left edge lines up with
   the heading / other content), and its inner blocks are narrowed and pinned
   to the left. The !important beats the constrained layout's margin:auto. */
.kaupunkivaikutus-width-text > :where(:not(.alignfull):not(.alignwide)) {
	max-width: 38.5rem !important; /* 616px reading width */
	margin-left: 0 !important;
	margin-right: auto !important;
}

img {
	max-width: 100%;
	height: auto;
}

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

/* Headings */
.text-h1 { font-weight: 600; font-size: 2.8125rem; line-height: 1.1; } /* 45px */
.text-h2 { font-weight: 400; font-size: 2.5rem; line-height: 1.2; } /* 40px */
.text-h3 { font-weight: 700; font-size: 1.625rem; line-height: 1.2; } /* 26px */
.text-h4 { font-weight: 700; font-size: 1.25rem; line-height: 1.3; } 

.text-subtitle-1 { font-weight: 600; font-size: 1.375rem; line-height: 1.3; } /* 22px */
.text-subtitle-2 { font-weight: 400; font-size: 1rem; line-height: 1.5; } 

/* Default heading elements match the block heading scale (.text-h1..4).
   Element specificity (0,0,1) so the .text-* utility classes still win. */
h1 { font-weight: 600; font-size: 2.8125rem; line-height: 1.1; } /* 45px */
h2 { font-weight: 400; font-size: 2.5rem; line-height: 1.2; } /* 40px */
h3 { font-weight: 700; font-size: 1.625rem; line-height: 1.2; } /* 26px */
h4 { font-weight: 700; font-size: 1.25rem; line-height: 1.3; } 

/* Meta: date and category (accent or black) */
.text-meta,
.is-style-kaupunkivaikutus-meta {
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.1;
	color: var(--color-accent-dark);
}

/* Category tag (end of article) */
.text-category-tag { font-weight: 400; font-size: 1rem; line-height: 1; } /* 16px */
.text-category-tag:hover { text-decoration: underline; }

/* ---------- TEXT SCALE ----------
   Every size in the style guide is written once, as a pair of classes: the
   `text-*` utility the theme's own markup uses, and the `is-style-*` block
   style the editor offers for the same thing. They share one declaration so a
   size can never drift between the two. */

/* Body text */
.text-body-lead,
.is-style-kaupunkivaikutus-body-lead,
/* The Nostolaatikko's own text is a lead-in, not article body, so it reads at
   the Body1 size. Listed here rather than only in the block's template so the
   boxes already written with .text-body follow it too. */
.highlight-box > p,
.highlight-box--light > p,
.highlight-box--plain > p {
	font-weight: 300;
	font-size: 1.5rem; /* Body1 / hero, 24px */
	line-height: 1.5;
}
.text-ingress,
.is-style-kaupunkivaikutus-ingress {
	font-weight: 300;
	font-size: 1.375rem; /* Article opening, 22px */
	line-height: 1.5;
}
.text-body-medium,
.is-style-kaupunkivaikutus-body-medium {
	font-weight: 300;
	font-size: 1.125rem; /* Listings, 18px */
	line-height: 1.5;
}
.text-body,
.is-style-kaupunkivaikutus-body {
	font-weight: 300;
	font-size: 1rem; /* Body2 / article body, 16px */
	line-height: 1.5;
}
.text-body-bold,
.is-style-kaupunkivaikutus-body-bold {
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.5;
}
.text-body-subhead,
.is-style-kaupunkivaikutus-subhead {
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.4;
}

/* Inline link in body text */
.text-body-link {
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.5;
	color: var(--color-accent-dark);
	text-decoration: none;
}
.text-body-link:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
}

/* Reference in body text */
.text-reference {
	font-weight: 400;
	font-size: 1.25rem; /* 20px */
	line-height: 1;
	color: var(--color-accent-dark);
	text-decoration: none;
}
.text-reference:hover {
	text-decoration: underline;
	text-decoration-thickness: 1px;
}

/* Pull quote – body-sized text set off by a thin line in the light accent
   color, indented from it. */
.text-quote,
.is-style-kaupunkivaikutus-quote {
	font-weight: 300;
	font-size: 1rem; /* 16px */
	line-height: 1.5;
	border-left: 2px solid var(--color-accent-light);
	padding-left: 1rem;
	margin-left: 0;
}
.text-sources,
.is-style-kaupunkivaikutus-sources {
	font-weight: 300;
	font-size: 1rem; /* Source list, 16px */
	line-height: 1.3;
}
.text-caption,
.is-style-kaupunkivaikutus-caption {
	font-weight: 300;
	font-size: 1rem;
	line-height: 1.2;
}

/* Footer */
.text-footer {
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.6;
}
.text-footer-link {
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.1;
	color: var(--color-accent-light);
	text-decoration: none;
}
.text-footer-link:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
}

/* Navigation text button */
.text-nav {
	font-weight: 300;
	font-size: 1rem;
	line-height: 1.1;
}
.text-nav-active {
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.1;
}

/* Heading – H1…H4 come from the heading level; these are the two subtitles. */
.text-subtitle-1,
.is-style-kaupunkivaikutus-subtitle-1 {
	font-weight: 600;
	font-size: 1.375rem; /* Subtitle 1, 22px */
	line-height: 1.3;
}
.text-subtitle-2,
.is-style-kaupunkivaikutus-subtitle-2 {
	font-weight: 400;
	font-size: 1rem;
	line-height: 1.5;
}

/* 2px bottom line in the light accent color (light green / light blue per site).
   It is drawn as a pseudo-element rather than a border so it can stop at the
   root padding, lining up with a block whose width option is "Leveä" instead of
   running from screen edge to screen edge. */
.site-header {
	position: relative;
}
.site-header::after {
	content: "";
	position: absolute;
	bottom: 0;
	left: var(--wp--style--root--padding-left, 1rem);
	right: var(--wp--style--root--padding-right, 1rem);
	height: 2px;
	background: var(--color-accent-light);
}

.site-brand {
	gap: 0.6rem;
}
.site-brand .wp-block-site-logo img {
	height: auto;
	max-height: 40px;
	width: auto;
}
.site-brand .wp-block-site-title {
	font-weight: 700;
	line-height: 1.1;
}
.site-brand .wp-block-site-title a {
	color: var(--color-black);
	text-decoration: none;
}
/* Hide the fallback text title once a site logo image is present */
.site-brand:has(.wp-block-site-logo img) .brand-fallback-title {
	display: none;
}

.site-nav-row {
	width: 100%;
}

/* Navigation list (wp_nav_menu output) */
.main-nav {
	width: 100%;
}
.main-menu {
	list-style: none;
	margin: 0;
	padding: 0;
	/* Above the header's accent line, so the active item's underline draws over
	   it instead of disappearing behind it. The stacking has to live here, not
	   on .site-nav-row: a positioned ancestor would become the containing block
	   of the mobile panel, which is absolutely positioned against the header. */
	position: relative;
	z-index: 1;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1.75rem;
}
.main-menu a {
	font-family: var(--wp--preset--font-family--sora, "Sora", sans-serif);
	font-weight: 300;
	font-size: 1rem;
	line-height: 1.1;
	text-align: center;
	color: var(--color-black);
	text-decoration: none;
}
/* 14px, not 15: at 15 the underline landed one pixel below the header's accent
   line; this lifts it so the two overlap. */
.main-menu a:hover,
.main-menu a:focus-visible {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 14px;
}
/* Current page – bold + underline */
.main-menu .current-menu-item > a,
.main-menu .current_page_item > a {
	font-weight: 700;
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 14px;
}

/* Hamburger toggle – hidden on desktop */
.nav-toggle {
	display: none;
	background: none;
	border: none;
	padding: 0.5rem;
	cursor: pointer;
	color: var(--color-black);
}
.nav-toggle__bars {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	width: 26px;
	height: 18px;
}
.nav-toggle__bar {
	width: 100%;
	height: 2px;
	background: currentColor;
	transition: transform 0.25s ease, opacity 0.15s ease;
}
/* Open: the outer bars meet in the middle as a cross, the middle one fades. */
.main-nav.is-open .nav-toggle__bar:nth-child(1) {
	transform: translateY(8px) rotate(45deg);
}
.main-nav.is-open .nav-toggle__bar:nth-child(2) {
	opacity: 0;
}
.main-nav.is-open .nav-toggle__bar:nth-child(3) {
	transform: translateY(-8px) rotate(-45deg);
}

/* Mobile: show toggle, collapse menu until opened */
@media (max-width: 768px) {
	/* The header's own constrained layout stacks the brand above the nav row.
	   On mobile they belong on one line, so the header becomes the flex row and
	   the open menu drops out of the flow into a panel underneath it. */
	.site-header {
		position: relative;
		display: flex;
		flex-wrap: nowrap;
		align-items: center;
		justify-content: space-between;
		gap: 0.75rem;
	}
	/* The constrained layout gives every header child `margin-inline: auto`, and
	   core sets it with !important (.is-layout-constrained > :where(...)). In a
	   flex row those auto margins eat the free space and push the brand off the
	   left edge, so they have to be overridden in kind. */
	.site-header > * {
		margin-left: 0 !important;
		margin-right: 0 !important;
	}
	.site-brand {
		flex: 0 1 auto;
	}
	.site-nav-row,
	.main-nav {
		flex: 0 0 auto;
		width: auto;
	}
	.nav-toggle {
		display: inline-flex;
		/* Lifts the button off the header's bottom edge; mobile only. */
		margin-block-end: 15px;
	}
	/* Each site's logo has its own proportions, so the mobile size is given per
	   site rather than through a shared max-height. */
	.kaupunkivaikutus-site-blue .site-brand .wp-block-site-logo img {
		width: 241px;
		height: 24px;
		max-height: none;
	}
	.kaupunkivaikutus-site-green .site-brand .wp-block-site-logo img {
		width: 219px;
		height: 34px;
		max-height: none;
	}
	/* The panel stays in the layout so it can animate; visibility (not display)
	   keeps it out of the tab order and off the screen reader until it opens. */
	.main-menu {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		justify-content: flex-start;
		gap: 0.25rem;
		position: absolute;
		top: 100%;
		/* Stops at the root padding, so white shows on both sides exactly like
		   the first wide block on the front page (.highlight-box), whose inner
		   padding this matches too. */
		left: var(--wp--style--root--padding-left, 1rem);
		right: var(--wp--style--root--padding-right, 1rem);
		z-index: 20;
		padding: clamp(1.5rem, 4vw, 3rem);
		background: var(--color-accent-light);
		opacity: 0;
		visibility: hidden;
		transform: translateY(-0.5rem);
		transition: opacity 0.25s ease, transform 0.25s ease,
			visibility 0s linear 0.25s;
	}
	.main-nav.is-open .main-menu {
		opacity: 1;
		visibility: visible;
		transform: none;
		transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s;
	}
	/* Bigger tap targets and a tighter underline offset in the vertical menu */
	.main-menu a {
		display: block;
		width: 100%;
		padding: 0.6rem 0;
	}
	.main-menu a:hover,
	.main-menu a:focus-visible,
	.main-menu .current-menu-item > a,
	.main-menu .current_page_item > a {
		text-underline-offset: 4px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.main-menu,
	.main-nav.is-open .main-menu,
	.nav-toggle__bar {
		transition: none;
	}
}

/* Visually hidden but available to screen readers */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* Skip link – visible only on keyboard focus */
.skip-link.screen-reader-text {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 100000;
	padding: 0.75rem 1.25rem;
	background: var(--color-black);
	color: var(--color-white);
	text-decoration: none;
}
.skip-link.screen-reader-text:focus {
	left: 0;
}

/* Color variants (per-site: blue on one site, green on the other), chosen from
   the block's Asetukset panel. The background sits behind the text column
   only, not the media. Dark is also the fallback for blocks saved before the
   variant setting existed, so no instance renders on a bare white column.
   The is-style-* selectors are legacy content from the old block styles. */
.media-text .text-col {
	background-color: var(--color-accent-dark);
	color: var(--color-white);
}
.media-text .text-col :where(h1, h2, h3, h4, h5, h6),
.media-text .text-col .text-meta {
	color: var(--color-white);
}
.media-text.feature-light .text-col {
	background-color: var(--color-accent-light);
	color: var(--color-black);
}
.media-text.feature-light .text-col :where(h1, h2, h3, h4, h5, h6),
.media-text.feature-light .text-col .text-meta {
	color: var(--color-black);
}

/* Layout: media ~2/5, small gap, text ~3/5 (not 50/50) */
.media-text > .wp-block-columns {
	/* The row declares its own flex layout. Core supplies one through the
	   is-layout-flex class, but only for columns that went through the block
	   renderer; the listing rows are written by hand in
	   latest-posts/render.php, and without this the columns stack like on
	   mobile. */
	display: flex;
	flex-wrap: nowrap;
	align-items: stretch;
	gap: 0.75rem;
	margin: 0;
}
/* 40:60, image to text, in every listing. The selector is deliberately long:
   core ships
     @media (min-width: 782px) .wp-block-columns:not(.is-not-stacked-on-mobile) > .wp-block-column { flex: 1 1 0 }
   which outweighs a two-class selector, so template-rendered rows ended up 1:1
   while the rows the block writes itself (core's columns CSS is not loaded for
   those) kept the theme's ratio. min-width: 0 lets the text column shrink to
   its share instead of holding on to its min-content width. */
.media-text > .wp-block-columns > .wp-block-column.media-col,
.media-text > .wp-block-columns > .wp-block-column.text-col {
	/* border-box, so the text column's own padding comes out of its 60 % share
	   instead of being added on top of it. */
	box-sizing: border-box;
	min-width: 0;
}
/* The share is a percentage of the row, not a grow factor: with flex-basis 0
   the text column's own padding is taken off the top before the split, which
   left the image at 37 % instead of 40 %. Half the 0.75rem gap comes off each
   side so the two still fit on one line. */
.media-text > .wp-block-columns > .wp-block-column.media-col {
	flex: 0 0 calc(40% - 0.375rem);
	padding: 0;
}
.media-text > .wp-block-columns > .wp-block-column.text-col {
	flex: 0 0 calc(60% - 0.375rem);
}
/* A 16:9 video needs more width than a 3:2 image to read at the same height,
   so the shares swap when the media is a video or a YouTube embed: 60 % media,
   40 % text. Matched with :has() on the media column's own first block, so the
   rows saved before this rule follow it too, in both the automatic and the
   hand-built variant. Desktop only – stacked, the basis would apply to the
   height. */
@media (min-width: 769px) {
	.media-text:has(> .wp-block-columns > .media-col > .wp-block-embed) > .wp-block-columns > .wp-block-column.media-col,
	.media-text:has(> .wp-block-columns > .media-col > .wp-block-video) > .wp-block-columns > .wp-block-column.media-col {
		flex: 0 0 calc(60% - 0.375rem);
	}
	.media-text:has(> .wp-block-columns > .media-col > .wp-block-embed) > .wp-block-columns > .wp-block-column.text-col,
	.media-text:has(> .wp-block-columns > .media-col > .wp-block-video) > .wp-block-columns > .wp-block-column.text-col {
		flex: 0 0 calc(40% - 0.375rem);
	}
}
/* The image keeps its exact aspect ratio (3:2 / 4:3) and defines the height;
   the colored text area stretches to match the image (align-items: stretch). */
.media-text .media-col > .wp-block-image,
.media-text .media-col > .wp-block-post-featured-image,
.media-text .media-col > .wp-block-video,
.media-text .media-col > .wp-block-embed,
/* The caption band belongs to the image above it, so it must not pick up the
   column's flow gap – it sits flush against the image. */
.media-text .media-col > .kaupunkivaikutus-caption-band {
	margin: 0;
}
.media-text .media-col > .wp-block-post-featured-image img {
	aspect-ratio: 3 / 2;
}
/* The image fills the row's height. Its 3:2 ratio sets the row height whenever
   the image is the taller side; when the text is longer, the image grows with
   it and crops, so the colored text area never runs past the picture. */
.media-text .media-col {
	display: flex;
	flex-direction: column;
}
.media-text .media-col > .wp-block-image,
.media-text .media-col > .wp-block-post-featured-image,
.media-text .media-col > .wp-block-video {
	flex: 1 1 auto;
	min-height: 0;
}
.media-text .media-col img,
.media-text .media-col video {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.media-text .text-col {
	padding: clamp(1.5rem, 4vw, 3rem);
	display: flex;
	flex-direction: column;
	justify-content: space-evenly;
	gap: 1rem;
}

/* "Valkoinen (ei taustaa)": the text sits straight on the page, so the column
   drops its background and its padding on the outer side. */
.media-text.media-text--plain .text-col {
	background-color: transparent;
	color: inherit;
	padding-block: 0;
	padding-inline-end: 0;
}
.media-text.media-text--plain .text-col :where(h1, h2, h3, h4, h5, h6),
.media-text.media-text--plain .text-col .text-meta,
.media-text.media-text--plain .text-col .wp-block-post-title a {
	color: var(--color-black);
}
.media-text.media-text--plain .text-col .wp-block-read-more {
	color: var(--color-accent-dark);
}

/* One vertical rhythm for every listing: the row's text column, the grid card
   and the Media ja teksti block all space title, meta, ingress and arrow the
   same way. The children's own margins are cleared so only the gap counts. */
.media-text .text-col > * {
	margin-top: 0;
	margin-bottom: 0;
}
/* No auto margin on the arrow: it would swallow the column's free space and
   leave justify-content: space-evenly above with nothing to distribute. */
/* The listing ingress runs at the middle body size (18px). The listings build
   their own markup, so they cannot pick the style in the editor - the size is
   applied here, and matches .text-body-medium / .is-style-kaupunkivaikutus-body-medium. */
.media-text .text-col .wp-block-post-excerpt,
.media-text .text-col .wp-block-post-excerpt p,
.media-text .text-col .text-body {
	font-size: 1.125rem;
	line-height: 1.5;
}

/* Media position: right (default is left) */
.media-text.media-right > .wp-block-columns {
	flex-direction: row-reverse;
}

/* Image aspect ratio: driven by the caption toggle. Without a caption the
   main image is 3:2; with a caption it is 4:3. Scoped to the media column's
   own image so the caption logo is unaffected. */
.media-text .media-col > .wp-block-image img { aspect-ratio: 3 / 2; }
.media-text.has-caption .media-col > .wp-block-image img { aspect-ratio: 4 / 3; }

/* Video and YouTube embed fill the media column exactly like the image does.
   The embed keeps 16:9 (the video's own ratio) instead of being cropped. */
.media-text .media-col > .wp-block-video video { aspect-ratio: 3 / 2; }
.media-text.has-caption .media-col > .wp-block-video video { aspect-ratio: 4 / 3; }
.media-text .media-col > .wp-block-embed .wp-block-embed__wrapper {
	position: relative;
	aspect-ratio: 16 / 9;
}
.media-text .media-col > .wp-block-embed .wp-block-embed__wrapper iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}
.media-text .media-col > .wp-block-embed figcaption {
	margin-inline: clamp(1rem, 3vw, 1.5rem);
}

/* Optional caption band under the media (two lines + logo).
   Hidden unless the caption toggle is on. */
.media-text:not(.has-caption) .media-caption {
	display: none;
}
/* The standalone "Nostokuvan kuvateksti" block brings its own band, so it is
   never hidden by the toggle above (listing templates have no such toggle). */
.kaupunkivaikutus-caption-band .media-caption,
.media-text .kaupunkivaikutus-caption-band .media-caption {
	display: flex;
}
/* Two lines on the left, logo on the right, both vertically centred. */
.media-caption {
	background-color: var(--color-accent-light);
	color: var(--color-black);
	padding: 1.25rem clamp(1rem, 3vw, 1.5rem);
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	flex-wrap: nowrap;
}
.media-caption > .wp-block-group:not(.media-caption-logo) {
	min-width: 0;
}
.media-caption p:first-child {
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.4;
	margin: 0;
} /* 16px */
.media-caption p + p {
	font-weight: 400;
	font-size: 1rem;
	line-height: 1.4;
	margin: 0.15rem 0 0;
} /* 16px */
.media-caption .media-caption-logo {
	flex: 0 0 auto;
	margin: 0;
}
.media-caption .media-caption-logo img {
	max-height: 40px;
	max-width: 8rem;
	width: auto;
	object-fit: contain;
}

/* Meta line (date – category) */
.media-text .text-meta {
	margin: 0;
}

/* Accessible arrow link: visible arrow is decorative, link text for screen readers */
.arrow-link a {
	display: inline-flex;
	align-items: center;
	color: inherit;
	text-decoration: none;
}
.arrow-link a::after {
	/* The same masked arrow the listing rows use, so every "image beside text"
	   row ends in an identical link, not a text glyph. */
	content: "";
	flex-shrink: 0;
	width: 1.0625rem;
	height: 1.0625rem;
	background-color: currentColor;
	-webkit-mask: var(--icon-arrow) no-repeat center / contain;
	mask: var(--icon-arrow) no-repeat center / contain;
	transition: transform 0.15s ease;
}
.arrow-link a:hover::after {
	transform: translateX(4px);
}

/* Mobile: stack, and optionally show text first */
@media (max-width: 768px) {
	.media-text > .wp-block-columns {
		flex-direction: column;
	}
	/* Stacked, the percentage basis would apply to height instead of width. */
	.media-text > .wp-block-columns > .wp-block-column.media-col,
	.media-text > .wp-block-columns > .wp-block-column.text-col {
		flex: 0 0 auto;
	}
	.media-text.mobile-text-first > .wp-block-columns {
		flex-direction: column-reverse;
	}
}

/* Block heading (e.g. "Hankkeen julkaisut") above the grid */
.post-grid__heading {
	text-align: center;
	margin: 0 0 2rem;
}

/* The card list is a plain <ul>: drop the browser's default list padding so
   the cards start at the block's own left edge – otherwise a wide grid ends
   up 40px narrower than the other wide blocks. */
.post-grid .wp-block-post-template {
	list-style: none;
	margin: 0;
	padding: 0;
}

/* Grid of cards – equal columns, cells never overflow (minmax 0) so long
   titles wrap instead of overlapping the next card. */
.post-grid .wp-block-post-template.is-layout-grid {
	grid-template-columns: repeat(var(--post-grid-columns, 3), minmax(0, 1fr));
	gap: 1.5rem;
	align-items: stretch;
}

/* Each card is a vertical flow; content wraps normally. Per-site light
   background (blue / green); the image is flush at the top and the text
   content is padded. */
.post-grid .wp-block-post-template > li {
	min-width: 0;
	display: flex;
	flex-direction: column;
	background: var(--color-accent-light);
	color: var(--color-black);
}
.post-grid .wp-block-post-template > li > *:not(.wp-block-post-featured-image) {
	padding-left: 1.5rem;
	padding-right: 1.5rem;
}
.post-grid .wp-block-post-template > li > .post-meta {
	padding-top: 1.5rem;
}
.post-grid .wp-block-post-template > li > *:last-child {
	padding-bottom: 1.5rem;
}
/* Card color, chosen per block in Asetukset ("Korttien väri"). Light is the
   default; dark is the accent color; plain drops the background altogether so
   the text sits directly on the page (the green site's news listing). */
.post-grid--dark .wp-block-post-template > li {
	background: var(--color-accent-dark);
	color: var(--color-white);
}
.post-grid--plain .wp-block-post-template > li {
	background: none;
	color: inherit;
}
.post-grid--plain .wp-block-post-template > li > *:not(.wp-block-post-featured-image) {
	padding-left: 0;
	padding-right: 0;
}
.post-grid--plain .wp-block-post-template > li > *:last-child {
	padding-bottom: 0;
}

.post-grid .wp-block-post-title {
	overflow-wrap: break-word;
	word-break: normal;
	hyphens: auto;
	margin: 0.5rem 0;
}
.post-grid .wp-block-post-title a {
	color: var(--color-black);
	text-decoration: none;
}
.post-grid .wp-block-post-title a:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
}
.post-grid .wp-block-post-featured-image {
	/* display:flex keeps the figure exactly as tall as the image; without it a
	   text line's worth of space crept in under the picture. */
	display: flex;
	margin: 0 0 1rem;
}
.post-grid .wp-block-post-featured-image img {
	aspect-ratio: 3 / 2;
	width: 100%;
	height: auto;
	object-fit: cover;
}

/* Meta line: date – category */
.post-grid .post-meta {
	gap: 0.35rem;
	margin: 0;
}
.post-grid .post-meta .wp-block-post-terms::before {
	content: "\2013\00a0"; /* – */
}
.post-grid .post-meta .wp-block-post-date,
.post-grid .post-meta .wp-block-post-terms,
.post-grid .post-meta .wp-block-post-terms a {
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.1;
	color: var(--color-accent-dark);
}
/* Category link: underline only on hover */
.post-grid .post-meta .wp-block-post-terms a {
	text-decoration: none;
}
.post-grid .post-meta .wp-block-post-terms a:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

/* Dark cards: the title and the meta line turn white. This has to come after
   the generic title and meta colors above - the selectors weigh the same, so
   source order decides, and earlier the black title and accent meta won. */
.post-grid--dark .wp-block-post-title a,
.post-grid--dark .post-meta .wp-block-post-date,
.post-grid--dark .post-meta .wp-block-post-terms,
.post-grid--dark .post-meta .wp-block-post-terms a {
	color: var(--color-white);
}

/* "See all" link – centered, tertiary style with a trailing arrow */
.see-all-link {
	text-align: center;
	margin-top: 2rem;
}
.see-all-link a {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	color: var(--color-accent-dark);
	font-weight: 600;
	font-size: 1.25rem; /* 20px */
	text-decoration: none;
}
.see-all-link a::after {
	content: "";
	flex-shrink: 0;
	width: 1.0625rem; /* 17px */
	height: 1.0625rem; /* 17px */
	background-color: currentColor;
	-webkit-mask: var(--icon-arrow) no-repeat center / contain;
	mask: var(--icon-arrow) no-repeat center / contain;
}
.see-all-link a:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

@media (max-width: 900px) {
	/* One card per row: the image runs the full width with the text below it,
	   the same shape as a "Media ja teksti" row on a phone. */
	.post-grid .wp-block-post-template.is-layout-grid {
		--post-grid-columns: 1;
	}

	/* "Määrä mobiilissa": show only the first N cards on narrow screens. */
	.post-grid[data-mobile-count="1"] .wp-block-post-template > li:nth-child(n + 2),
	.post-grid[data-mobile-count="2"] .wp-block-post-template > li:nth-child(n + 3),
	.post-grid[data-mobile-count="3"] .wp-block-post-template > li:nth-child(n + 4),
	.post-grid[data-mobile-count="4"] .wp-block-post-template > li:nth-child(n + 5) {
		display: none;
	}
}

/* The listing at the end of an article is as wide as the front page's news
   grid. There the block sits inside the post content, and WordPress cancels the
   break-out for an alignfull block in a nested has-global-padding container, so
   it stops at the root padding. In a single template the same block is a direct
   child of <main> and would pull itself out to the window edge instead, which
   reads as too wide next to the article. Desktop only – on a phone the cards
   are meant to run edge to edge (see the mobile rules below). */
@media (min-width: 769px) {
	.single .post-grid.alignfull {
		margin-left: 0;
		margin-right: 0;
	}
}

/* Inside post content the listing sits in a container that already carries the
   root padding, and WordPress keeps an alignfull child's own padding on top of
   it. Zeroing it lines the rows up with the same listing rendered straight from
   a template (Ajankohtaista). */
.entry-content .article-list.alignfull.has-global-padding {
	padding-left: 0;
	padding-right: 0;
}

.archive-title {
	margin: 0 0 2rem;
}

/* Post template as a plain vertical list of media-text rows */
.article-list .wp-block-post-template {
	list-style: none;
	margin: 0;
	padding: 0;
}
/* Rows stand 1.5rem apart. The template listings get that from core's flow
   layout; the block writes its rows itself, so it needs the rule too. */
.article-list .media-text + .media-text {
	margin-top: 1.5rem;
}

/* Title link follows the text-column color (white on dark, black on light) */
.media-text .text-col .wp-block-post-title a {
	color: inherit;
	text-decoration: none;
}
.media-text .text-col .wp-block-post-title a:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
}

/* Read more link inside a listing row: only the arrow shows. The label stays in
   the markup and in the accessibility tree - it is the link's name - but is
   sized to nothing so the row reads as a bare arrow. */
.media-text .text-col .wp-block-read-more {
	display: inline-flex;
	align-items: center;
	gap: 0;
	color: var(--color-accent-dark);
	font-weight: 600;
	font-size: 0;
	text-decoration: none;
	/* The text column is a flex column, so the link would stretch across the
	   whole row and leave a wide invisible click target next to the arrow. */
	align-self: flex-start;
}
.media-text .text-col .wp-block-read-more:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}
/* Feature-dark listing: meta, terms and the arrow turn white for contrast. Kept
   after the rules above, which weigh the same and would otherwise win on order
   and leave a dark blue arrow on a dark blue column. */
.feature-dark .text-col .wp-block-post-date,
.feature-dark .text-col .wp-block-post-terms,
.feature-dark .text-col .wp-block-post-terms a,
.feature-dark .text-col .wp-block-read-more {
	color: var(--color-white);
}
.media-text .text-col .wp-block-read-more::after {
	content: "";
	flex-shrink: 0;
	width: 1.0625rem;
	height: 1.0625rem;
	background-color: currentColor;
	-webkit-mask: var(--icon-arrow) no-repeat center / contain;
	mask: var(--icon-arrow) no-repeat center / contain;
}

/* Pagination – spacing and current page emphasis */
.article-list .wp-block-query-pagination {
	margin-top: 2.5rem;
	gap: 0.75rem;
}
.article-list .wp-block-query-pagination [aria-current="page"] {
	font-weight: 700;
	text-decoration: underline;
	text-underline-offset: 4px;
}

/* Article body defaults to the 724px measure, handled the same way as the
   "Kaita" and "Leipäteksti" width options: the content area keeps its normal
   width so the text's left edge lines up with the title and meta above, and
   only the blocks inside are narrowed. The core constrained layout centres
   with its own !important margins, so this has to out-specify them. Scoped to
   `body.single` so pages, which centre their content, keep the full width. */
.single .entry-content.is-layout-constrained
	> :where(:not(.alignleft):not(.alignright):not(.alignwide):not(.alignfull)) {
	max-width: 45.25rem !important; /* 724px */
	margin-left: 0 !important;
	margin-right: auto !important;
}

/* Air between the article's title and the meta line below it. */
.single main > .wp-block-post-title {
	margin-bottom: 2rem;
}

/* The featured image belongs to the article body. A block template cannot nest
   it inside post-content, so it is given the same measure and the same left
   edge as the blocks in there - it reads as the article's first element. */
.single main > .wp-block-post-featured-image {
	max-width: 45.25rem; /* 724px, the article measure */
	/* Left edge of the content column: the constrained container centres its
	   1290px measure first, and the article's blocks start there. Core centres
	   with !important margins, so this has to answer in kind. */
	margin-left: max(0px, (100% - var(--wp--style--global--content-size, 80.625rem)) / 2) !important;
	margin-right: auto !important;
}

/* Meta line (date – category), used in the article header and card grid */
.post-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.35rem;
	margin: 0.5rem 0 0;
}
.post-meta .wp-block-post-date,
.post-meta .wp-block-post-terms,
.post-meta .wp-block-post-terms a {
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.1;
	color: var(--color-accent-dark);
}
.post-meta .wp-block-post-terms::before {
	content: "\2013\00a0"; /* – */
}
.post-meta .wp-block-post-terms a {
	text-decoration: none;
}
.post-meta .wp-block-post-terms a:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}
/* Author names sit on their own line under the date/term row */
.post-meta .kaupunkivaikutus-authors {
	flex-basis: 100%;
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.3;
	color: var(--color-accent-dark);
}

/* Person (Henkilö): round avatar + name/role/org */
.person {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: 1.5rem;
	margin: 1.5rem 0;
}
.person .person-avatar {
	margin: 0;
	flex-shrink: 0;
}
.person .person-avatar img,
.person .person-avatar .person-placeholder {
	width: 96px;
	height: 96px;
	border-radius: 50%;
	object-fit: cover;
	display: block;
}
.person .person-info {
	min-width: 0;
}
.person .person-name {
	font-weight: 700;
	margin: 0;
}
.person .person-role,
.person .person-org {
	margin: 0;
}

/* Share block (Jaa artikkeli) */
.share-block {
	margin: 2.5rem 0 0;
}
.share-block__title {
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.4;
	margin: 0 0 0.75rem;
}
.share-block__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}
.share-block__list a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	background: var(--color-accent-dark);
	color: var(--color-white);
}
.share-block__list a:hover,
.share-block__list a:focus-visible {
	background: var(--color-black);
}
.share-block__list svg {
	width: 20px;
	height: 20px;
	fill: currentColor;
}

/* Article tags (post_tag) – light chips, shown only when tags exist */
.article-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem;
	margin: 2.5rem 0 0;
}
.article-tags a {
	background: var(--color-accent-light);
	color: var(--color-black);
	padding: 0.4rem 0.9rem;
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.1;
	text-decoration: none;
}
.article-tags a:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

/* PDF download link. Uses the same arrow affordance as "Lue lisää". */
.kaupunkivaikutus-pdf-download {
	margin: 2rem 0 0;
}
.kaupunkivaikutus-pdf-download .download-pdf {
	font-weight: 600;
	color: var(--color-accent-dark);
}

/* References: numbered citations, then book references. */
.kaupunkivaikutus-references {
	margin: 2.5rem 0 0;
	max-width: 38.5rem; /* reading width, same as .kaupunkivaikutus-width-text */
}
.kaupunkivaikutus-references__heading {
	margin: 0 0 1rem;
}
.kaupunkivaikutus-references .citations,
.kaupunkivaikutus-references .citations li,
.kaupunkivaikutus-references .book-references li {
	margin-bottom: 0.75rem;
	line-height: 1.5;
}
.kaupunkivaikutus-references .book-references {
	margin: 0 0 1.5rem;
	padding: 1rem 0 0;
	list-style: none;
	border-top: var(--stroke-button);
}
.kaupunkivaikutus-references .book-reference__author {
	font-weight: 600;
}

/* Authors (ACF user field): photo + name, title, bio. */
.kaupunkivaikutus-authors {
	margin: 3rem 0 0;
}
.kaupunkivaikutus-authors__heading {
	margin: 0 0 1.5rem;
}
.kaupunkivaikutus-authors__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 2rem;
}
.kaupunkivaikutus-author {
	display: grid;
	grid-template-columns: 8rem 1fr;
	gap: 1.5rem;
	align-items: start;
	max-width: 44rem;
}
.kaupunkivaikutus-author:has(.kaupunkivaikutus-author__text:only-child) {
	grid-template-columns: 1fr;
}
.kaupunkivaikutus-author__photo img,
.kaupunkivaikutus-author__photo .person-placeholder {
	width: 8rem;
	height: 8rem;
	border-radius: 50%;
	object-fit: cover;
	display: block;
}
.kaupunkivaikutus-author__name {
	margin: 0;
}
.kaupunkivaikutus-author__title {
	margin: 0.25rem 0 0;
}
.kaupunkivaikutus-author__bio {
	margin: 0.75rem 0 0;
}
.kaupunkivaikutus-author__bio p:last-child {
	margin-bottom: 0;
}
.kaupunkivaikutus-author__url {
	margin: 0.5rem 0 0;
}

/* Editor-only note shown when an ACF-backed block has no data yet. */
.kaupunkivaikutus-block-placeholder {
	padding: 0.75rem 1rem;
	border: 1px dashed var(--color-accent-dark);
	color: var(--color-black);
	font-size: 0.875rem;
	margin: 0;
}

/* Image captions read as body text, so they line up with the text around them
   instead of picking up the block library's centering. */
figcaption.wp-element-caption,
.wp-element-caption {
	text-align: left;
}

/* Headings inside the footer inherit the light text color */
.site-footer .wp-block-heading,
.site-footer .footer-column :where(h1, h2, h3, h4, h5, h6) {
	color: var(--color-white);
}

/* Four columns from the Footer settings (WYSIWYG) – single row */
.footer-columns {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	gap: 2rem;
}
.footer-column {
	flex: 1 1 0;
	min-width: 0;
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.6;
}
/* The last column sizes to its content and is pushed against the right edge,
   so the social links close the row rather than floating mid-width. The basis
   has to be auto as well: with the shared flex-basis of 0 and no growth the
   column would collapse to zero width and its links would spill past the
   footer's right edge. */
.footer-columns > .footer-column:last-child {
	flex: 0 0 auto;
	margin-inline-start: auto;
}
.footer-column p {
	margin: 0 0 0.75rem;
}
.footer-column a {
	color: var(--color-accent-light);
	text-decoration: none;
}
.footer-column a:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

/* Logo row – optional heading above up to 5 logos */
.footer-logos-section {
	margin-top: 3rem;
}
.footer-logos-title {
	margin: 0;
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.6;
	color: var(--color-white);
}
.footer-logos-section .footer-logos {
	margin-top: 1.5rem;
}
.footer-logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 1.5rem;
	margin-top: 3rem;
}

@media (max-width: 768px) {
	.footer-columns {
		flex-direction: column;
		/* Stacked, the 2rem column gap reads as a gap between unrelated blocks;
		   the paragraph spacing inside a column is enough separation. */
		gap: 1rem;
	}
	/* Stacked, the auto inline margin would only shove the last column sideways. */
	.footer-columns > .footer-column:last-child {
		margin-inline-start: 0;
	}
	/* An unused column has no height of its own but still claims a gap, which
	   reads as a double gap in the stack. */
	.footer-column:empty {
		display: none;
	}
}
.footer-logos .footer-logo {
	margin: 0;
	flex: 0 1 auto;
}
.footer-logos .footer-logo img {
	max-height: 80px;
	width: auto;
	height: auto;
}
/* Hide placeholder logos that have no image source yet */
.footer-logos .footer-logo img:not([src]),
.footer-logos .footer-logo img[src=""] {
	display: none;
}

/* Mobile: smaller logos, centred – space-between leaves a ragged last row once
   they wrap. Placed after the rules above so it wins on source order. */
@media (max-width: 768px) {
	.footer-logos {
		justify-content: center;
	}
	.footer-logos .footer-logo img {
		max-height: 50px;
	}
}

/* Arrow icon after buttons (not navigation). SVG used as a mask so the arrow
   inherits the button text color via currentColor (white / black / accent). */
.wp-block-button.is-style-kaupunkivaikutus-primary > .wp-block-button__link::after,
.wp-block-button.is-style-kaupunkivaikutus-secondary > .wp-block-button__link::after {
	content: "";
	flex-shrink: 0;
	width: 1.0625rem; /* 17px */
	height: 1.0625rem; /* 17px */
	background-color: currentColor;
	-webkit-mask: var(--icon-arrow) no-repeat center / contain;
	mask: var(--icon-arrow) no-repeat center / contain;
}

/* Accordion (Haitari) – single-open, accessible */
.accordion__item {
	background: var(--color-accent-light);
	margin-bottom: 0.5rem;
}
.accordion__heading {
	margin: 0;
	font-size: 1rem;
}
.accordion__trigger {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	width: 100%;
	text-align: left;
	background: none;
	border: none;
	padding: 1rem 1.25rem;
	font-family: inherit;
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.3;
	color: var(--color-black);
	cursor: pointer;
}
/* Triangle marker: points right when closed, down when open */
.accordion__trigger::before {
	content: "";
	flex-shrink: 0;
	width: 0;
	height: 0;
	border-style: solid;
	border-width: 0.4rem 0 0.4rem 0.6rem;
	border-color: transparent transparent transparent currentColor;
	transition: transform 0.15s ease;
}
.accordion__trigger[aria-expanded="true"]::before {
	transform: rotate(90deg);
}
.accordion__panel {
	padding: 0 1.25rem 1.25rem;
	overflow: hidden;
	transition: max-height 0.25s ease;
}
@media (prefers-reduced-motion: reduce) {
	.accordion__panel {
		transition: none;
	}
}
/* The script moves focus into the panel when a series opens. With :focus that
   painted a thick accent outline on every mouse click; :focus-visible keeps the
   indicator for keyboard users and leaves mouse opening clean. */
.accordion__panel:focus-visible {
	outline: 3px solid var(--color-accent-dark);
	outline-offset: -3px;
}
.accordion__panel > :first-child {
	margin-top: 0;
}

/* Publication list (Julkaisulista): the accordion above, with a filled
   heading bar per series and a bordered card per publication. */
.publication-list .accordion__item {
	background: none;
	margin-bottom: 0.75rem;
}
.publication-list .accordion__heading {
	background: var(--color-accent-dark);
	font-size: 1rem;
}
.publication-list .accordion__trigger {
	color: var(--color-white);
	font-size: 1.125rem;
}
.publication-list .accordion__panel {
	padding: 0.75rem 0 0;
}
.publication-list__items {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}
.publication {
	background: var(--color-white);
	border: var(--stroke-button);
	padding: 1.25rem;
}
.publication__title {
	margin: 0;
	font-size: 1.125rem;
	line-height: 1.3;
	font-weight: var(--font-weight-bold);
}
.publication__title a {
	color: inherit;
	text-decoration: none;
}
.publication__title a:hover,
.publication__title a:focus {
	text-decoration: underline;
}
.publication__meta {
	display: flex;
	flex-wrap: wrap;
	gap: 0.25rem 0.75rem;
	margin: 0.5rem 0 0;
}
.publication__excerpt {
	margin: 0.75rem 0 0;
}

/* Info box (Tietolaatikko): 2px accent border, no fill, small accent label */
.info-box {
	border: var(--stroke-accent);
	padding: clamp(1.5rem, 4vw, 2rem);
}
.info-box-label {
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.1;
	color: var(--color-accent-dark);
	margin: 0 0 0.25rem;
}

/* Highlight box: accent on front page, light accent on news */
.highlight-box,
.highlight-box--light {
	padding: clamp(1.5rem, 4vw, 3rem);
}
.highlight-box {
	background: var(--color-accent-dark);
	color: var(--color-white);
}
.highlight-box--light {
	background: var(--color-accent-light);
	color: var(--color-black);
}

/* No-background variant */
.highlight-box--plain {
	background: none;
	color: inherit;
	padding: 0;
}
.highlight-box-logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1.5rem;
	margin-top: 2.5rem;
}
.highlight-box-logos .wp-block-image {
	margin: 0;
}
.highlight-box-logos .wp-block-image img {
	/* 96px is the tallest the five logos can be and still share one row inside
	   the content width: their widths add up to about 7.9x the height, plus
	   4 x 1.5rem of gap. */
	max-height: 96px;
	width: auto;
	height: auto;
}
.highlight-box-logos .wp-block-image img:not([src]),
.highlight-box-logos .wp-block-image img[src=""] {
	display: none;
}

/* Button block styles matching the design (used in patterns) */
.wp-block-button.is-style-kaupunkivaikutus-primary > .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	background-color: var(--color-black);
	color: var(--color-white);
	border: none;
	border-radius: 0;
	font-weight: 600;
	font-size: 1.25rem; /* 20px */
	line-height: 1.1;
	padding: 0.75rem 1.25rem;
}
.wp-block-button.is-style-kaupunkivaikutus-primary > .wp-block-button__link:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}
.wp-block-button.is-style-kaupunkivaikutus-secondary > .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	background-color: var(--color-white);
	color: var(--color-black);
	border: var(--stroke-button);
	border-radius: 0;
	font-weight: 600;
	font-size: 1.25rem; /* 20px */
	line-height: 1.1;
	padding: 0.75rem 1.25rem;
}
.wp-block-button.is-style-kaupunkivaikutus-secondary > .wp-block-button__link:hover {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 4px;
}

/* Card block style (register_block_style: core/group is-style-card) */
.wp-block-group.is-style-card {
	background-color: var(--color-accent-light);
	padding: clamp(1.25rem, 3vw, 2rem);
}

/* ---------- KAUPUNKISILUETTI (skyline divider) ---------- */
/* The skyline is kept at the content width (the same width as the text) and the
   space left on both sides is filled with a plain line that grows with the
   viewport. On narrow screens the skyline shrinks together with the content, so
   its ends stay aligned with the edges of the text. */
.kaupunkivaikutus-cityline {
	display: flex;
	align-items: flex-end;
	width: 100%;
	margin-block: clamp(2rem, 5vw, 3.5rem);
	color: var(--color-accent-dark);
}

.kaupunkivaikutus-cityline__figure {
	display: block;
	flex: 0 1 auto;
	/* Content width, but never wider than the row itself. The row already sits
	   inside the root padding, so subtracting the padding here would inset the
	   skyline a second time and leave its ends short of the text. */
	width: min( var( --wp--style--global--content-size, 80.625rem ), 100% );
	height: auto;
	/* The baseline sits on the bottom edge of the viewBox, so half of the
	   stroke would be clipped without this. */
	overflow: visible;
}

.kaupunkivaikutus-cityline__line {
	flex: 1 1 auto;
	height: 1px;
	background: currentColor;
	/* Align with the skyline's baseline (the SVG stroke is drawn centred). */
	margin-bottom: -0.5px;
}

/* ---------- MOBILE (≤768px) ---------- */
@media (max-width: 768px) {
	.text-h1, h1 { font-size: 1.875rem; line-height: 1.1; } /* 30px */
	.text-h2, h2 { font-size: 1.5625rem; line-height: 1.1; } /* 25px */
	.text-h3, h3 { font-size: 1.375rem; line-height: 1.2; } /* 22px */
	.text-h4, h4 { font-size: 1.125rem; line-height: 1.3; } 

	.text-subtitle-1,
	.is-style-kaupunkivaikutus-subtitle-1 { font-size: 1.125rem; line-height: 1.3; } /* 18px */
	.text-subtitle-2,
	.is-style-kaupunkivaikutus-subtitle-2 { font-size: 1.125rem; line-height: 1.5; } 

	.text-meta,
	.is-style-kaupunkivaikutus-meta { font-size: 0.875rem; } /* 14px */
	.text-category-tag { font-size: 0.875rem; } 

	.text-body-lead,
	.is-style-kaupunkivaikutus-body-lead,
	.highlight-box > p,
	.highlight-box--light > p,
	.highlight-box--plain > p { font-size: 1.125rem; } /* 18px */
	/* .text-body stays the same as desktop */
	.text-caption,
	.is-style-kaupunkivaikutus-caption { font-size: 0.875rem; } 

	.text-footer { font-size: 0.875rem; } /* 14px */
	.text-footer-link { font-size: 0.875rem; line-height: 1.6; } /* 14px */
}

/* Contact lines on a person: same size as the body text, the address links. */
.person-phone,
.person-email,
.kaupunkivaikutus-author__contact {
	margin: 0.25rem 0 0;
	font-weight: 300;
	font-size: 1rem;
	line-height: 1.4;
}
.kaupunkivaikutus-author__contact .kaupunkivaikutus-contact__phone + .kaupunkivaikutus-contact__email::before {
	content: " · ";
}
.person-email a,
.kaupunkivaikutus-author__contact a {
	color: var(--color-accent-dark);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.kaupunkivaikutus-toc {
	margin: 2rem 0;
}
.kaupunkivaikutus-toc__heading {
	margin: 0 0 0.75rem;
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.3;
}
.kaupunkivaikutus-toc__list {
	margin: 0;
	padding-left: 1.25rem;
	list-style: disc;
}
.kaupunkivaikutus-toc__item {
	margin: 0 0 0.5rem;
	font-weight: 300;
	font-size: 1rem;
	line-height: 1.4;
}
/* Deeper headings step in, so the list reads as the article's structure. */
.kaupunkivaikutus-toc__item--level-3 { margin-left: 1rem; }
.kaupunkivaikutus-toc__item--level-4 { margin-left: 2rem; }
.kaupunkivaikutus-toc__item--level-5 { margin-left: 3rem; }
.kaupunkivaikutus-toc__item--level-6 { margin-left: 4rem; }
.kaupunkivaikutus-toc__item a {
	color: var(--color-accent-dark);
	font-weight: 600;
	text-decoration: none;
}
.kaupunkivaikutus-toc__item a:hover,
.kaupunkivaikutus-toc__item a:focus-visible {
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
}

/* A heading landed on from the table of contents is not hidden under the
   sticky header, and the jump is a scroll rather than a cut. */
:where(h2, h3, h4, h5, h6)[id] {
	scroll-margin-top: 2rem;
}
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

/* Repeating rows in the publication panel: numbered, with a rule between. */
.kaupunkivaikutus-rows__heading {
	margin: 1.5rem 0 0.5rem;
	font-size: 0.75rem;
	text-transform: uppercase;
	letter-spacing: 0.05em;
}
.kaupunkivaikutus-rows__row {
	padding: 0.75rem 0;
	border-top: 1px solid #e0e0e0;
}
.kaupunkivaikutus-rows__number {
	margin: 0 0 0.25rem;
	font-weight: 600;
}
.kaupunkivaikutus-pdf__name {
	margin: 0 0 0.5rem;
	word-break: break-word;
}

/* The server-rendered blocks show a live preview, links and all, and a stray
   click lands on the site instead of selecting the block. The previews are not
   editable anyway, so their links are inert while editing. Blocks built from
   inner blocks are left alone: their links are real content. */
.editor-styles-wrapper .wp-block-kaupunkivaikutus-feature-media-text a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-person a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-share a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-publication-pdf a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-publication-references a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-publication-list a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-cityline a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-byline a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-latest-posts a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-caption-band a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-authors a,
.editor-styles-wrapper .wp-block-kaupunkivaikutus-table-of-contents a {
	pointer-events: none;
}
