/*
 * Dover — shared design system.
 *
 * Every campaign site gets this. It is deliberately free of any single
 * client's colors, fonts, or copy: every value here resolves through a
 * theme.json preset variable, so a child theme changes its palette and
 * this entire stylesheet re-skins itself with no edits.
 *
 * THE RULE: if you are about to write a literal color, stop. Either it
 * belongs in theme.json as a token, or it is a derived state and belongs
 * in the token block below as a color-mix() off an existing token.
 *
 * Class prefix is `dsg-`. A child theme adds its own `<client>-` prefixed
 * classes for genuinely one-off work; it should not need to override much
 * here, and if it starts to, that is a signal the pattern belongs in this
 * file instead.
 */

/* ---------------------------------------------------------------- tokens */

/* Declared on :root, not on the section classes, so header/footer parts
   and anything else outside a .dsg-section can use them too. */
:root {
	/* Derived states. color-mix keeps hover/tint shades correct for every
	   client automatically. The plain declaration above each mix is the
	   fallback for browsers without color-mix — they get no shift on
	   hover, which is a valid state (the transform still fires). */
	--dsg-accent-dark: var(--wp--preset--color--accent);
	--dsg-accent-dark: color-mix(in srgb, var(--wp--preset--color--accent) 82%, #000);

	--dsg-on-secondary: var(--wp--preset--color--white);
	--dsg-on-secondary: color-mix(in srgb, var(--wp--preset--color--white) 88%, var(--wp--preset--color--secondary));

	--dsg-light-tint: var(--wp--preset--color--white);
	--dsg-light-tint: color-mix(in srgb, var(--wp--preset--color--white) 94%, var(--wp--preset--color--secondary));

	/* Hairlines and scrims, derived so they sit correctly on any palette. */
	--dsg-rule: color-mix(in srgb, var(--wp--preset--color--pale) 28%, transparent);
	--dsg-card-border: color-mix(in srgb, var(--wp--preset--color--pale) 18%, transparent);
	--dsg-chip-bg: color-mix(in srgb, var(--wp--preset--color--ink) 55%, transparent);

	/* Section rhythm. */
	--dsg-pad-y: clamp(3.5rem, 8vw, 7rem);
	--dsg-pad-x: clamp(1.5rem, 6vw, 7rem);

	/* Sticky header height, subtracted by the full-viewport hero so it
	   doesn't overflow the first screen. Keep in sync with .dsg-header's
	   actual rendered height if you change its padding. */
	--dsg-header-h: 68px;
}

@media (max-width: 600px) {
	:root { --dsg-header-h: 58px; }
}

/* ---------------------------------------------------------------- header */

.dsg-header {
	position: sticky;
	top: 0;
	z-index: 50;
	padding: 0 var(--dsg-pad-x);
}

.dsg-header__inner {
	max-width: 1120px;
	margin-inline: auto;
	min-height: var(--dsg-header-h);
}

/* Site Logo. Set the file under Appearance -> Editor -> Styles, or in the
   Customizer's Site Identity panel — it is a site setting, not a theme
   file, so it does not travel in git and must be uploaded per install.
   If no logo is set, core renders nothing here on the front end; swap the
   block for the wordmark group (see the footer part) as a text fallback. */
.dsg-header__logo { display: flex; align-items: center; }

.dsg-header__logo img {
	display: block;
	height: auto;
	max-height: calc(var(--dsg-header-h) - 20px);
	width: auto;
}

/* NO COLOR RULES HERE — deliberately.
   Navigation colors live in theme.json under styles.blocks.core/navigation,
   which makes them changeable in Appearance -> Editor -> Styles -> Blocks
   -> Navigation and per-instance in the block's own color panel. Setting
   them here at class specificity would silently beat both, so the color
   controls would appear to do nothing. Only non-color defaults below, and
   wrapped in :where() so they add no specificity either. */
:where(.dsg-nav) a {
	text-decoration: none;
	letter-spacing: 0.01em;
}

:where(.dsg-nav) a:hover,
:where(.dsg-nav) a:focus-visible {
	text-decoration: underline;
	text-underline-offset: 4px;
}

/* A full-size donate button makes the header too tall. */
.dsg-btn--compact .wp-block-button__link {
	padding: 10px 22px;
	font-size: 0.95rem;
}

/* ------------------------------------------------- mobile overlay menu */

/* Core supplies the behaviour — the toggle, the focus trap, Escape to
   close, aria-expanded — and none of the appearance. Everything below is
   presentation only; don't reimplement the interaction. Core's own
   breakpoint for overlayMenu:"mobile" is 600px, so these queries match it
   exactly. Change one and you must change the other or the hamburger and
   the layout disagree in a 1px band. */

/* Hamburger and close button. Size only — the color inherits from the
   Navigation block's own text color so it follows whatever is set in the
   editor rather than being pinned here. */
:where(.dsg-nav) .wp-block-navigation__responsive-container-open,
:where(.dsg-nav) .wp-block-navigation__responsive-container-close {
	color: inherit;
	padding: 6px;
}

:where(.dsg-nav) .wp-block-navigation__responsive-container-open svg,
:where(.dsg-nav) .wp-block-navigation__responsive-container-close svg {
	width: 28px;
	height: 28px;
	fill: currentColor;
}

/* Open overlay: spacing and type scale only.
   Overlay COLORS come from the Navigation block's overlayBackgroundColor
   and overlayTextColor attributes, set in the header template part — core
   has first-class support for them, so they are editable in the block's
   Color panel. Forcing them here would break that panel. */
:where(.dsg-nav) .wp-block-navigation__responsive-container.is-menu-open {
	padding: clamp(1.5rem, 6vw, 3rem);
}

:where(.dsg-nav) .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	padding-top: clamp(2rem, 8vh, 4rem);
}

