/**
 * Global Base Styles — Dfd
 */

*,
*::before,
*::after {
	box-sizing: border-box;
}

/* ── Smooth Scroll ──────────────────────────────────────────────────────────── */

html {
	scroll-behavior: smooth;
}

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

body {
	font-family: var(--kd-font-body);
	font-size: var(--kd-size-body);
	font-weight: var(--kd-fw-body);
	line-height: var(--kd-lh-body);
	color: var(--kd-color-body);
	background-color: var(
		--kd-color-surface
	); /* lavender page tint — NOT base (F1 review round 1: base=white is the starter's ~30-pattern "text-on-dark" role) */
	-webkit-font-smoothing: antialiased;
}

img,
video {
	max-width: 100%;
	height: auto;
	display: block;
}

a {
	color: var(--kd-color-primary);
	transition: color var(--kd-transition-fast);
}

a:hover {
	color: var(--kd-color-secondary);
}

/* ── Headings — DynaPuff 700, 3% tracking, drop shadow (figma-analysis §1.2/1.4) ── */

h1,
h2,
h3,
h4,
h5,
h6 {
	font-variation-settings: "wdth" 100;
	text-shadow: var(--dfd-shadow-heading);
}

/* ── Announcement Bar (dormant — re-add a .kd-announcement-bar group to use) ── */

.kd-announcement-bar {
	background-color: var(--kd-color-banner-bg);
	text-align: center;
	font-size: 1rem;
	font-weight: 700;
	color: var(--kd-color-base);
	width: 100%;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
	padding-left: max(var(--kd-space-lg), calc((100% - 1216px) / 2)) !important;
	padding-right: max(
		var(--kd-space-lg),
		calc((100% - 1216px) / 2)
	) !important;
}

.kd-announcement-bar p {
	margin: 0;
	line-height: 1;
}

/* ── Buttons ───────────────────────────────────────────────────────────────── */

.wp-block-button__link,
.kd-btn {
	display: inline-block;
	font-family: var(--kd-font-heading);
	font-size: var(--kd-size-btn);
	font-weight: var(--kd-fw-heading);
	letter-spacing: var(--dfd-track-btn);
	border-radius: var(--kd-radius-pill);
	padding: var(--kd-btn-pad); /* 1.5rem 2.25rem → 74px tall at 22px/1.2 */
	transition:
		background-color var(--kd-transition-base),
		color var(--kd-transition-base),
		border-color var(--kd-transition-base);
	cursor: pointer;
	text-decoration: none;
	border: none; /* both roles are solid fills (10:347/348, 10:334/335) — a
		border would add to the box height on top of --kd-btn-pad and miss
		the verified 74px target (padding 1.5rem × 2 + 22px/1.2 line-height
		≈ 74px exactly, border-box) */
	line-height: 1.2;
}

/* Primary button (fill) — duck yellow → ~6% darker yellow hover (10:347/348) */
.wp-block-button:not(.is-style-outline):not(.is-style-text-link)
	.wp-block-button__link {
	background-color: var(--kd-btn-bg);
	color: var(--kd-btn-fg);
}

.wp-block-button:not(.is-style-outline):not(.is-style-text-link)
	.wp-block-button__link:hover {
	background-color: var(--kd-btn-bg-hover);
	color: var(--kd-btn-fg);
}

/* Secondary button — WP core's built-in "Outline" style (is-style-outline) is
   remapped to a SOLID navy pill / white text (10:334/335), not a transparent
   outline: the Figma comp has no outline-style button anywhere. */
.wp-block-button.is-style-outline .wp-block-button__link {
	background-color: var(--kd-btn2-bg);
	color: var(--kd-btn2-fg);
}

.wp-block-button.is-style-outline .wp-block-button__link:hover {
	background-color: var(--kd-btn2-bg-hover);
	color: var(--kd-btn2-fg);
	border-color: var(--kd-btn2-bg-hover);
}

/* Inverted outline button — white on purple bands (header donate, footer subscribe) */
.kd-btn-invert .wp-block-button__link,
.kd-btn-invert.is-style-outline .wp-block-button__link {
	background-color: transparent;
	color: var(--kd-color-base);
	border-color: var(--kd-color-base);
	border-width: 3px;
}

.kd-btn-invert .wp-block-button__link:hover,
.kd-btn-invert.is-style-outline .wp-block-button__link:hover {
	background-color: var(--kd-color-base);
	color: var(--kd-color-primary);
	border-color: var(--kd-color-base);
}

/* Text link button */
.wp-block-button.is-style-text-link .wp-block-button__link {
	background: none;
	border: none;
	border-radius: 0;
	padding: 0;
	color: var(--kd-btn-link);
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 900;
	font-size: 1.125rem;
	text-transform: uppercase;
	text-decoration: underline;
	text-decoration-color: var(--kd-btn-link);
	text-decoration-thickness: 3px;
	text-underline-offset: 8px;
	letter-spacing: 0.02em;
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
}

.wp-block-button.is-style-text-link .wp-block-button__link:hover {
	background: none;
	color: var(--kd-btn-link-accent);
	text-decoration-color: var(--kd-btn-link-accent);
}

