/*
 * Scott Pool 2026 -- page-content components (Phase 3: Meet Scott).
 *
 * Targets the block markup on the "Meet Scott" page: eyebrow labels,
 * image+text intro, the top-rule card grid used for "His Experience" and
 * "Why Scott?", pull quotes, and the closing callout banner. Ported from
 * the Scott Pool Campaign Design System's components/content.css and
 * components/typography.css, re-expressed in this theme's existing token
 * names (--wp--preset--*, tokens.css semantic aliases) -- no new color,
 * font, spacing, or motion values introduced. Reuses assets/css/base.css's
 * .sp-container / .sp-section / .sp-grid utilities and the is-style-sp-*
 * button variations already registered for the header/hero.
 */

/* ===== Eyebrow label ===== */

.sp-eyebrow {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-weight: 700;
	font-size: var(--wp--preset--font-size--eyebrow);
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--campaign-red);
	margin: 0 0 var(--wp--preset--spacing--4);
}

.sp-heading__rule {
	display: block;
	width: 56px;
	height: var(--border-width-accent);
	background: var(--wp--preset--color--campaign-red);
	border: 0;
	margin: var(--wp--preset--spacing--5) 0 0;
}

/* ===== Desktop / mobile copy toggle (matches the Hero's own
   sp-hero__lede--desktop/--mobile technique and breakpoint) ===== */

.sp-copy--desktop-only { display: none; }
.sp-copy--mobile-only { display: block; }
@media (min-width: 1024px) {
	.sp-copy--desktop-only { display: block; }
	.sp-copy--mobile-only { display: none; }
}

/* ===== Image + text section ===== */

.sp-imagetext {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--wp--preset--spacing--16);
	align-items: center;
}
.sp-imagetext__media {
	overflow: hidden;
	background: var(--wp--preset--color--off-white);
}
.sp-imagetext__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform var(--duration-slow) var(--ease-out);
}
.sp-imagetext__media:hover img {
	transform: scale(var(--hover-image-scale));
}

@media (max-width: 1023px) {
	.sp-imagetext { grid-template-columns: minmax(0, 1fr); gap: var(--wp--preset--spacing--10); }
}

/* ===== Top-rule card (His Experience / Why Scott? grids) ===== */

.sp-rule-card {
	border-top: var(--border-width-rule) solid var(--wp--preset--color--primary-navy);
	padding-top: var(--wp--preset--spacing--5);
}
.sp-rule-card__title {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--h4);
	font-weight: 800;
	color: var(--wp--preset--color--primary-navy);
	margin: 0 0 var(--wp--preset--spacing--3);
}
.sp-rule-card__body {
	font-size: var(--wp--preset--font-size--body-sm);
	color: var(--text-body);
	margin: 0;
}

/* ===== Pull quote ===== */

.sp-quote {
	/* Phase 30C: was `margin: 0`, which left the red-ruled quote flush
	   against the "In Scott's Words" heading (the rule visually touched
	   the heading). A normal heading-to-content gap now sits above it. */
	margin: var(--wp--preset--spacing--6) 0 0;
	padding: 0 0 0 var(--wp--preset--spacing--6);
	border-left: var(--border-width-accent) solid var(--wp--preset--color--campaign-red);
}
.sp-quote__text {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--h4);
	font-weight: 600;
	line-height: 1.3;
	color: var(--wp--preset--color--primary-navy);
	margin: 0;
}
.sp-quote__attribution {
	display: block;
	margin-top: var(--wp--preset--spacing--4);
	font-family: var(--wp--preset--font-family--text);
	font-size: var(--wp--preset--font-size--body-sm);
	font-weight: 600;
	color: var(--text-body); /* was --text-muted (3.52:1 on white, fails WCAG AA); --text-body is #33415C, 10.24:1 on white */
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

/* Campaign-team feedback (Phase 12): .sp-quote__text's own display-font/
   600-weight/h4-size treatment was built for a short, punchy pull-quote
   (see Meet Scott's two genuine testimonial quotes, unchanged) -- applying
   it unmodified to "Why I Decided"'s multi-sentence prose paragraphs (same
   class, per Phase 11's "preserve existing component design" instruction)
   reads as too heavy for body copy at that length. Scoped modifier,
   added only to those two paragraphs' own className (Home page content),
   so Meet Scott's actual quotes keep their original bold treatment. Only
   font-weight changes, to the site's normal body-text weight (400);
   family/size/color/layout are all still inherited from .sp-quote__text
   above, unchanged. */
.sp-quote__text--prose {
	font-weight: 400;
}

/* Phase 30C -- Meet Scott "In Scott's Words": give the section a clearer
   top break so it reads as a new major page section. base.css gives the
   section spacing--12 (48px) top padding on mobile; that fell short of the
   separation the section needs and is raised to spacing--16 (64px) at
   phone widths. Tablet and desktop keep base.css's spacing--20 (80px),
   which already sits inside the target band. Scoped via :has() to the one
   section that carries the pull quote -- a pattern the theme already uses
   in header.css. The heading-to-quote gap also eases back one step here. */
@media (max-width: 767px) {
	.sp-section:has(.sp-quote) {
		padding-top: var(--wp--preset--spacing--16);
	}
	.sp-quote {
		margin-top: var(--wp--preset--spacing--5);
	}
}

/* ===== Closing callout banner ===== */

.sp-callout {
	background: var(--wp--preset--color--primary-navy);
	color: var(--text-on-inverse);
	padding: var(--wp--preset--spacing--20) 0;
}
.sp-callout h2 {
	color: var(--wp--preset--color--white);
}
.sp-callout__actions {
	margin-top: var(--wp--preset--spacing--8);
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--4);
}

@media (max-width: 767px) {
	.sp-callout { padding: var(--wp--preset--spacing--16) 0; }
	.sp-callout__actions { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--wp--preset--spacing--3); }
}

@media (prefers-reduced-motion: reduce) {
	.sp-imagetext__media img { transition-duration: 1ms; }
}

/*
 * Phase 4 -- remaining interior pages (Issues & Vision, About the Office,
 * Donate, Volunteer, Contact, News & Events). Same porting method as
 * everything above: design system classes/values, re-expressed in this
 * theme's existing tokens, nothing invented.
 */

/* ===== Interior page hero (consistent opening treatment) ===== */