:where(.dsg-nav) .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container {
	gap: clamp(1rem, 3vh, 1.75rem);
}

/* Bigger tap targets and type than the desktop bar — the desktop size is
   fine in a row and far too small as a full-screen menu. */
:where(.dsg-nav) .wp-block-navigation__responsive-container.is-menu-open a {
	font-size: clamp(1.25rem, 5vw, 1.6rem);
	font-weight: 800;
	letter-spacing: -0.01em;
	padding: 0.25rem 0;
}

/* Items that belong only in the overlay — a secondary action that lives
   as a button in the desktop header would otherwise be unreachable once
   that button is hidden on small screens. */
.dsg-nav__mobile-only { display: none; }

@media (max-width: 600px) {
	.dsg-nav__mobile-only { display: block; }

	/* Two buttons plus a hamburger will not fit next to a logo. Keep the
	   donate ask visible — it is the point of the site — and let the
	   secondary action move into the overlay via .dsg-nav__mobile-only. */
	.dsg-header .dsg-btn--outline { display: none; }

	.dsg-header__inner { flex-wrap: nowrap; }
	.dsg-header__actions { gap: 10px; }
	.dsg-header__logo img { max-height: calc(var(--dsg-header-h) - 16px); }
	.dsg-btn--compact .wp-block-button__link { padding: 9px 16px; font-size: 0.9rem; }
}

/* Very narrow phones: the donate label alone is wider than the space
   left beside a logo and a hamburger. */
@media (max-width: 380px) {
	.dsg-header__logo img { max-height: calc(var(--dsg-header-h) - 26px); }
	.dsg-btn--compact .wp-block-button__link { padding: 8px 12px; font-size: 0.85rem; }
}

/* --------------------------------------------------------------- section */

.dsg-section {
	padding: var(--dsg-pad-y) var(--dsg-pad-x);
	position: relative;
	overflow: hidden;
}

/* The measure. These sections are alignfull with their own padding, so
   the inner width is set here rather than fighting core's layout engine. */
.dsg-section__inner {
	max-width: 820px;
	margin-inline: auto;
	position: relative;
}

.dsg-section__inner--wide { max-width: 1120px; }
.dsg-section__inner--mid  { max-width: 860px; }

.dsg-center { text-align: center; }

/* Long-form prose rhythm. */
.dsg-lead {
	font-weight: 700;
	line-height: 1.35;
	letter-spacing: -0.01em;
	font-size: clamp(1.5rem, 3vw, 2.1rem);
	margin: 0 0 1.4rem;
}