/* Buttons on the interior hero (dark) — invert to light; no per-section recolor */
.kd-hero-interior
	.wp-block-button:not(.is-style-outline)
	.wp-block-button__link {
	background-color: var(--kd-btn-fg);
	color: var(--kd-btn-bg);
	border-color: var(--kd-btn-fg);
}
.kd-hero-interior
	.wp-block-button:not(.is-style-outline)
	.wp-block-button__link:hover {
	background-color: color-mix(
		in srgb,
		var(--kd-btn-fg) 88%,
		var(--kd-btn-bg)
	);
	border-color: color-mix(in srgb, var(--kd-btn-fg) 88%, var(--kd-btn-bg));
	color: var(--kd-btn-bg);
}
.kd-hero-interior .wp-block-button.is-style-outline .wp-block-button__link {
	background-color: transparent;
	color: var(--kd-btn-fg);
	border-color: var(--kd-btn-fg);
}
.kd-hero-interior
	.wp-block-button.is-style-outline
	.wp-block-button__link:hover {
	background-color: var(--kd-btn-fg);
	color: var(--kd-btn-bg);
	border-color: var(--kd-btn-fg);
}

/* ══════════════════════════════════════════════════════════════════════════════
   SITE HEADER — single-tier bar on the lavender page background
   Built from the Figma Home/Adopt header (logo 12:657, nav 12:651–656):
   163px logo left, 6-item nav right, 196px tall, no border, no top strip.
   ══════════════════════════════════════════════════════════════════════════════ */

/* DL-E (2026-09-12, Alain: "the hero should bleed into the nav"): the header
   is now transparent and overlays the hero band (see .dfd-hero-campaign's
   negative top margin in hero-campaign.css) rather than pushing it down.
   Sticky is dropped for this item — a transparent bar floating over scrolled
   page content with no scrolled-state treatment in the comp is unreadable,
   so the wrapper stays `position: relative` (still positioned, so its
   z-index below still wins the stacking order against the hero it now
   visually sits on top of; see .kd-site-header's own z-index for the
   mechanism). Was `position: sticky; top: var(--wp-admin--admin-bar--height,
   0px);` — revert if a future item reintroduces a scrolled-state design. */
header.wp-block-template-part:has(.kd-site-header) {
	position: relative;
	z-index: var(--kd-z-header);
	/* QA-1: the off-canvas mobile panel (.kd-mobile-panel, further down this
	   file) is `position:fixed` + `transform: translateX(100%)` when closed —
	   in-flow-excluded per spec, but a Chromium quirk with transformed fixed
	   elements can still let its box register in the initial containing
	   block's scrollable overflow, growing `document.scrollWidth` past the
	   viewport at mobile widths (480 vs 375) and causing real sideways
	   rubber-band scroll on touch browsers (iOS Safari). `overflow-x: clip`
	   here (an ancestor of the panel — see parts/header.html /
	   dfd_render_mobile_nav()) removes that box from the scroll-overflow
	   computation entirely — unlike `hidden`, `clip` never creates a
	   scrollable region for a browser to size the root against. Deliberately
	   `overflow-x` only: `overflow-y` stays the initial `visible` so the
	   panel's full-viewport-height open state (`top:0; bottom:0`, taller than
	   this ~196px header bar) and the desktop nav's `.sub-menu` dropdowns
	   (position:absolute, can drop below the header) are unaffected — mixing
	   `clip`/`visible` across axes does not force the visible axis to `auto`
	   (that auto-conversion is only a `visible`+non-`clip` rule). Do NOT
	   change this to `overflow-x: hidden` on html/body — that masks the same
	   symptom sitewide instead of removing its source, and defeats future
	   sideways-scroll bugs from ever surfacing. */
	overflow-x: clip;
}

.kd-site-header {
	position: relative;
	z-index: var(--kd-z-header);
	width: 100%;
}

.kd-site-header > * {
	margin-block: 0 !important;
}

.kd-mainbar {
	/* DL-E: transparent — the mainbar overlays the hero image on Home
	   (hero-campaign.css) and the plain lavender page background on
	   no-hero interior pages (nothing painted here means the page bg shows
	   through either way, matching both Figma frames — Home 1:2's header
	   sits ON the hero art, Adopt 1:145's sits on the lavender page bg). Was
	   `background-color: var(--kd-color-surface);`. */
	background-color: transparent;
	min-height: var(--kd-mainbar-height); /* 196px desktop */
	padding-left: var(--kd-edge-pad) !important;
	padding-right: var(--kd-edge-pad) !important;
	gap: 1.5rem;
}

/* Logo — 163px wide (2x srcset in parts/header.html), pinned left */
.kd-site-header .kd-brand-badge {
	display: flex;
	align-items: center;
	line-height: 0;
	margin-inline-end: auto;
}

.kd-site-header .kd-brand-badge img {
	display: block;
	width: 163px;
	height: auto;
}