.sp-page-hero {
	background: var(--surface-muted);
	border-bottom: var(--border-width-hairline) solid var(--border-subtle);
	padding: var(--wp--preset--spacing--16) 0 var(--wp--preset--spacing--10);
}
.sp-page-hero__lede {
	margin-top: var(--wp--preset--spacing--5);
	font-size: var(--wp--preset--font-size--body-lg);
	color: var(--text-body);
	max-width: 640px;
	/* Core's own constrained-layout rule
	   (.is-layout-constrained > :where(:not(.alignleft)...)) sets
	   margin-left/right: auto !important on any non-aligned child --
	   harmless for the eyebrow/H1 above (no max-width, so they already
	   fill the container and auto-margins resolve to 0), but this
	   paragraph's own narrower max-width let that rule center it,
	   knocking it out of the eyebrow/H1's left edge. !important is
	   required to beat core's own !important (confirmed via computed-style
	   inspection: this rule was the actual source, not our own CSS). */
	margin-left: 0 !important;
	margin-right: 0 !important;
}
@media (max-width: 767px) {
	.sp-page-hero { padding: var(--wp--preset--spacing--10) 0 var(--wp--preset--spacing--8); }
}

/* ===== Numbered priority item (Scott's Vision / commitments) ===== */

.sp-priority {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--wp--preset--spacing--8);
	padding: var(--wp--preset--spacing--8) 0;
	border-top: var(--border-width-rule) solid var(--wp--preset--color--primary-navy);
}
/* .sp-priority__num: decorative 01-04 numerals removed from markup Phase 18
   (were aria-hidden or missing it inconsistently, and forced the 96px 1fr
   column that pushed title/body right). Rule kept in case a future design
   pass reintroduces a numeral treatment; currently unused. */
.sp-priority__num {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--h1);
	font-weight: 800;
	line-height: 1;
	color: var(--wp--preset--color--pale-steel);
}
.sp-priority__title {
	font-family: var(--wp--preset--font-family--display);
	font-size: 36px;
	font-weight: 800;
	color: var(--wp--preset--color--primary-navy);
	margin: 0 0 var(--wp--preset--spacing--3);
}
.sp-priority__body {
	margin: 0;
	color: var(--text-body);
}
/* Phase 23: the homepage "Scott's Priorities" cards carry multi-paragraph
   bodies now (were a single sentence each). .sp-priority__body's own
   `margin: 0` above beats core's flow-layout blockGap, so stacked
   paragraphs would otherwise butt together with no gap. Restore a
   related-content gap (16px) between consecutive body paragraphs only --
   two classes beat the single-class `margin: 0` rule. Unchanged for the
   single-paragraph uses of this component elsewhere. */
.sp-priority__body + .sp-priority__body {
	margin-block-start: var(--wp--preset--spacing--4);
}
@media (max-width: 767px) {
	.sp-priority { grid-template-columns: minmax(0, 1fr); gap: var(--wp--preset--spacing--2); padding: var(--wp--preset--spacing--6) 0; }
	.sp-priority__title { font-size: 30px; }
}

/* ===== Bordered card (Myth vs. Fact, generic content grouping) ===== */

.sp-card {
	background: var(--surface-card);
	border: var(--border-width-hairline) solid var(--border-subtle);
	padding: var(--wp--preset--spacing--6);
}
.sp-card p:last-child { margin-bottom: 0; }
/* Body copy's own font-weight (300) puts <strong>'s UA-default "bolder"
   keyword in the 100-349 lookup bucket, which resolves to 400 -- only one
   step up, not an actual bold weight, so labels like "Myth:"/"Fact:" (and
   the "Does not X." lead-ins in the Does/Does Not cards) never visually
   read as bold despite already being correctly, narrowly wrapped in
   <strong> in the content itself (confirmed via computed-style inspection
   -- no markup change needed, just a real bold weight). Scoped to .sp-card
   only, not <strong> sitewide. */
.sp-card strong {
	font-weight: 700;
}

/* ===== FAQ accordion ===== */

.sp-faq {
	border-top: var(--border-width-hairline) solid var(--wp--preset--color--info-blue);
}
.sp-faq__item {
	border-bottom: var(--border-width-hairline) solid var(--border-subtle);
}
.sp-faq__trigger {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--wp--preset--spacing--6);
	background: transparent;
	border: 0;
	cursor: pointer;
	text-align: left;
	padding: var(--wp--preset--spacing--6) 0;
	min-height: var(--touch-min);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--h4);
	font-weight: 700;
	color: var(--wp--preset--color--info-blue);
	transition: color var(--duration-fast) var(--ease-out);
}
.sp-faq__trigger:hover { color: var(--wp--preset--color--primary-navy); }
.sp-faq__sign {
	font-family: var(--wp--preset--font-family--text);
	font-size: var(--wp--preset--font-size--h4);
	color: var(--wp--preset--color--secondary-navy);
	transition: transform var(--duration-base) var(--ease-out);
	flex-shrink: 0;
}
.sp-faq__item.is-open .sp-faq__sign { transform: rotate(45deg); }
/* grid-template-rows 0fr -> 1fr replaces a fixed max-height cap (was
   640px) -- content-aware, so an answer of any length expands to its
   real height with no clipping ceiling, while still animating smoothly
   with the same motion tokens. No JS or markup changes needed: faq.js's
   existing .is-open toggle and .sp-faq__panel-inner's existing wrapper
   div are exactly what this technique requires. */
.sp-faq__panel {
	display: grid;
	grid-template-rows: 0fr;
	transition: grid-template-rows var(--duration-slow) var(--ease-out);
}
.sp-faq__item.is-open .sp-faq__panel { grid-template-rows: 1fr; }
.sp-faq__panel-inner {
	overflow: hidden;
	min-height: 0; /* lets the grid row's inner content shrink below its natural height during the transition */
	/* Bottom padding only applies open -- min-height:0 lets the box shrink
	   below its content height, but padding still occupies space at any
	   height, so a static bottom padding here would leave a residual gap
	   even when the row is collapsed to 0fr. Toggling it via .is-open
	   (transitioning alongside the same duration/easing token) restores
	   a true 0-height closed state without changing the open-state
	   spacing at all -- still the same --spacing--6 the design always used. */
	padding: 0;
	transition: padding-bottom var(--duration-slow) var(--ease-out);
}
.sp-faq__item.is-open .sp-faq__panel-inner {
	padding-bottom: var(--wp--preset--spacing--6);
}
.sp-faq__panel-inner p { margin: 0; color: var(--text-body); }
@media (max-width: 767px) {
	.sp-faq__trigger { font-size: var(--wp--preset--font-size--h4); padding: var(--wp--preset--spacing--5) 0; }
}