.dsg-prose p + p { margin-top: 0; margin-bottom: 1.3rem; }
.dsg-prose p:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------- eyebrow */

/* The rule + spaced caps label that opens a section. The rule is a
   pseudo-element so the pattern markup stays one editable paragraph. */
.dsg-eyebrow {
	display: flex;
	align-items: center;
	gap: 14px;
	font-weight: 800;
	letter-spacing: 0.2em;
	font-size: var(--wp--preset--font-size--eyebrow);
	line-height: 1;
	text-transform: uppercase;
	margin-bottom: 22px;
}

.dsg-eyebrow::before {
	content: "";
	flex: 0 0 auto;
	width: 34px;
	height: 3px;
	background: var(--wp--preset--color--secondary);
}

/* On dark grounds the brand secondary is typically far too dark to read —
   measured at 1.7:1 against navy in this system, i.e. the rule that opens
   every dark section was effectively invisible. Dark backgrounds get the
   on-dark variant of the same hue. Keyed off the background preset
   classes so no pattern markup has to opt in, and .dsg-hero explicitly
   because it sets its background in CSS rather than via a block class. */
.dsg-hero .dsg-eyebrow::before,
.has-primary-background-color .dsg-eyebrow::before,
.has-ink-background-color .dsg-eyebrow::before,
.has-surface-background-color .dsg-eyebrow::before {
	background: var(--wp--preset--color--secondary-light);
}

.dsg-eyebrow--center { justify-content: center; }

/* -------------------------------------------------------------- wordmark */

.dsg-wordmark {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
	margin: 0;
}

.dsg-wordmark::before {
	content: "";
	flex: 0 0 auto;
	width: 0;
	height: 0;
	border-left: 9px solid transparent;
	border-right: 9px solid transparent;
	border-bottom: 15px solid var(--wp--preset--color--secondary);
}

.dsg-wordmark__name {
	font-weight: 900;
	letter-spacing: 0.14em;
	font-size: 15px;
	text-transform: uppercase;
	color: var(--wp--preset--color--white);
}

.dsg-wordmark__dot {
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--wp--preset--color--accent);
	display: inline-block;
	margin: 0 4px;
}

.dsg-wordmark__role {
	font-weight: 600;
	letter-spacing: 0.14em;
	font-size: 12px;
	text-transform: uppercase;
	color: var(--wp--preset--color--pale);
}

/* --------------------------------------------------------------- buttons */

/* Core button blocks, restyled. Targeting the inner link keeps core's own
   width and alignment controls working. */
.dsg-btn .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	gap: 9px;
	font-weight: 800;
	font-size: 1.02rem;
	letter-spacing: 0.02em;
	padding: 16px 34px;
	border-radius: 4px;
	text-decoration: none;
	transition: background-color 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

/* Label color comes from the on-accent token, NOT from white. A gold or
   yellow accent with a white label measures around 2:1 — unreadable — and
   hard-coding white silently produced that for any client whose accent is
   light. Each theme declares the correct label color for its own accent;
   the give-triangle inherits it via currentColor. */
.dsg-btn--solid .wp-block-button__link {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--on-accent);
	border: 0;
}

.dsg-btn--solid .wp-block-button__link:hover,
.dsg-btn--solid .wp-block-button__link:focus-visible {
	background: var(--dsg-accent-dark);
	transform: translateY(-2px);
}

.dsg-btn--outline .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--white);
	border: 2px solid var(--wp--preset--color--pale);
}

.dsg-btn--outline .wp-block-button__link:hover,
.dsg-btn--outline .wp-block-button__link:focus-visible {
	background: var(--wp--preset--color--pale);
	color: var(--wp--preset--color--primary);
}

/* For bands where the accent color has no contrast against the ground. */
.dsg-btn--light .wp-block-button__link {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--secondary);
	border: 0;
	white-space: nowrap;
}

.dsg-btn--light .wp-block-button__link:hover,
.dsg-btn--light .wp-block-button__link:focus-visible {
	background: var(--dsg-light-tint);
	transform: translateY(-2px);
}