/* Gate round 1 fix (design-diff): the mainbar's shared vertical centring
   (align-items:center) put the logo art top at y32.5 live vs Figma's y≈55
   (box 12:657 is y45–196, 151 tall, with the 131px-tall art CENTRED inside
   that box per Figma's own layout — box centre 120.5, art top 120.5−131/2).
   `align-self:flex-start` + a fixed margin-top (not just a bigger
   margin-top under the inherited `align-items:center`, tried first — that
   only moved the art 11.5px for a 23px margin, since centring re-splits an
   asymmetric margin box and halves its visible effect) anchors the art to
   the row's own top edge, where margin-top IS the real distance, matching
   Figma 1:1. Independent of the nav (which already lands correctly, see
   .kd-menu-wrap--primary above). Scoped to desktop only, per the gate —
   mobile has no comp and already gets its own smaller logo width below.
   NAV-1: breakpoint is 1100, not the original gate's 1025 — see the
   canonical note at the `@media (max-width: 1099.98px)` nav block below. */
@media (min-width: 1100px) {
	.kd-site-header .kd-brand-badge {
		align-self: flex-start;
		/* px, not rem (gate round 2): this is a geometric constant tied to the
		   163px-wide, 131px-tall logo art and the 196px mainbar, not a type
		   size — at a 19-20px root font a rem value here outgrows the
		   mainbar's own min-height (also px-anchored, see --kd-mainbar-height)
		   and opens a gap under the header. */
		margin-top: 55.5px;
	}
}

/* ── Classic menu (Appearance → Menus, "Primary") ────────────────────────── */

.kd-menu-wrap {
	display: flex;
}

/* DL-E (nav review): the mainbar row centres its flex children
   (verticalAlignment:center on parts/header.html's group), which is right
   for the 163px-tall logo lockup but puts the single-line nav ~7px lower
   than the comp — Figma's nav baseline sits higher than the logo's own
   vertical centre (nav text top y81 vs the logo box's y45–196 span), not
   at the row's shared centre. Nudge the desktop nav wrap up to match,
   independent of the logo. Desktop-only class (kd-menu-wrap--mobile is the
   off-canvas panel's own vertical list, untouched by this — see the panel's
   own `.kd-mobile-panel__inner` spacing).
   Qualified with the `.kd-mainbar` ancestor (0,2,0), not just the bare
   class (0,1,0) — confirmed live (matched-rules/CSSOM) that WP core's
   flex-layout gap reset, `.is-layout-flex > :is(*, div) { margin: 0px; }`
   (0,1,1), otherwise beats a bare single class and zeroes this back out. */
.kd-mainbar .kd-menu-wrap--primary {
	margin-top: -0.6875rem; /* -11px, live-calibrated against Figma's y81 nav baseline (DynaPuff line-box leading ate the first, smaller pass) */
}

.kd-menu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--kd-nav-gap);
	margin: 0;
	padding: 0;
	list-style: none;
	font-family: var(--kd-nav-font);
	font-weight: var(--kd-nav-weight);
	font-size: var(--kd-nav-size);
}

.kd-menu a {
	color: var(--kd-nav-link) !important;
	text-decoration: none;
	text-transform: capitalize;
	letter-spacing: var(--dfd-track-heading);
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	line-height: 1.2;
	transition: opacity var(--kd-transition-fast);
}

.kd-menu > li > a:hover,
.kd-menu > li > a:focus-visible {
	opacity: var(--kd-nav-link-hover-opacity);
	color: var(--kd-nav-link);
}

/* Desktop dropdowns (unused by the 6 flat DFD nav items, kept generic) */
.kd-menu--primary .menu-item-has-children {
	position: relative;
}

.kd-menu--primary .menu-item-has-children > a::after {
	content: "";
	width: 0.5em;
	height: 0.5em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg) translateY(-1px);
	margin-left: 0.15rem;
	transition: transform var(--kd-transition-fast);
}

.kd-menu--primary .sub-menu {
	position: absolute;
	top: 100%;
	left: 0;
	margin: 0;
	padding: 0.5rem 0;
	list-style: none;
	min-width: var(--kd-dropdown-min-width);
	background: var(--kd-dropdown-bg);
	border-radius: var(--kd-dropdown-radius);
	box-shadow: var(--kd-dropdown-shadow);
	opacity: 0;
	visibility: hidden;
	transform: translateY(8px);
	transition:
		opacity var(--kd-transition-fast),
		transform var(--kd-transition-fast),
		visibility var(--kd-transition-fast);
	z-index: var(--kd-z-overlay);
}