/* ===== Forms (Volunteer signup, Contact) -- prototype UI, not wired to a
   backend; every field is real, labeled, and keyboard-accessible so a form
   plugin/CRM can be dropped in later without redesigning. ===== */

.sp-field { display: block; margin-bottom: var(--wp--preset--spacing--5); }
.sp-field[hidden] { display: none; } /* restores the native [hidden] behavior .sp-field's own `display: block` otherwise overrides. */
.sp-field__label {
	display: block;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--label);
	font-weight: 700;
	color: var(--wp--preset--color--primary-navy);
	margin-bottom: var(--wp--preset--spacing--2);
}
.sp-field__req { color: var(--wp--preset--color--campaign-red); margin-left: 4px; }
.sp-field__hint { display: block; font-size: var(--wp--preset--font-size--legal); color: var(--text-muted); margin-bottom: var(--wp--preset--spacing--2); }
.sp-input, .sp-textarea {
	width: 100%;
	min-height: var(--touch-min);
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
	background: var(--wp--preset--color--white);
	border: var(--border-width-hairline) solid var(--border-default);
	border-radius: var(--radius-sm);
	font-family: var(--wp--preset--font-family--text);
	font-size: var(--wp--preset--font-size--body-sm);
	color: var(--text-heading);
	transition: border-color var(--duration-fast) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);
}
.sp-input:hover, .sp-textarea:hover { border-color: var(--wp--preset--color--secondary-navy); }
.sp-textarea { min-height: 132px; resize: vertical; line-height: 1.6; }

.sp-check { display: flex; align-items: flex-start; gap: var(--wp--preset--spacing--3); min-height: var(--touch-min); cursor: pointer; }
.sp-check input { width: 22px; height: 22px; margin: 11px 0 0; accent-color: var(--wp--preset--color--primary-navy); flex: none; }
.sp-check__label { font-size: var(--wp--preset--font-size--body-sm); color: var(--text-body); padding-top: 10px; }

.sp-note { display: flex; gap: var(--wp--preset--spacing--3); padding: var(--wp--preset--spacing--4); background: var(--surface-muted); font-size: var(--wp--preset--font-size--body-sm); color: var(--text-body); }
.sp-note--success { background: var(--feedback-success-bg); color: var(--feedback-success); }

.sp-chipgroup { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--3); }
.sp-chip {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: var(--touch-min);
	padding: var(--wp--preset--spacing--3) var(--wp--preset--spacing--4);
	background: var(--wp--preset--color--white);
	border: var(--border-width-hairline) solid var(--border-default);
	border-radius: var(--radius-none);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--body-sm);
	font-weight: 600;
	color: var(--wp--preset--color--primary-navy);
	text-decoration: none;
	cursor: pointer;
	transition: background-color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}
.sp-chip:hover { border-color: var(--wp--preset--color--primary-navy); }

/* ===== Meet Scott: His Experience photo layout ===== */

.sp-experience-layout {
	display: grid;
	gap: var(--wp--preset--spacing--10);
}
/* Phase 14: root cause of the photo/text misalignment finally found -- it
   was never the photo. .sp-experience-layout's own block ships
   layout:{"type":"default"} (flow), which stamps core's
   `.wp-block-group-is-layout-flow` class on it; `:where(...) > *` then adds
   the usual 32px blockGap as margin-block-start to every child after the
   first, regardless of this file's own display:grid override (margin isn't
   layout-mode-specific -- the identical bug already fixed on
   .sp-hero/.sp-hero + .sp-section in hero.css and .sp-footer__inner in
   footer.css). .sp-experience-photo-wrap is the first child (exempt);
   .sp-grid.sp-grid--2 (the four text cards) is the second, and measured
   ~68px lower than the photo as a result -- not the ~32px base blockGap
   alone, compounded with this rule's own explicit `gap` above stacking on
   top of it. Zeroed unconditionally, matching the same reasoning as the
   footer fix: `gap` above already controls all the spacing that's
   actually wanted here. */
.sp-experience-layout > * {
	margin-block-start: 0;
}
.sp-experience-photo {
	overflow: hidden;
	border: var(--border-width-hairline) solid var(--border-subtle);
}
.sp-experience-photo img {
	display: block;
	width: 100%;
	/* Source photo's own true ratio (1290x1691), not the 3:4 approximation
	   used before Phase 13 -- close enough that it rarely mattered, but
	   measuring the team's actual mockup screenshot pixel-for-pixel (Phase
	   13) showed the photo box at almost exactly this ratio with no
	   cropping, so using it directly needs none either. */
	aspect-ratio: 1290 / 1691;
	object-fit: cover;
	object-position: 50% 25%;
}
@media (min-width: 1024px) {
	/* align-items:start is unchanged and confirmed correct (Phase 15
	   live-DOM measurement, cross-checked again Phase 16 against the
	   team's current screenshot pixel-for-pixel: the photo's own top edge
	   and the rule above "Military Service" land within ~2px of each
	   other already -- effectively the same line). What still needed
	   fixing was the bottom: at the natural aspect-ratio height (367px,
	   base rule above), the photo ended mid-way through the lower-left
	   card's paragraph, short of that paragraph's actual last line
	   ("families face navigating complex property tax rules"), measured
	   directly off the team's screenshot. */
	.sp-experience-layout { grid-template-columns: 280px 1fr; align-items: start; }
	/* Explicit px height, not a percentage of anything -- the same
	   deliberate choice as the hero portrait's fix (hero.css), avoiding
	   the percentage/auto-track fragility that broke this exact element
	   twice before (Phase 12/13). 430px (up from the natural 367px)
	   extends the photo down to that last line, measured against the
	   team's screenshot. Fixed width (280px, unchanged) means object-fit:
	   cover now crops a modest, even amount off both sides of the source
	   photo to fill the taller box, rather than distorting it -- the
	   "tiny controlled crop" this task explicitly allowed; top/bottom
	   framing (object-position) is untouched, so nothing is cut from the
	   top or bottom of the shot. */
	.sp-experience-photo-wrap,
	.sp-experience-photo {
		height: 430px;
	}
	.sp-experience-photo img {
		height: 100%;
		aspect-ratio: auto;
	}
}
/* Wraps .sp-experience-photo (untouched above -- same border/overflow/image
   treatment as before) together with the military-photo disclaimer that
   now sits directly beneath it, so the pair moves as one unit. Takes over
   the responsive width/centering .sp-experience-photo used to carry alone,
   so the caption always matches the photo's own width instead of
   stretching to the full grid-column/container width. */