/* Solid triangle marking a donate action. */
.dsg-btn--give .wp-block-button__link::before {
	content: "";
	width: 0;
	height: 0;
	border-left: 6px solid transparent;
	border-right: 6px solid transparent;
	border-bottom: 10px solid currentColor;
}

/* Trailing arrow on a "read more" action. */
.dsg-btn--arrow .wp-block-button__link::after {
	content: "→";
	font-size: 1.15rem;
	line-height: 1;
}

/* ----------------------------------------------------------------- cards */

.dsg-card {
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--dsg-card-border);
	border-top: 4px solid var(--wp--preset--color--secondary);
	border-radius: 6px;
	padding: clamp(1.5rem, 2.4vw, 2rem);
	height: 100%;
	display: flex;
	flex-direction: column;
}

.dsg-card > :last-child { margin-bottom: 0; }

.dsg-card h3 {
	margin: 0 0 12px;
	color: var(--wp--preset--color--white);
	font-size: clamp(1.2rem, 1.8vw, 1.45rem);
}

.dsg-card p {
	margin: 0;
	color: var(--wp--preset--color--card-text);
	font-size: clamp(0.98rem, 1.3vw, 1.08rem);
	line-height: 1.6;
}

/* Action cards push their button to the bottom so a row lines up
   regardless of copy length. */
.dsg-card--action p { flex: 1 1 auto; margin-bottom: clamp(1.5rem, 3vw, 2rem); }
.dsg-card--action .wp-block-buttons { margin-top: auto; }
.dsg-card--action h3 { font-size: clamp(1.3rem, 2vw, 1.6rem); }

/* Makes cards fill their stretched grid/column track so the colored top
   edges align across a row. */
.dsg-card-grid { align-items: stretch; }
.dsg-card-grid > .wp-block-group,
.dsg-card-grid > .wp-block-column { height: 100%; }
.dsg-card-grid > .wp-block-column { display: flex; flex-direction: column; }

/* ------------------------------------------------------------ split hero */

.dsg-hero {
	display: flex;
	flex-direction: row;
	min-height: calc(100vh - var(--dsg-header-h));
	min-height: calc(100svh - var(--dsg-header-h));
	width: 100%;
	background: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--sky);
	overflow: hidden;
}

/* Mirrors the source design's photoSide = "left" option. */
.dsg-hero--photo-left { flex-direction: row-reverse; }

.dsg-hero__content {
	flex: 1 1 56%;
	min-width: 0;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	padding: clamp(2rem, 4.5vw, 5rem);
}

.dsg-hero__main { max-width: 640px; margin: clamp(2rem, 5vh, 4rem) 0; }
.dsg-hero__main > :first-child { margin-top: 0; }

.dsg-hero h1 { margin: 0; line-height: 0.98; color: var(--wp--preset--color--white); }

.dsg-hero__subtitle {
	margin: 14px 0 0;
	font-weight: 600;
	line-height: 1.2;
	font-size: clamp(1.15rem, 2.2vw, 1.7rem);
}

.dsg-hero__lede {
	margin: clamp(1.4rem, 3vh, 2rem) 0 0;
	max-width: 540px;
	line-height: 1.55;
}

.dsg-hero .wp-block-buttons {
	gap: 16px;
	margin-top: clamp(1.6rem, 3.5vh, 2.4rem);
}

/* Coverage block, pinned to the bottom of the content column. */
.dsg-hero__district { margin-top: auto; }

.dsg-hero__district::before {
	content: "";
	display: block;
	height: 1px;
	background: var(--dsg-rule);
	margin-bottom: 20px;
}

.dsg-hero__district-label {
	font-weight: 800;
	letter-spacing: 0.16em;
	font-size: 11px;
	text-transform: uppercase;
	color: var(--wp--preset--color--pale);
	margin: 0 0 12px;
}

.dsg-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 12px;
	padding: 0;
	list-style: none;
}

.dsg-chips li {
	font-weight: 600;
	font-size: 13px;
	color: var(--wp--preset--color--sky);
	background: var(--dsg-chip-bg);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--pale) 22%, transparent);
	padding: 6px 13px;
	border-radius: 999px;
}