.kd-menu--primary .menu-item-has-children:hover > .sub-menu,
.kd-menu--primary .menu-item-has-children:focus-within > .sub-menu {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

.kd-menu--primary .sub-menu a {
	display: block;
	padding: 0.5rem 1.25rem;
	color: var(--kd-dropdown-link);
	font-weight: 500;
	white-space: nowrap;
}

.kd-menu--primary .sub-menu a:hover,
.kd-menu--primary .sub-menu a:focus-visible {
	color: var(--kd-dropdown-link-hover);
	opacity: 1;
}

/* ── Hamburger (mobile only, <1100px — NAV-1) ─────────────────────────────── */

.kd-hamburger {
	display: none;
	flex-direction: column;
	justify-content: center;
	gap: 5px;
	width: 42px;
	height: 42px;
	padding: 8px;
	background: none;
	border: none;
	cursor: pointer;
}

.kd-hamburger__bar {
	display: block;
	width: var(--kd-burger-width);
	height: var(--kd-burger-bar-height);
	background: var(--kd-burger-bar);
	border-radius: 2px;
	transition:
		transform var(--kd-transition-base),
		opacity var(--kd-transition-base);
}

.kd-hamburger[aria-expanded="true"] .kd-hamburger__bar:nth-child(1) {
	transform: translateY(7.5px) rotate(45deg);
}
.kd-hamburger[aria-expanded="true"] .kd-hamburger__bar:nth-child(2) {
	opacity: 0;
}
.kd-hamburger[aria-expanded="true"] .kd-hamburger__bar:nth-child(3) {
	transform: translateY(-7.5px) rotate(-45deg);
}

/* ── Off-canvas mobile panel (slides in from the right) ─────────────────────── */

.kd-mobile-overlay {
	position: fixed;
	inset: 0;
	background: var(--kd-mobile-overlay-bg);
	opacity: 0;
	visibility: hidden;
	transition:
		opacity var(--kd-mobile-transition),
		visibility var(--kd-mobile-transition);
	z-index: var(--kd-z-mobile-overlay);
}

.kd-mobile-overlay.is-open {
	opacity: 1;
	visibility: visible;
}

.kd-mobile-panel {
	--kd-nav-link: var(--kd-color-base);
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	width: var(--kd-mobile-panel-width);
	max-width: var(--kd-mobile-panel-max);
	background: var(--kd-mobile-panel-bg);
	color: var(--kd-mobile-panel-fg);
	padding: var(--kd-mobile-panel-pad);
	box-shadow: var(--kd-mobile-panel-shadow);
	transform: translateX(100%);
	visibility: hidden;
	transition:
		transform var(--kd-mobile-transition),
		visibility var(--kd-mobile-transition);
	z-index: var(--kd-z-mobile-panel);
	overflow-y: auto;
	-webkit-overflow-scrolling: touch;
}

.kd-mobile-panel.is-open {
	transform: translateX(0);
	visibility: visible;
}

/* Tracker fix (header-lane, DL-B/DL-C gates) — full detail + the separate
   cta-cards-3up overflow finding are in the tracker's DL-E session entry,
   not duplicated here. `:not(.is-open)` (gate round 1 fix): an unscoped
   `display:none` would strand the panel mid-transition (opened below the
   hamburger breakpoint, window resized wider) with
   `body.kd-nav-open{overflow:hidden}` still locked and no way left to
   close it — scoping to the closed state only avoids that while still
   fully excluding it from layout when closed. NAV-1: breakpoint is 1100,
   not the original gate's 1025 — see the canonical note at the
   `@media (max-width: 1099.98px)` nav block below. */
@media (min-width: 1100px) {
	.kd-mobile-panel:not(.is-open),
	.kd-mobile-overlay:not(.is-open) {
		display: none;
	}
}

.admin-bar .kd-mobile-panel {
	top: 32px;
}

@media screen and (max-width: 782px) {
	.admin-bar .kd-mobile-panel {
		top: 46px;
	}
}

.kd-mobile-close {
	position: absolute;
	top: 1.75rem;
	right: 1.25rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	background: rgba(255, 255, 255, 0.12);
	border: none;
	border-radius: 50%;
	color: var(--kd-mobile-panel-fg);
	cursor: pointer;
	padding: 0;
	line-height: 0;
	z-index: 2;
	transition: background-color var(--kd-transition-fast);
}

.kd-mobile-close:hover,
.kd-mobile-close:focus-visible {
	background: rgba(255, 255, 255, 0.22);
}

body.kd-nav-open .kd-hamburger {
	opacity: 0;
	pointer-events: none;
}

.kd-mobile-panel__inner {
	margin-top: 4rem;
}

.kd-menu--mobile {
	flex-direction: column;
	align-items: stretch;
	gap: 0;
	width: 100%;
	font-size: 1.1rem;
}

.kd-menu--mobile li {
	width: 100%;
	border-bottom: 1px solid rgba(255, 255, 255, 0.18);
}

.kd-menu--mobile a {
	color: var(--kd-mobile-panel-fg);
	display: block;
	padding: 0.85rem 0;
	width: 100%;
}

.kd-menu--mobile .menu-item-has-children > a {
	position: relative;
	padding-right: 1.75rem;
	cursor: pointer;
}

.kd-menu--mobile .menu-item-has-children > a::after {
	content: "";
	position: absolute;
	right: 0.35rem;
	top: 50%;
	width: 0.55em;
	height: 0.55em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: translateY(-70%) rotate(45deg);
	transition: transform var(--kd-transition-fast);
}

.kd-menu--mobile .menu-item-has-children.is-expanded > a::after {
	transform: translateY(-30%) rotate(-135deg);
}

.kd-menu--mobile .sub-menu {
	list-style: none;
	margin: 0;
	padding: 0 0 0.5rem 1rem;
	display: none;
}

.kd-menu--mobile .menu-item-has-children.is-expanded > .sub-menu {
	display: block;
}

.kd-menu--mobile .sub-menu li {
	border-bottom: none;
}

.kd-menu--mobile .sub-menu a {
	padding: 0.5rem 0;
	font-size: 1rem;
	opacity: 0.92;
}

/* Lock body scroll while the panel is open */
body.kd-nav-open {
	overflow: hidden;
}

/* Admin-only "assign a menu" hint when a location is empty */
.kd-nav-empty a {
	color: var(--kd-color-contrast);
	font-size: 0.85rem;
	opacity: 0.8;
	text-decoration: underline;
}

/* Narrow-desktop safety margin — 6 nav items + the 163px logo are tight in
   the 1100–1439 band. NAV-1 (2026-09-12): the header gets its own gutter
   (--kd-header-gutter, tokens.css — full formula + calibration there) and
   a flat 48px nav-gap, replacing DL-E's fluid 12→48px ramp; ≥1440
   untouched. See the canonical breakpoint note at the
   `@media (max-width: 1099.98px)` nav-switch block below. */
@media (min-width: 1100px) and (max-width: 1439.98px) {
	.kd-mainbar {
		gap: 0;
		/* Set through the token (gate round 1 fix), not a `gap:` override on
		   `.kd-menu--primary` — `.kd-menu { gap: var(--kd-nav-gap) }`
		   (global, below) already reads this custom property, and it
		   inherits from this ancestor with zero specificity fight. */
		--kd-nav-gap: 48px;
		/* Code review (round 1 gate fix): override the TOKEN, not the
		   property. The base `.kd-mainbar` rule below already reads
		   `padding-left/-right: var(--kd-edge-pad) !important`; redirecting
		   --kd-edge-pad itself to --kd-header-gutter here lets that one
		   base declaration pick up the header's narrower value with no
		   duplicated padding rule and no !important escalation. Confirmed
		   no other element in the header subtree reads --kd-edge-pad (the
		   off-canvas panel uses --kd-mobile-panel-pad), so this can't leak
		   past .kd-mainbar. --kd-header-gutter's own ceiling term
		   deliberately does NOT reference --kd-edge-pad by name — see its
		   definition in tokens.css for why (cyclic custom property). */
		--kd-edge-pad: var(--kd-header-gutter);
	}
}

/* ── Nav responsive switch — ≤1099.98px (not the starter's 768px) ────────────
   NAV-1 (2026-09-12) canonical breakpoint note: raised from the original
   gate's 1024/1025px split. Even with the header's own 24px gutter floor
   (tokens.css --kd-header-gutter), the 6 items at ≥48px gaps don't fit
   single-line below ~1030px live-measured (binary search, zero padding,
   163px logo — see tokens.css's --kd-header-row-need); 1100 gives a clean
   round breakpoint with margin. Every other rule keyed to this switch
   moves WITH it — the desktop-logo block and the mobile-panel
   display:none rule above, the narrow-desktop nav-gap band above, and
   tokens.css's --kd-mainbar-height mobile override — all four say "see
   this note" rather than repeating the rationale. */

@media (max-width: 1099.98px) {
	.kd-menu-wrap--primary {
		display: none;
	}
	.kd-hamburger {
		display: flex;
	}
	.kd-site-header .kd-brand-badge img {
		width: 120px;
	}
}

@media (max-width: 480px) {
	.kd-site-header .kd-brand-badge img {
		width: 96px;
	}
}

/* ══════════════════════════════════════════════════════════════════════════════
   SITE FOOTER — purple band, 4 columns (Figma footer group 10:386)
   ══════════════════════════════════════════════════════════════════════════════ */

.kd-site-footer {
	background-color: var(--kd-color-secondary);
	color: var(--kd-color-base);
	padding-left: var(--kd-edge-pad) !important;
	padding-right: var(--kd-edge-pad) !important;
	/* No min-height: the Figma frame's 496px left ~144px of empty band under
	   the credit line at desktop (Alain, 2026-11-02). Content + padding set the
	   height; bottom padding is spacing|50 (40px) in parts/footer.html. */
}

.kd-site-footer a {
	color: var(--kd-color-base);
}

.kd-site-footer a:hover {
	color: var(--kd-color-base);
	opacity: 0.8;
}

/* Credit link: Medium (500), not bold. A <strong> inside the bold link
   computed to 900, which the Adobe kit doesn't have, so the browser
   faux-bolded the 700 and the word smeared (Alain, 2026-11-02). */
.kd-site-footer .kd-footer-credit {
	font-weight: 500;
}

.kd-footer-heading {
	color: var(--kd-color-base);
	font-size: var(--kd-size-h4); /* 24px */
	letter-spacing: var(--dfd-track-heading);
	margin-top: 0;
	margin-bottom: var(--kd-gap-tight);
}

.kd-footer-columns {
	align-items: flex-start;
	row-gap: var(--kd-space-xl);
	column-gap: var(--kd-space-lg);
}

.kd-footer-col--brand {
	flex: 0 0 auto;
}

.kd-footer-col--brand img {
	/* KID + Family Central lock-up (client, 10-21), 300 × 89 */
	width: 300px;
	max-width: 100%;
	height: auto;
}

.kd-footer-col--contact,
.kd-footer-col--social {
	flex: 0 1 auto;
}

.kd-footer-address,
.kd-footer-ein {
	color: var(--kd-color-base);
	font-family: var(--kd-font-body);
	font-size: 1rem;
	line-height: 1.6;
	max-width: 18rem;
}

.kd-footer-address a {
	text-decoration: underline;
	text-underline-offset: 2px;
}

.kd-footer-ein {
	margin-top: var(--kd-space-md);
}

/* Social icons — pink 62px circles, navy glyph (Kd_Social_Walker auto-detects
   facebook.com / instagram.com / linkedin.com from the "Social" menu's URLs). */
.kd-social-wrap {
	margin-top: var(--kd-space-md);
	display: flex;
	justify-content: flex-start;
}

.kd-social-menu {
	display: flex;
	gap: var(--kd-space-sm);
	margin: 0;
	padding: 0;
	list-style: none;
}

.kd-social-menu .kd-social-item a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 62px;
	height: 62px;
	border-radius: 50%;
	background: var(--kd-color-pink);
	color: var(--kd-color-primary); /* navy glyph */
	transition: background-color var(--kd-transition-fast);
}