@media (max-width: 1023px) {
	.sp-experience-photo-wrap { max-width: 240px; margin: 0 auto; }
}
.sp-photo-disclaimer {
	margin: var(--wp--preset--spacing--3) 0 0;
	font-size: var(--wp--preset--font-size--caption);
	font-style: italic;
	line-height: 1.5;
	color: var(--text-body); /* not --text-muted: that token is already flagged elsewhere in this file as failing WCAG AA (3.52:1) -- --text-body is 10.24:1 on white, stays legible while font-size/style alone read as secondary/caption. */
}

/* ===== Page-bottom legal/tax disclaimer (About the Office) =====
   Same secondary-text treatment as .sp-photo-disclaimer above (font-size--legal
   instead of --caption -- one step smaller, matching the footer disclaimer's
   own size -- since this sits at the true bottom of the page rather than
   directly under a photo), plus a hairline top rule to separate it from the
   page's last content section now that it's no longer part of the intro. */
.sp-page-disclaimer {
	margin: var(--wp--preset--spacing--10) 0 0;
	padding-top: var(--wp--preset--spacing--5);
	border-top: var(--border-width-hairline) solid var(--border-subtle);
	font-size: var(--wp--preset--font-size--legal);
	font-style: italic;
	line-height: 1.5;
	color: var(--text-body); /* not --text-muted: flagged elsewhere in this file as failing WCAG AA (3.52:1) -- --text-body is 10.24:1 on white. */
}

/* ===== Integration-needed placeholder flag (Donate/Volunteer/Contact) =====
   Visually distinct from the sp-legal editorial-note style used during
   drafting -- this one is an intentional, staff-editable placeholder meant
   to stay in the page until a real destination/processor is supplied, not
   an internal comment to strip before publish. */

.sp-todo-flag {
	display: inline-flex;
	align-items: center;
	gap: var(--wp--preset--spacing--2);
	padding: var(--wp--preset--spacing--2) var(--wp--preset--spacing--4);
	border: var(--border-width-hairline) dashed var(--border-default);
	border-radius: var(--radius-sm);
	font-family: var(--wp--preset--font-family--text);
	font-size: var(--wp--preset--font-size--legal);
	font-weight: 600;
	color: var(--text-muted);
	background: var(--surface-muted);
}

/* ===== Donate page banner -- full artwork, no crop at any width ===== */

/* width:auto (not 100%) deliberately -- on Home's alignfull instance,
   100% resolved against the post-padding content box (before the
   .has-global-padding > .alignfull negative-margin bleed below gets a
   chance to reclaim that space), capping the section short of the true
   edge even after the padding/figure fixes below. display:block's own
   default width:auto already fills 100% of the *final* available box
   (after margins), which is what both this alignfull-on-Home and
   plain-constrained-on-Donate contexts actually need -- verified
   unchanged on Donate (see breakpoint tests). */
/* Phase 14 added a border-bottom divider here; Phase 15 moved it back to
   .sp-hero's own bottom edge (hero.css) per team feedback -- it belongs
   at the transition into Meet Scott, not under the banner. */
.sp-donate-banner { display: block; }
.sp-donate-banner img {
	display: block;
	width: 100%;
	height: auto;
	/* Phase 13: reported blur investigated -- the source file itself
	   (donate-page-banner.jpg) is a correct, high-quality 1920x600 asset;
	   checksummed identical to the "original" file the team re-sent, and
	   "full" size (not a smaller generated thumbnail) is what the block
	   already uses, so neither is the cause. Root cause is this rule's own
	   width:100% with no cap: on any viewport wider than the image's own
	   1920px, the browser has to upscale the bitmap past its native
	   resolution to fill the section edge-to-edge, which is visible
	   softness/blur, worse the wider the screen. max-width caps it at
	   native resolution -- full-bleed unchanged below 1920px (which covers
	   the vast majority of real screens), centered instead of stretched
	   above it. Per instructions, not upscaling beyond native quality --
	   there is no higher-resolution source available to fix any remaining
	   softness on very wide/high-DPI screens beyond this. */
	max-width: 1920px;
	margin: 0 auto;
}
/* This block's own layout type is "constrained" (unlike e.g. .sp-hero's
   "default"/flow), so core stamps it with `.has-global-padding` and adds
   the site's root-padding gutter (24px) as real left/right padding on the
   alignfull section itself -- intentional core behavior for most
   constrained-layout full-width sections, but here it left visible white
   margins on both sides of what's meant to be an edge-to-edge banner
   graphic (confirmed via computed-style/matching-rule inspection: no
   separate max-width/centering on the <img>, just this section padding).
   Scoped to .sp-donate-banner specifically -- doesn't touch
   .has-global-padding or constrained-layout behavior anywhere else on the
   site. */
.sp-donate-banner.has-global-padding {
	padding-left: 0;
	padding-right: 0;
}
/* Second, independent layer of the same "constrained" layout type: core
   also caps the image's own <figure> wrapper (no align class of its own)
   at max-width:var(--wp--style--global--content-size) with !important
   auto margins, via .is-layout-constrained > :where(:not(.alignleft)...).
   !important required to beat core's own !important (same pattern as the
   .sp-page-hero__lede fix elsewhere in this file). Scoped to the figure
   inside .sp-donate-banner only. */
.sp-donate-banner figure {
	max-width: none;
	margin-left: 0 !important;
	margin-right: 0 !important;
}

@media (prefers-reduced-motion: reduce) {
	.sp-faq__sign, .sp-faq__panel { transition-duration: 1ms; }
}

/* ===================================================================
   Phase 23.2B -- homepage design-correction pass (audit 23.2A).
   .home-scoped: .sp-priority*, .sp-experience-*, .sp-callout__actions are
   all shared with interior pages (Issues & Vision, Meet Scott), which stay
   as-is.
   =================================================================== */

/* 2. Section H2 must clearly outrank the four priority H3s at every
   breakpoint. Before: H2 fluid min 26px vs a hard 30px .sp-priority__title
   on mobile -- the section title was *smaller* than its own subsection
   titles. H2 gets a fluid ramp with a 30px floor; .sp-priority__title
   (a hard 36/30px, and on Issues & Vision it styles top-level H2s, so this
   is .home-only) gets a ramp that stays ~1.25-1.4x below the section H2
   (30/22.7 at ~390, 37/30 at ~1024, 42/30 at ~1440). Semantic H2/H3
   markup is unchanged. */