.dsg-hero__zips {
	font-weight: 500;
	font-size: 13px;
	color: var(--wp--preset--color--pale);
	letter-spacing: 0.01em;
	margin: 0;
}

/* Photo column. */
.dsg-hero__media {
	flex: 0 0 42%;
	min-width: 280px;
	position: relative;
	background: var(--wp--preset--color--ink);
}

.dsg-hero__media .wp-block-image,
.dsg-hero__media figure,
.dsg-hero__media img {
	width: 100%;
	height: 100%;
	margin: 0;
	display: block;
	object-fit: cover;
}

/* Accent edge on the seam between photo and copy. */
.dsg-hero__media::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	width: 6px;
	background: var(--wp--preset--color--secondary);
	pointer-events: none;
	z-index: 2;
}

/* Disclaimer over a scrim so it stays legible on any photograph.
   pointer-events:none so it never blocks the image. */
.dsg-hero__disclaimer {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	margin: 0;
	padding: 14px 18px;
	background: linear-gradient(to top, color-mix(in srgb, var(--wp--preset--color--ink) 85%, transparent), transparent);
	pointer-events: none;
	text-align: right;
	font-weight: 500;
	font-size: 10px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: color-mix(in srgb, var(--wp--preset--color--sky) 70%, transparent);
	z-index: 2;
}

/* -------------------------------------------------------- internal hero */

.dsg-page-hero { padding: clamp(2.6rem, 6vw, 4.2rem) var(--dsg-pad-x); }

/* Decorative dot cluster. Ornamental only — the markup is a single
   core/html block marked aria-hidden. */
.dsg-dots {
	position: absolute;
	top: 0;
	right: 0;
	transform: translate(28%, -32%);
	display: grid;
	grid-template-columns: repeat(4, clamp(34px, 4.5vw, 54px));
	gap: 10px;
	pointer-events: none;
}

.dsg-dots span {
	width: 100%;
	aspect-ratio: 1;
	border-radius: 50%;
	background: var(--wp--preset--color--accent);
}

.dsg-dots span:nth-child(1),
.dsg-dots span:nth-child(7) { grid-column: 2; }

.dsg-dots span:nth-child(2),
.dsg-dots span:nth-child(5),
.dsg-dots span:nth-child(7) { background: var(--wp--preset--color--pale); }

/* ------------------------------------------------------------ facts list */

.dsg-facts { display: flex; flex-direction: column; }

/* Top border on each row, not bottom, so the list opens with a rule and
   doesn't close with a dangling one. */
.dsg-facts__item {
	padding: clamp(1.4rem, 2.6vw, 1.9rem) 0;
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 16%, transparent);
}

.dsg-facts__item h3 {
	margin: 0 0 10px;
	font-size: clamp(1.15rem, 1.8vw, 1.4rem);
	line-height: 1.25;
}

.dsg-facts__item p {
	margin: 0;
	color: var(--wp--preset--color--muted);
	line-height: 1.6;
}

/* Same hairline-separated treatment for search results and CPT archives. */
.dsg-listing__item {
	padding: clamp(1.4rem, 2.6vw, 1.9rem) 0;
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--primary) 16%, transparent);
}

.dsg-listing__item :where(h2, h3) { margin: 0 0 8px; }

.dsg-listing__item p {
	margin: 0;
	color: var(--wp--preset--color--muted);
	line-height: 1.6;
}

/* -------------------------------------------------------------- search */

.dsg-search .wp-block-search__input {
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--muted) 45%, transparent);
	border-radius: 4px;
	padding: 12px 14px;
	font-size: 1rem;
}

.dsg-search .wp-block-search__button {
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--on-accent);
	border: 0;
	border-radius: 4px;
	padding: 10px 20px;
	font-weight: 700;
	cursor: pointer;
}

.dsg-search .wp-block-search__button:hover,
.dsg-search .wp-block-search__button:focus-visible {
	background: var(--dsg-accent-dark);
}

/* On dark grounds the input needs a light field to stay legible. */
.has-primary-background-color .dsg-search .wp-block-search__input,
.has-ink-background-color .dsg-search .wp-block-search__input {
	background: var(--wp--preset--color--white);
	color: var(--wp--preset--color--primary);
}