.kd-social-menu .kd-social-item a svg {
	width: 26px;
	height: 26px;
	fill: currentColor;
}

.kd-social-menu .kd-social-item a:hover {
	background: var(--kd-color-base);
}

/* Footer pills — stacked, right column (Adopt a Duck yellow / Create a Team navy) */
.kd-footer-col--pills {
	gap: var(--kd-space-sm);
}

.kd-footer-pill .wp-block-button__link {
	white-space: nowrap;
}

.kd-footer-copyright {
	color: var(--kd-color-base);
	font-size: 0.9375rem;
	line-height: 1.55;
	margin-top: var(--kd-space-xl);
}

.kd-footer-copyright a {
	font-weight: 700;
	text-decoration: underline;
}

/* ══════════════════════════════════════════════════════════════════════════════
   RESPONSIVE — footer
   ══════════════════════════════════════════════════════════════════════════════ */

/* Tablet (768–1024, review round 1): the plain flex row orphaned the pills
   column bottom-left under the logo once the row ran out of width. A 2×2
   grid keeps a predictable pairing instead — brand+contact top, social+pills
   bottom, pills right-aligned in its cell. DOM order is brand, contact,
   social, pills, so a 2-col grid auto-places them into exactly that
   arrangement with no explicit grid-area assignment needed. */