.home .sp-section > .sp-container > h2,
.home .sp-section > .sp-container--prose > h2,
.home .sp-callout > .sp-container--prose > h2,
/* Phase 30F: "A Property Appraiser's Office" H2 moved one level deeper
   (.sp-container > .sp-appraiser > .sp-appraiser__body > h2) by the new
   two-column split -- added here so it keeps the same size as every
   other homepage section heading instead of falling back to the
   smaller default. */
.home .sp-appraiser__body > h2 {
	font-size: clamp(30px, calc(25.5px + 1.14vw), 42px);
	line-height: 1.15;
}
.home .sp-priority__title {
	/* Phase 23.3: nudged down a step (was clamp(22px..30px)). The cards now
	   carry a border + red accent, so each item title reads as a stronger
	   unit -- keep it clearly subordinate to the "Scott's Priorities" H2
	   (~1.5x at 390 and 1440, ~1.35x at 1024). Still bold display navy. */
	font-size: clamp(20px, calc(16.8px + 1vw), 28px);
}

/* 7. Scott's Priorities -- restrained emphasis on each card's existing
   closing takeaway sentence (wrapped in <strong> in the page content).
   Weight + navy only; no size bump, no colour on a tint, no new copy. */
.home .sp-priority__body strong {
	font-weight: 700;
	color: var(--wp--preset--color--primary-navy);
}

/* 6. Why This Race Became Personal -- format-only readability, existing
   words only. `.sp-story` is added to that one section's prose container. */
.home .sp-story > * + * {
	margin-block-start: var(--wp--preset--spacing--10); /* 40px between story beats -- a step up from the 32px default */
}
.home .sp-story strong {
	font-weight: 700;
	color: var(--wp--preset--color--primary-navy);
}
/* The single turning-point sentence, as a pull-line -- larger and heavier
   than body, campaign navy, its own breathing room. Not a quote card, not
   oversized. */
.home .sp-pullline {
	margin-block: var(--wp--preset--spacing--12) !important; /* 48px */
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(21px, calc(17.4px + 1.1vw), 28px);
	font-weight: 700;
	line-height: 1.3;
	color: var(--wp--preset--color--primary-navy);
}

/* 8. Leadership / Experience teaser. The text track was 1fr (~830px /
   ~104 CPL at wide desktop) -- cap it to a comfortable measure. The forced
   430px photo (this file + an !important rule in the wp_global_styles
   record) hung ~75px below the shorter teaser text, so bring it closer;
   !important + later cascade beats the global-styles inline rule. Mobile:
   the photo was centred (margin:0 auto) while the heading and text are
   flush-left -- left-align it so it reads as connected to the copy.
   .sp-experience-* is shared with Meet Scott, hence .home. */
@media (min-width: 1024px) {
	.home .sp-experience-layout {
		grid-template-columns: 280px minmax(0, 560px);
		justify-content: start;
	}
	.home .sp-experience-photo-wrap,
	.home .sp-experience-photo {
		height: 448px !important;
	}
}
@media (max-width: 1023px) {
	.home .sp-experience-photo-wrap {
		margin-left: 0;
		margin-right: 0;
		max-width: 280px;
	}
}

/* 9. Get Involved -- core's .wp-block-buttons.is-layout-flex (display:flex,
   two classes) out-specified the shared .sp-callout__actions grid rule
   above, so the two buttons never stacked on mobile. Win the tie with a
   three-class .home-scoped selector and stack via flex-direction (no fight
   with display:flex itself). Full-width buttons; the button styles keep
   their own >=44px min-height. */
@media (max-width: 767px) {
	.home .sp-callout .sp-callout__actions {
		flex-direction: column;
		align-items: stretch;
	}
	.home .sp-callout .sp-callout__actions .wp-block-button,
	.home .sp-callout .sp-callout__actions .wp-block-button__link {
		width: 100%;
	}
}

/* ===================================================================
   Phase 23.3 -- homepage priority-card styling + personal-story polish.
   .home-scoped (.sp-priority* is shared with Issues & Vision; .sp-story
   is homepage-only). Experience section untouched.
   =================================================================== */

/* --- Scott's Priorities: each item becomes a distinct, restrained card ---
   Was a full-bleed text block under a 2px navy top rule. Now a light panel
   with a hairline border and a restrained red accent line on the top edge.
   Subtle on purpose -- structure, not weight. 2x2 desktop / stacked mobile
   is unchanged (the .sp-grid--2 grid is untouched). */
.home .sp-priority {
	gap: 0;
	padding: var(--wp--preset--spacing--6); /* 24px all sides (was 32px top/bottom, 0 sides) */
	background: var(--surface-muted); /* #F4F6F8 -- light panel on the white section */
	border: var(--border-width-hairline) solid var(--border-subtle);
	border-top: var(--border-width-accent) solid var(--wp--preset--color--campaign-red);
	border-radius: 0; /* brand is square-cornered (matches .sp-card) */
}

/* "Scott's Priorities" reads as the parent through size (H2 ~1.5x the card
   H3s, see the 23.2B/23.3 clamps above) and treatment (the H2 is bare, the
   items are boxed) -- the existing 32px block-gap between the H2 and the
   grid is left as-is. */

@media (max-width: 767px) {
	.home .sp-priority {
		padding: var(--wp--preset--spacing--5); /* 20px -- not over-padded on small screens */
	}
	/* A little more air between the bordered boxes than the base 16px grid gap. */
	.home .sp-grid.sp-grid--2 {
		gap: var(--wp--preset--spacing--5); /* 20px */
	}
}

/* --- "Why This Race Became Personal": inset emphasis callout ---
   The "Years in the mortgage industry taught him..." paragraph (item 6 of
   the 23.2A audit) is lifted into a subtle panel. Related to the priority
   card (light panel, hairline border, restrained red accent) but the accent
   sits on the LEFT edge, not the top -- signals "emphasis inset", not
   "one of a set". Existing words only; nothing hidden. */