/* ----------------------------------------------------- split content+media */

.dsg-split {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: clamp(2rem, 5vw, 4rem);
	align-items: center;
}

/* Add this class to the split group to put the image on the left. Using
   `order` rather than reversing the markup keeps the reading order for
   screen readers and keyboard tabbing correct either way. */
.dsg-split--media-left .dsg-split__media { order: -1; }

.dsg-split__media img,
.dsg-split__media .wp-block-image { margin: 0; }

.dsg-split__media img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 6px;
}

.dsg-split__content > :first-child { margin-top: 0; }
.dsg-split__content > :last-child { margin-bottom: 0; }

@media (max-width: 782px) {
	.dsg-split { grid-template-columns: 1fr; }
	/* On one column the image belongs above the copy regardless of the
	   desktop side, so the order override is dropped. */
	.dsg-split--media-left .dsg-split__media { order: 0; }
}

/* ----------------------------------------------------------------- stats */

.dsg-stats {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: clamp(1.5rem, 4vw, 3rem);
}

.dsg-stat > :last-child { margin-bottom: 0; }

.dsg-stat__number {
	font-family: var(--wp--preset--font-family--display, inherit);
	font-weight: 900;
	font-size: clamp(2.5rem, 6vw, 4rem);
	line-height: 1;
	letter-spacing: -0.02em;
	margin: 0 0 0.5rem;
	color: var(--wp--preset--color--secondary);
}

.dsg-stat__label {
	margin: 0;
	font-size: 1rem;
	line-height: 1.4;
}

/* ------------------------------------------------------------ pull quote */

.dsg-pullquote {
	margin: 0;
	border-left: 4px solid var(--wp--preset--color--secondary);
	padding-left: clamp(1.25rem, 3vw, 2rem);
}

.dsg-pullquote p {
	font-weight: 700;
	font-size: clamp(1.35rem, 3vw, 2rem);
	line-height: 1.3;
	letter-spacing: -0.01em;
	margin: 0 0 1rem;
}

.dsg-pullquote cite {
	font-style: normal;
	font-weight: 600;
	font-size: 0.95rem;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	opacity: 0.85;
}

/* Same on-dark swap as the eyebrow rule: the brand secondary is far too
   dark to read against a dark ground, so anything using it as an accent
   switches to the lightened variant automatically. */
.dsg-hero .dsg-stat__number,
.has-primary-background-color .dsg-stat__number,
.has-ink-background-color .dsg-stat__number,
.has-surface-background-color .dsg-stat__number { color: var(--wp--preset--color--secondary-light); }

.dsg-hero .dsg-pullquote,
.has-primary-background-color .dsg-pullquote,
.has-ink-background-color .dsg-pullquote,
.has-surface-background-color .dsg-pullquote { border-left-color: var(--wp--preset--color--secondary-light); }

/* ------------------------------------------------------------ logo strip */

.dsg-logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: clamp(1.5rem, 5vw, 3.5rem);
}

/* Endorser and press logos arrive at wildly different intrinsic sizes;
   capping height rather than width is what makes a mixed row read as one
   line. Deliberately no grayscale filter — organisation marks usually
   have to appear in their own colors. */
.dsg-logos figure,
.dsg-logos .wp-block-image { margin: 0; }

.dsg-logos img {
	display: block;
	max-height: 52px;
	width: auto;
	max-width: 160px;
	object-fit: contain;
}

/* --------------------------------------------------------- email capture */

.dsg-email-band { padding: clamp(3.5rem, 7vw, 6rem) var(--dsg-pad-x); }

.dsg-email {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: clamp(1.5rem, 4vw, 3rem);
	max-width: 900px;
	margin-inline: auto;
}

.dsg-email__copy { flex: 1 1 340px; min-width: 0; }

.dsg-email__copy h2 {
	margin: 0 0 10px;
	font-size: clamp(1.8rem, 3.6vw, 2.7rem);
	color: var(--wp--preset--color--white);
}