@media (min-width: 768px) and (max-width: 1024px) {
	/* !important: WP's block-supports layout generates its OWN per-block
	   stylesheet (.wp-container-core-group-is-layout-XXXX, same 0,1,0
	   specificity as .kd-footer-columns) printed later in the document than
	   this file, so an unweighted override loses the display tie — confirmed
	   live at 1024px, where `display` computed as "flex" despite this rule. */
	.kd-footer-columns {
		display: grid !important;
		grid-template-columns: 1fr 1fr;
		column-gap: var(--kd-space-lg);
		row-gap: var(--kd-space-xl);
	}
	.kd-footer-col--pills {
		justify-self: end;
	}
}

@media (max-width: 767.98px) {
	.kd-footer-columns {
		flex-direction: column;
	}
	.kd-footer-col {
		flex-basis: 100% !important;
		width: 100%;
	}
	.kd-footer-col--pills {
		flex-direction: column !important;
	}
	.kd-footer-col--pills .wp-block-button__link {
		width: 100%;
		text-align: center;
	}
}

/* ── Focus Indicators (Accessibility) ───────────────────────────────────────── */

*:focus-visible {
	outline: 3px solid var(--kd-color-primary);
	outline-offset: 2px;
}

/* Buttons — rounded focus ring */
.wp-block-button__link:focus-visible {
	outline: 3px solid var(--kd-color-primary);
	outline-offset: 3px;
	border-radius: var(--kd-radius-pill);
}

/* On the purple footer band and the navy mobile panel, focus ring switches to
   white for contrast. The header bar (transparent since DL-E, over the hero
   image on Home or the lavender page bg on interior pages) keeps the
   default navy ring in both cases — white would fail contrast against the
   lavender page bg, and navy already reads fine over the hero art. */
.kd-site-footer :focus-visible,
.kd-mobile-panel :focus-visible {
	outline-color: var(--kd-color-base);
}

/* Remove default outline on mouse click */
:focus:not(:focus-visible) {
	outline: none;
}

/* ── Section Spacing ───────────────────────────────────────────────────────── */

/* Owl selector: one --kd-section-gap margin between every pair of stacked
   .entry-content children — groups AND the cover-based CTA band. Applied once,
   regardless of whether the adjacent section is plain or banded/colored.
   First child gets no margin-top (top of page is handled by hero / no-hero
   clearance tokens, which are left untouched). */
.entry-content > * + * {
	margin-block-start: var(--kd-section-gap);
}

/* Zero the trailing margin only. The owl above (--kd-section-gap, specificity
   0,1,0) already beats WP's zero-specificity :where(.is-layout-constrained) > * + *
   block-gap, so the inter-section gap is exactly --kd-section-gap. Do NOT switch
   this to `margin-block:0` — `.entry-content > .wp-block-group` is (0,2,0) and
   would override the owl's margin-block-start, collapsing every gap to zero. */
.entry-content > .wp-block-group {
	margin-block-end: 0;
}

/* Plain sections: no vertical padding — the margin-gap is the only space.
   Banded sections set their own padding-block in their pattern partials. */
.kd-section {
	padding-block: 0;
}