.home .sp-story__callout {
	margin-block: var(--wp--preset--spacing--10) !important; /* 40px, matches the story-beat rhythm */
	padding: var(--wp--preset--spacing--6);
	background: var(--wp--preset--color--white); /* white panel on the muted section */
	border: var(--border-width-hairline) solid var(--border-subtle);
	border-left: var(--border-width-accent) solid var(--wp--preset--color--campaign-red);
	font-size: var(--wp--preset--font-size--body-lg); /* 20px -- a touch above body */
	line-height: 1.55;
	color: var(--text-heading);
}
.home .sp-container--prose > .sp-story__callout {
	max-width: 36em; /* a hair wider than the 31em body measure so it reads as its own block */
}
@media (max-width: 767px) {
	.home .sp-story__callout {
		padding: var(--wp--preset--spacing--5);
		font-size: var(--wp--preset--font-size--body); /* back to 18px on small screens */
	}
	/* Slightly tighter beat rhythm on mobile so the section scrolls shorter
	   while still reading as distinct beats (desktop keeps 40px). */
	.home .sp-story > * + * {
		margin-block-start: var(--wp--preset--spacing--8); /* 32px */
	}
}

/* ===================================================================
   Phase 23.3B -- Scott's Priorities, mobile-only accordion.
   The .sp-priority--accordion / .sp-priority__toggle / .sp-priority__panel
   classes are added by priorities.js at <=767px on the homepage only, and
   removed again above 767px, so desktop keeps the Phase 23.3 expanded 2x2
   cards untouched. The @media guard is belt-and-braces.
   =================================================================== */
@media (max-width: 767px) {
	/* .sp-priority ships display:grid (single 1fr column). Its collapsible
	   panel then sits inside that grid track, where the grid's auto-row
	   sizing keeps the panel at content height and defeats height:0. Drop
	   the enhanced cards to plain block flow so height:0 clips normally. */
	.home .sp-priority--accordion {
		display: block;
	}
	/* Closed card: red accent + a full-width disclosure button, compact. */
	.home .sp-priority--accordion .sp-priority__title {
		margin: 0;
	}
	.home .sp-priority__toggle {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--wp--preset--spacing--4);
		width: 100%;
		min-height: var(--touch-min); /* >=44px tap target */
		padding: 0;
		margin: 0;
		background: transparent;
		border: 0;
		border-radius: 0;
		cursor: pointer;
		text-align: left;
		font: inherit; /* inherit the .sp-priority__title display/size/weight */
		color: inherit;
	}
	.home .sp-priority__toggle-text {
		flex: 1 1 auto;
	}

	/* +/- indicator. priorities.js writes the glyph ("+" closed, "−" open)
	   directly into this span's text -- a plain element, no pseudo-elements,
	   no ancestor-class restyle, so it is reliable when .is-open toggles.
	   Restrained: a small campaign-red glyph, not an oversized icon. */
	.home .sp-priority__icon {
		flex: 0 0 auto;
		width: 1em;
		font-family: var(--wp--preset--font-family--text);
		font-size: 22px;
		font-weight: 400;
		line-height: 1;
		text-align: center;
		color: var(--wp--preset--color--campaign-red);
	}

	/* Collapsible panel. Closed accordion cards get height:0 + overflow:hidden
	   (clipped to nothing); open cards drop the height:0 rule and the panel
	   is its natural height. priorities.js only toggles the .is-open class,
	   so there is no scripted height to get stuck. */
	.home .sp-priority--accordion .sp-priority__panel {
		overflow: hidden;
	}
	.home .sp-priority--accordion:not(.is-open) .sp-priority__panel {
		height: 0;
	}
	.home .sp-priority__panel-inner {
		padding-top: var(--wp--preset--spacing--4); /* 16px, matches the old title -> body gap */
	}
}

/* ===================================================================
   Phase 24B -- Contact page Jetpack form.
   Aligns the native Jetpack contact form to the campaign form language:
   campaign-primary Submit, square/consistent fields, >=44px touch targets
   on every control, and the phone/text consent as a readable-but-secondary
   disclosure block. Scoped entirely to .wp-block-jetpack-contact-form so
   nothing else is affected.

   NOTE: the consent checkbox wording is a WORKING DRAFT (Phase 24B). Final
   phone/text consent language must be reviewed by campaign counsel, the
   treasurer, and the SMS/texting provider before production migration. No
   SMS/texting provider is connected as of Phase 24B.
   =================================================================== */

/* Tighten Jetpack's default field gap so the (now longer) form stays short
   and approachable. */
.wp-block-jetpack-contact-form.is-layout-flex {
	gap: var(--wp--preset--spacing--5); /* 20px, was ~32px */
}

/* Text / email / tel / textarea inputs -- campaign field look. */
.wp-block-jetpack-contact-form input[type="text"],
.wp-block-jetpack-contact-form input[type="email"],
.wp-block-jetpack-contact-form input[type="tel"],
.wp-block-jetpack-contact-form input[type="url"],
.wp-block-jetpack-contact-form textarea {
	min-height: var(--touch-min); /* >=44px */
	border: var(--border-width-hairline) solid var(--border-default);
	border-radius: var(--radius-sm);
	background: var(--wp--preset--color--white);
	font-family: var(--wp--preset--font-family--text);
	color: var(--text-heading);
}
.wp-block-jetpack-contact-form input:hover,
.wp-block-jetpack-contact-form textarea:hover {
	border-color: var(--wp--preset--color--secondary-navy);
}

/* "I'm interested in:" options -- each row a >=44px tap target, body-weight
   text, checkbox large enough to hit. */
.wp-block-jetpack-contact-form .grunion-checkbox-multiple-options label {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--3);
	min-height: var(--touch-min);
	font-family: var(--wp--preset--font-family--text);
	font-weight: 400;
	color: var(--text-body);
	cursor: pointer;
}
.wp-block-jetpack-contact-form input[type="checkbox"],
.wp-block-jetpack-contact-form input.checkbox,
.wp-block-jetpack-contact-form input.checkbox-multiple {
	width: 22px !important;  /* Jetpack sizes its appearance:none checkbox inline; match the consent box */
	height: 22px !important;
	flex: none;
	margin: 0;
	accent-color: var(--wp--preset--color--primary-navy);
	cursor: pointer;
}

/* Phone/text consent -- its own block: hairline rule above, small secondary
   text (still AA: --text-body on white). The checkbox and its label are
   siblings inside .contact-form__checkbox-wrap, so flex the wrapper (not the
   label) -- the label stays a normal text block and the inline Privacy
   Policy link flows with the sentence. */