.dsg-email__copy p {
	margin: 0;
	max-width: 460px;
	line-height: 1.55;
	color: var(--dsg-on-secondary);
}

/* ---------------------------------------------------------------- footer */

.dsg-footer { padding: clamp(2.5rem, 5vw, 4rem) var(--dsg-pad-x); }

.dsg-footer__inner {
	max-width: 1120px;
	margin-inline: auto;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
}

.dsg-footer__disclaimer,
.dsg-disclaimer {
	font-weight: 500;
	font-size: 11px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: color-mix(in srgb, var(--wp--preset--color--pale) 70%, transparent);
	margin: 0;
}

/* Shown only to logged-in admins when no disclaimer text is set. Loud on
   purpose — an unset legal notice needs to be noticed, not blend in. */
.dsg-disclaimer--unset {
	text-transform: none;
	letter-spacing: normal;
	font-size: 0.8125rem;
	color: var(--wp--preset--color--secondary);
}

/* Footer link columns. */
.dsg-linklist {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.dsg-linklist a {
	color: var(--wp--preset--color--sky);
	text-decoration: none;
	font-size: 0.95rem;
}

.dsg-linklist a:hover,
.dsg-linklist a:focus-visible {
	color: var(--wp--preset--color--white);
	text-decoration: underline;
}

/* Link columns sit above the colophon, so drop the colophon's own top
   padding when they are stacked together. */
.dsg-footer-links + .dsg-footer { padding-top: clamp(1.5rem, 3vw, 2.5rem); }

/* ------------------------------------------------------------- animation */

/* Staggered entrance. Wrapped in no-preference so users who ask for
   reduced motion get the finished state immediately, rather than an
   animation that has to be overridden. */
@media (prefers-reduced-motion: no-preference) {
	@keyframes dsgUp {
		from { opacity: 0; transform: translateY(14px); }
		to   { opacity: 1; transform: none; }
	}

	.dsg-hero__content > *,
	.dsg-hero__main > * { animation: dsgUp 0.7s ease both; }

	.dsg-hero__main > :nth-child(1) { animation-delay: 0.05s; }
	.dsg-hero__main > :nth-child(2) { animation-delay: 0.10s; }
	.dsg-hero__main > :nth-child(3) { animation-delay: 0.16s; }
	.dsg-hero__main > :nth-child(4) { animation-delay: 0.22s; }
	.dsg-hero__main > :nth-child(5) { animation-delay: 0.28s; }
	.dsg-hero__district             { animation-delay: 0.34s; }
}

/* ------------------------------------------------------------ responsive */

/* Below 900px the split hero stacks photo-first: a face above the name
   reads better on a phone than a tall column of copy pushing the
   photograph off-screen. */
@media (max-width: 900px) {
	.dsg-hero,
	.dsg-hero--photo-left {
		flex-direction: column-reverse;
		min-height: 0;
	}

	.dsg-hero__media { flex: 0 0 auto; min-height: 58vh; }
	.dsg-hero__content { padding: clamp(1.75rem, 6vw, 3rem); }
	.dsg-hero__main { margin: 2rem 0; }

	/* The accent edge belongs on the seam, which is now horizontal. */
	.dsg-hero__media::before {
		top: auto;
		bottom: 0;
		left: 0;
		right: 0;
		width: auto;
		height: 6px;
	}
}

@media (max-width: 600px) {
	.dsg-dots { display: none; }
	.dsg-email { flex-direction: column; align-items: flex-start; }

	/* :not(--compact) is load-bearing. This block sits later in the file
	   than the header's compact-button rule at identical specificity, so
	   without the exclusion it would win on source order and silently
	   restore full padding to the header donate button on exactly the
	   screens where it has the least room. */
	.dsg-btn:not(.dsg-btn--compact) .wp-block-button__link { padding: 14px 26px; }
}

/* ------------------------------------------------------------------ a11y */

.dsg-hero a:not(.wp-block-button__link):focus-visible,
.dsg-section a:not(.wp-block-button__link):focus-visible,
.dsg-btn .wp-block-button__link:focus-visible {
	outline: 3px solid var(--wp--preset--color--pale);
	outline-offset: 3px;
}