/* Interior-hero pages: <main> has blockGap:0 and the owl above skips the first
   child, so the first content section would butt directly against the hero.
   Give it one rhythm unit of separation below the hero.

   Applies under BOTH heroes, but keyed on what the first child actually is
   rather than on which hero precedes it. A full-bleed (.alignfull) band is
   meant to run flush to the hero — that was the original reason home was
   excluded wholesale. Any ordinary constrained section is not, and was landing
   with 0px against the hero because the section-rhythm owl selector
   (> * + *) skips the first child by design. */
main:has(.kd-hero-interior) .entry-content > :first-child,
main:has(.kd-hero-home) .entry-content > :first-child:not(.alignfull) {
	margin-block-start: var(--kd-section-gap);
}

.entry-content > .wp-block-group > *:first-child {
	margin-top: 0;
}

.entry-content > .wp-block-group > *:last-child {
	margin-bottom: 0;
}

/* Section header → content gap */
.kd-section-header {
	margin-bottom: 65px !important;
	max-width: 36rem;
	margin-left: auto;
	margin-right: auto;
}

.kd-section-header h2 {
	margin-bottom: var(--kd-gap-tight) !important;
}

.kd-section-header p {
	margin-top: 0 !important;
}

/* ── Kill WP default 24px margin between site-level blocks ───────────────── */

.wp-site-blocks > * {
	margin-block-start: 0;
}

/* ── Interior Page Hero ────────────────────────────────────────────────────── */

.kd-hero-interior {
	width: 100%;
	align-items: flex-start !important; /* top-anchor content vertically (cover cross-axis) */
	min-height: var(
		--kd-hero-interior-min
	) !important; /* beat the cover's inline min-height */
	/* Brand gradient is the default; a Featured Image (raster OR svg) overrides it. */
	background: var(--kd-color-contrast) url("../images/hero-gradient.svg")
		center / cover no-repeat;
	/* Match the header/footer band: edge-pad gutter; the inner caps at content-max. */
	padding-inline: var(--kd-edge-pad) !important;
	padding-top: var(
		--kd-hero-content-top
	) !important; /* breadcrumb 50px below the badge */
}

/* No Featured Image → show the brand gradient clean (kill the dark legibility wash). */
.kd-hero-interior:not(:has(img)) .wp-block-cover__background {
	background: transparent !important;
	opacity: 1 !important;
}

/* Featured Image set → keep the left-to-right wash so white text stays legible. */
.kd-hero-interior:has(img) .wp-block-cover__background {
	background: linear-gradient(
		to right,
		rgba(0, 0, 0, 0.6) 0%,
		rgba(0, 0, 0, 0.35) 50%,
		transparent 100%
	) !important;
	opacity: 1 !important;
}

/* Hero content aligns to the same gutter + max-width as the rest of the site. */
.kd-hero-interior .wp-block-cover__inner-container {
	max-width: var(--kd-content-max);
	margin: 0 auto;
	width: 100%;
}

.kd-hero-interior .wp-block-post-title {
	font-family: var(--kd-font-heading);
	font-weight: var(--kd-fw-heading);
	font-size: var(--kd-size-banner);
	color: var(--kd-color-base);
	line-height: var(--kd-lh-tight);
	margin-top: var(--kd-space-sm);
	margin-bottom: 0;
}

.kd-hero-subtitle {
	margin-top: 2rem;
	max-width: 36rem;
}

/* Sticky footer — the wrapper fills the viewport so the footer sits at the bottom
   on short pages. `main` grows to take the slack; the hero keeps its own height
   (it's min-height, not flex-stretched), so hero sections are unaffected. */
.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.wp-site-blocks > main {
	flex: 1 0 auto;
}

/* Pages WITHOUT a hero (no-hero pages, CPT archives, posts) get top clearance so
   content doesn't collide with the badge that overflows the bar. Hero templates
   are auto-exempt — the badge is meant to spill onto the hero. */
.wp-site-blocks > main:not(:has(.kd-hero-interior)):not(:has(.kd-hero-home)) {
	padding-top: var(--kd-no-hero-top);
}

/* PG1: Home's hero is page content now (dfd/hero-campaign, via wp:post-content),
   not the starter's .kd-hero-home part, so it no longer trips the `:not(:has(...))`
   exemption above — main was picking up the full --kd-no-hero-top (134px) clearance
   meant for hero-LESS pages. The comp has the hero flush under the header (bg from
   y0). `kd-main--home` (front-page.html) opts Home back out — but the rule above
   is (0,3,1) specificity (2 chained :not(:has(.class)), each counting as a class,
   + the .wp-site-blocks class + the main tag), so a single extra class here is
   (0,2,1) and LOSES to it regardless of source order. `.kd-main--home` doubled
   below (a same-class repeat, not a typo) brings this selector to the same
   (0,3,1) — then source order (this rule is declared after) wins the tie, no
   !important needed. */
.wp-site-blocks > main.kd-main--home.kd-main--home {
	padding-top: 0;
}