.wp-block-jetpack-contact-form .grunion-field-checkbox-wrap {
	margin-top: var(--wp--preset--spacing--3);
	padding-top: var(--wp--preset--spacing--5);
	border-top: var(--border-width-hairline) solid var(--border-subtle);
}
.wp-block-jetpack-contact-form .grunion-field-checkbox-wrap .contact-form__checkbox-wrap {
	display: flex;
	align-items: flex-start;
	gap: var(--wp--preset--spacing--3);
}
.wp-block-jetpack-contact-form label[for="phone-text-consent"] {
	display: block;
	font-family: var(--wp--preset--font-family--text);
	font-weight: 400;
	font-size: var(--wp--preset--font-size--caption); /* 14px */
	line-height: 1.5;
	color: var(--text-body);
	cursor: pointer;
}
.wp-block-jetpack-contact-form label[for="phone-text-consent"] a {
	color: var(--text-link);
}
.wp-block-jetpack-contact-form #phone-text-consent {
	margin-top: 2px;
}

/* Submit -- carries is-style-sp-primary already; guarantee a real touch
   height and the campaign hover / focus-visible states inside Jetpack's
   own form CSS. */
.wp-block-jetpack-contact-form .wp-block-button.is-style-sp-primary .wp-block-button__link {
	min-height: var(--touch-min);
}
.wp-block-jetpack-contact-form .wp-block-button.is-style-sp-primary .wp-block-button__link:hover {
	background: var(--wp--preset--color--campaign-red-pressed);
}
.wp-block-jetpack-contact-form .wp-block-button__link:focus-visible {
	outline: 2px solid var(--border-focus);
	outline-offset: 2px;
	box-shadow: var(--focus-ring);
}

/* ===================================================================
   Phase 26B -- Issues & Vision deep-dive priority panels + About the
   Office "Myth vs. Fact" cards. Both get a mobile-only accordion built
   by assets/js/interior-accordions.js (self-gating on <=767px and on
   their own selectors, torn back down above 767px). The homepage
   "Scott's Priorities" accordion (priorities.js, body.home, .sp-priority
   without --deep) is a separate script and is not touched.
   =================================================================== */

/* --- Issues & Vision: deep priority panel. Deliberately NOT the homepage
   red-top card: a light panel, hairline border, and a restrained red LEFT
   accent, one priority per row, fully expanded on desktop. Overrides the
   shared base .sp-priority (grid + 2px navy top rule). --- */
.sp-priority.sp-priority--deep {
	display: block;
	gap: 0;
	padding: var(--wp--preset--spacing--8);
	background: var(--surface-muted);
	border: var(--border-width-hairline) solid var(--border-subtle);
	border-left: var(--border-width-accent) solid var(--wp--preset--color--campaign-red);
	border-radius: 0;
}
.sp-priority--deep + .sp-priority--deep {
	margin-top: var(--wp--preset--spacing--6);
}
.sp-priority--deep .sp-priority__title {
	font-size: clamp(24px, calc(20px + 1vw), 30px);
	margin: 0 0 var(--wp--preset--spacing--4);
}
.sp-priority--deep .sp-priority__body + .sp-priority__body {
	margin-block-start: var(--wp--preset--spacing--4);
}
/* Emphasised closing takeaway -- same restrained treatment as the homepage
   priority cards (weight + navy only), keyed to .sp-priority--deep so the
   .home rule is untouched. */
.sp-priority--deep .sp-priority__body strong {
	font-weight: 700;
	color: var(--wp--preset--color--primary-navy);
}

@media (max-width: 767px) {
	.sp-priority.sp-priority--deep {
		padding: var(--wp--preset--spacing--6);
	}
	.sp-priority--deep.sp-priority--accordion .sp-priority__title {
		margin: 0;
	}
	.sp-priority--deep .sp-priority__toggle {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--wp--preset--spacing--4);
		width: 100%;
		min-height: var(--touch-min); /* >=44px tap target */
		padding: 0;
		margin: 0;
		background: transparent;
		border: 0;
		border-radius: 0;
		cursor: pointer;
		text-align: left;
		font: inherit; /* inherit .sp-priority__title display/size/weight */
		color: inherit;
	}
	.sp-priority--deep .sp-priority__toggle-text {
		flex: 1 1 auto;
	}
	.sp-priority--deep .sp-priority__icon {
		flex: 0 0 auto;
		width: 1em;
		font-family: var(--wp--preset--font-family--text);
		font-size: 22px;
		font-weight: 400;
		line-height: 1;
		text-align: center;
		color: var(--wp--preset--color--campaign-red);
	}
	.sp-priority--deep.sp-priority--accordion .sp-priority__panel {
		overflow: hidden;
	}
	.sp-priority--deep.sp-priority--accordion:not(.is-open) .sp-priority__panel {
		height: 0;
	}
	.sp-priority--deep .sp-priority__panel-inner {
		padding-top: var(--wp--preset--spacing--4);
	}
}

/* --- About the Office: "Myth vs. Fact" now carries a semantic H3 per card
   (.sp-myth__q) and a fact paragraph (.sp-myth__a). Desktop keeps the
   existing 2-col .sp-card grid fully expanded; <=767px each becomes a
   disclosure with the myth as the trigger. --- */
.sp-myth__q {
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--h4);
	font-weight: 700;
	line-height: 1.3;
	color: var(--wp--preset--color--primary-navy);
	margin: 0 0 var(--wp--preset--spacing--3);
}
.sp-myth__a {
	margin: 0;
}
/* Inline "Official resource:" links appended inside the single collapsing
   paragraph of a FAQ answer / the Myth #3 fact -- kept inline so the
   accordion mechanics are unaffected; inline-block + margin-top sets them
   on their own line with breathing room without a structural change. */
.sp-faq__panel-inner > a[target="_blank"],
.sp-myth__a > a[target="_blank"] {
	display: inline-block;
	margin-top: var(--wp--preset--spacing--3);
	font-size: var(--wp--preset--font-size--body-sm);
	font-weight: 600;
}

@media (max-width: 767px) {
	.sp-myth--accordion .sp-myth__q {
		margin: 0;
	}
	.sp-myth__toggle {
		display: flex;
		align-items: flex-start;
		justify-content: space-between;
		gap: var(--wp--preset--spacing--4);
		width: 100%;
		min-height: var(--touch-min); /* >=44px tap target */
		padding: 0;
		margin: 0;
		background: transparent;
		border: 0;
		border-radius: 0;
		cursor: pointer;
		text-align: left;
		font: inherit;
		color: inherit;
	}
	.sp-myth__toggle-text {
		flex: 1 1 auto;
	}
	.sp-myth__icon {
		flex: 0 0 auto;
		width: 1em;
		font-family: var(--wp--preset--font-family--text);
		font-size: 22px;
		font-weight: 400;
		line-height: 1;
		text-align: center;
		color: var(--wp--preset--color--campaign-red);
	}
	.sp-myth--accordion .sp-myth__panel {
		overflow: hidden;
	}
	.sp-myth--accordion:not(.is-open) .sp-myth__panel {
		height: 0;
	}
	.sp-myth__panel-inner {
		padding-top: var(--wp--preset--spacing--3);
	}
}