/* PG2 — comp 12:905 y254: the Adopt a Duck page (`templates/page.html`,
   `.kd-main--no-hero`) wants the header→first-section gap at 58px, not the
   sitewide 134px no-hero clearance above (that value clears the badge
   overflow for pages designed against it; this page's first section is a
   plain card with no badge collision). `templates/page.html` is shared by
   every interior page (Sponsors/Gallery/FAQs too) and none of those have a
   comp of their own, so 58px becomes the system value for this template —
   intended, not a PG2-only leak. Scoped as a custom-property override on
   the same `main` element: tokens.css sets --kd-no-hero-top at `:root`,
   specificity (0,1,0); this selector's (0,2,1) wins outright, no
   !important needed. Kept local to global.css rather than editing the
   token itself in tokens.css, so --kd-no-hero-top stays available at its
   original 134px for anything else that references it directly. */
.wp-site-blocks > main.kd-main--no-hero {
	--kd-no-hero-top: 3.625rem; /* 58px */
}

/* ── Breadcrumb ──────────────────────────────────────────────────────────── */

.kd-breadcrumb {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: 0.5rem;
	font-size: 1.125rem;
	line-height: 1;
	color: var(--kd-color-base);
}

.kd-breadcrumb__home {
	color: var(--kd-color-base);
	opacity: 0.7;
	display: flex;
	align-items: center;
	text-decoration: none;
	transition: opacity 0.2s ease;
}

.kd-breadcrumb__home:hover {
	opacity: 1;
	color: var(--kd-color-base);
}

.kd-breadcrumb__sep {
	opacity: 0.7;
	display: flex;
	align-items: center;
}

.kd-breadcrumb__link {
	color: var(--kd-color-base);
	opacity: 0.7;
	text-decoration: none;
	transition: opacity 0.2s ease;
}

.kd-breadcrumb__link:hover {
	opacity: 1;
	color: var(--kd-color-base);
}

.kd-breadcrumb__current {
	opacity: 0.9;
}

/* ══════════════════════════════════════════════════════════════════════════════
   RESPONSIVE — Tablet (≤1024px)
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 1024px) {
	/* h1/h2/h3 are NOT overridden here — --wp--preset--font-size--huge and
	   --xxx-large are already fluid (clamp()), which is the one spec every
	   pattern references (theme-conventions.md). A fixed breakpoint override
	   here would re-declare that spec and drift from it. */

	/* Hero — reduce min-height on tablet (starter default cover hero; DFD's
	   own hero-campaign pattern, S1, sets its own responsive rules) */
	.wp-block-cover {
		min-height: 50vh !important;
	}

	/* Buttons — slightly smaller on tablet */
	.wp-block-button__link,
	.kd-btn {
		padding: 1.125rem 1.75rem;
		font-size: 1.25rem;
	}
}

/* ══════════════════════════════════════════════════════════════════════════════
   RESPONSIVE — Mobile (≤768px)
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 768px) {
	/* h1/h2/h3 — see the ≤1024 note; the clamp() spec already floors at 32px. */

	/* Hero — shorter on mobile */
	.wp-block-cover {
		min-height: 40vh !important;
	}

	.wp-block-cover__inner-container {
		padding-left: var(--kd-space-md) !important;
		padding-right: var(--kd-space-md) !important;
	}

	/* Buttons — keep inline, slightly smaller */
	.wp-block-button__link,
	.kd-btn {
		padding: 1rem 1.5rem;
		font-size: 1.125rem;
	}

	.kd-section-header {
		margin-bottom: 32px !important;
	}
}

/* ══════════════════════════════════════════════════════════════════════════════
   RESPONSIVE — Small phones (≤480px)
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-width: 480px) {
	.kd-section-header {
		margin-bottom: var(--kd-space-sm) !important;
	}
}

/* ══════════════════════════════════════════════════════════════════════════════
   RESPONSIVE — Landscape orientation (short viewports)
   ══════════════════════════════════════════════════════════════════════════════ */

@media (max-height: 500px) and (orientation: landscape) {
	.wp-block-cover {
		min-height: 60vh !important;
	}
}

/* ── Link contrast on light surfaces ──────────────────────────────────────────
   Embolden Blue (#2383EB) on white measures 3.81:1 — it FAILS WCAG AA (4.5:1)
   for normal-size text. It passes AA Large (3:1), so it stays correct for
   buttons and large display text, but body-size links need a darker value.
   --kd-color-link is that value: Anchor Navy, 14.6:1 on white. Change this
   token, not the brand primary, if a client needs a different link colour. */
:root {
	--kd-color-link: var(--kd-color-contrast);
}

.entry-content a:not(.wp-element-button):not([class*="kd-btn"]),
.kd-site-footer .kd-menu-wrap a,
.kd-card a {
	color: var(--kd-color-link);
}

/* ── Skip link (WCAG 2.4.1 Bypass Blocks) ─────────────────────────────────────
   With a two-tier nav plus a hero sub-nav, a keyboard user otherwise tabs
   through 15+ links before reaching content on EVERY page. QA-3 fix 7: the
   theme used to render its own "Skip to main content" link (.kd-skip-link)
   here, duplicating the "Skip to content" link core already emits on
   wp_body_open (the_block_template_skip_link(), styled + focus-managed by
   core) — both targeted #kd-main. Dropped the theme's copy; core's is now
   the only skip link. .screen-reader-text stays: core's own skip link (and
   four other spots in this theme) uses that class, and it isn't defined by
   core's block-library stylesheet — the theme has always had to supply it. */
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}