/* ===================================================================
   Phase 28B/28C/31 -- Meet Scott "Family, Faith & Community". Scoped
   entirely to .sp-family / .sp-family__* -- the intro's .sp-imagetext
   implementation and every other class are untouched. The section copy
   is unchanged. 28C: the copy sits above a restrained photo row -- the
   family beach photo (3:2, the lead) and the Scott + Nathan graduation
   photo (4:5, supporting). Phase 31 adds the third <figure> the 28C
   comment anticipated -- Scott + Victoria at the University of
   Tennessee (3:4) -- adjusting only the column ratio, per that note.
   =================================================================== */
.sp-family {
	max-width: 720px;
	margin-inline: auto;
}
.sp-family__body > :first-child {
	margin-top: 0;
}

/* Photo row: the beach photo (3:2), the Nathan graduation photo (4:5),
   and the Scott + Victoria photo (3:4) render at equal display height
   via a 30:16:15 column ratio -- none of the three is cropped. That
   ratio is the three source ratios (1.5 : 0.8 : 0.75) scaled to whole
   numbers, so the first two columns keep the exact same 1.875:1
   proportion the original 15:8 two-photo ratio used -- the third
   column is sized off the same "equal display height" math, not
   guessed. The beach photo stays the wider, warmer lead; the two
   portraits are smaller supporting images so the section doesn't read
   as military-heavy or crowd out the copy above it. */
/* Phase 32: visual order is now Nathan | Beach | Scott + Victoria, with
   the beach photo as the centered anchor. Columns are reordered to match
   (16fr 30fr 15fr -- same equal-height math, just shuffled) and the
   existing DOM children (1 = beach, 2 = Nathan, 3 = Victoria) are mapped
   to named areas so the page content itself doesn't have to change. */
.sp-family__support {
	display: grid;
	grid-template-columns: 16fr 30fr 15fr;
	grid-template-areas: "nathan beach victoria";
	gap: var(--wp--preset--spacing--5);
	align-items: start;
	/* Phase 30C: was spacing--10 (40px). Tightened one step so the photo
	   pair reads as part of the same section as the copy above it. */
	margin-top: var(--wp--preset--spacing--8);
}
.sp-family__support > :nth-child(1) { grid-area: beach; }
.sp-family__support > :nth-child(2) { grid-area: nathan; }
.sp-family__support > :nth-child(3) { grid-area: victoria; }
.sp-family__support .wp-block-image,
.sp-family__support figure {
	margin: 0;
}
.sp-family__support img {
	display: block;
	width: 100%;
	height: auto;
}

/* Phase 31: mobile moves from a 3-across row (each photo would land
   under ~110px tall on a 375px screen -- too small to read as a
   deliberate composition) to a 1-over-2 arrangement: the beach photo
   full-width on its own row, the two portraits (Nathan and Scott +
   Victoria) side by side underneath in an even 1fr/1fr split. Their
   ratios (4:5 and 3:4) are close enough that an even split keeps both
   comfortably legible and visually balanced without cropping either --
   heights differ by only a few px at typical phone widths. Gap and top
   margin stay tightened from Phase 30C so the group reads as one
   compact unit under the copy.
   Phase 32: layout is expressed as named areas (children are mapped
   above), and align-items: end bottom-aligns the two portraits in row
   two -- their tops may differ by a few px since 4:5 and 3:4 aren't
   equal, but the bottom edges line up exactly with no cropping. */
@media (max-width: 767px) {
	.sp-family__support {
		grid-template-columns: 1fr 1fr;
		grid-template-areas:
			"beach beach"
			"nathan victoria";
		align-items: end;
		gap: var(--wp--preset--spacing--3);
		margin-top: var(--wp--preset--spacing--6);
	}
	/* Mobile only: frame the 3:4 Scott + Victoria photo at Nathan's 4:5 so
	   the pair matches top and bottom. Anchored to the bottom, so the
	   ~6% trimmed comes entirely off the top (the UT seal), never the
	   faces. */
	.sp-family__support > :nth-child(3) img {
		aspect-ratio: 4 / 5;
		object-fit: cover;
		object-position: 50% 100%;
	}
}

/* ===================================================================
   Phase 30F -- Homepage "A Property Appraiser's Office That Works for
   the People It Serves": scoped two-column image+text split. The
   .sp-appraiser* classes are new and unique to this one section (not
   shared with Meet Scott's .sp-imagetext or anything else), so nothing
   here can affect any other section. Column split (not an even 1:1)
   and 1024px stack breakpoint follow .sp-imagetext's own conventions
   elsewhere in this file.
   =================================================================== */

.sp-appraiser {
	display: grid;
	grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
	/* align-items defaults to stretch -- written out because it's the
	   one thing this layout depends on: it's what makes the media
	   column's height match the text column's height exactly, so the
	   photo's top edge lines up with the heading and its bottom edge
	   lines up with the final paragraph, with no hand-measured pixel
	   height to keep in sync as the copy changes. */
	align-items: stretch;
	gap: var(--wp--preset--spacing--12);
}
/* Flow layout's blockGap (`.is-layout-flow > *`) adds an unwanted
   margin-block-start to the second grid item -- the same bug already
   fixed on .sp-grid / .sp-experience-layout elsewhere in this file.
   Left unfixed here it would push the media column down and break the
   top-alignment above. */
.sp-appraiser > * {
	margin-block-start: 0;
}
.sp-appraiser__media {
	overflow: hidden;
	border: var(--border-width-hairline) solid var(--border-subtle);
}
.sp-appraiser__media figure {
	height: 100%;
	margin: 0;
}
.sp-appraiser__media img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

@media (max-width: 1023px) {
	.sp-appraiser {
		grid-template-columns: minmax(0, 1fr);
		gap: var(--wp--preset--spacing--8);
	}
	/* Un-stretch on mobile/tablet -- the photo sits in its own
	   natural-ratio box below the text instead of being cropped to
	   match the (now much taller, single-column) text block's height. */
	.sp-appraiser__media figure {
		height: auto;
	}
	.sp-appraiser__media img {
		height: auto;
		aspect-ratio: 3 / 2; /* the source photo's own ratio -- no crop on mobile */
	}
}
