/*
 * Samsurfus — front-end presentation layer.
 * Structural styles live in theme.json; this file covers what blocks can't express.
 */

:root {
	--sf-red: #e40f0f;
	--sf-red-dark: #7e0707;
	--sf-red-text: #d60d0d;
	--sf-red-bright: #ff5252;
	--sf-navy: #041a38;
	--sf-ink: #020718;
	--sf-slate: #33373d;
	--sf-gray: #5f6874;
	--sf-mist: #dbdbdb;
	--sf-cloud: #f5f6f8;
	--sf-tint: #e9edf3;
	--sf-white: #fff;
	--sf-wide: 1240px;
	--sf-radius: 4px;
	--sf-radius-lg: 8px;
	--sf-shadow: 0 10px 30px rgba(4, 26, 56, 0.09);
	--sf-shadow-lg: 0 18px 45px rgba(4, 26, 56, 0.16);
}

/* ------------------------------------------------------------------ Base */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
}

:focus-visible {
	outline: 2px solid var(--sf-red-dark);
	outline-offset: 2px;
}

.sf-topbar-wrap :focus-visible,
.sf-hero :focus-visible,
.sf-stats :focus-visible,
.sf-testi :focus-visible,
.sf-cta :focus-visible,
.sf-footer :focus-visible {
	outline-color: #fff;
}

/* One button language for the theme. Declared up here so the component rules
   below (.sf-hero__cta, .sf-cta__btn) can still restate or
   override it at equal specificity — and because this stylesheet loads last,
   it also supersedes core's global-styles button padding/radius, which were
   producing a second dialect (14/28 padding, 3px radius, sentence case).
   Outline variants surrender 2px of vertical padding so a filled and an
   outlined button sharing a row come out the same height. */
.wp-block-button__link {
	display: inline-block;
	padding: 15px 34px;
	border-radius: var(--sf-radius);
	background: var(--sf-red);
	color: #fff;
	font-size: 0.85rem;
	font-weight: 700;
	line-height: 1.65;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	text-decoration: none;
	transition: background 0.18s ease, color 0.18s ease, transform 0.18s ease,
		box-shadow 0.25s ease;
}

body {
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

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

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(1px, 1px, 1px, 1px);
	word-wrap: normal !important;
}

/* --------------------------------------------------------------- Top bar */
/* Core gives background groups `padding: 1.25em 2.375em`, which turns this
   42px of content into an 82px bar. Tighten the vertical half only; the
   horizontal inset is still needed so the bar's content lines up with the
   constrained inner below it. */
.sf-topbar-wrap {
	background: var(--sf-ink);
	padding-top: 10px;
	padding-bottom: 10px;
}

.sf-topbar__inner {
	max-width: var(--sf-wide);
	margin: 0 auto;
	padding: 7px 16px;
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px 22px;
	font-size: 0.78rem;
	color: rgba(255, 255, 255, 0.82);
}

.sf-topbar__item {
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	gap: 7px;
	color: inherit;
	text-decoration: none;
	transition: color 0.18s ease;
}

a.sf-topbar__item:hover,
a.sf-topbar__item:focus-visible {
	color: var(--sf-red-bright);
}

/* Brokerage identity. GREC Rule 520-1-.09(5) requires the firm's name and
   telephone number on every viewable page, and (6)(a) wants the firm name at
   equal or greater prominence than the licensee's own name. */
.sf-topbar__item--firm {
	color: #fff;
}

.sf-topbar__item--firm strong {
	font-size: 1.06em;
	letter-spacing: 0.05em;
	text-transform: uppercase;
}

.sf-topbar__spacer {
	flex: 1 1 auto;
}

.sf-topbar__social {
	display: flex;
	align-items: center;
}

.sf-topbar__social .sf-social a {
	width: 26px;
	height: 26px;
}

.sf-topbar__social .sf-social a:hover,
.sf-topbar__social .sf-social a:focus {
	background: #fff;
	color: var(--sf-navy);
}

.sf-icon {
	flex: 0 0 auto;
	opacity: 0.9;
}

/* ---------------------------------------------------------------- Header */
/* WP's admin bar is fixed over the viewport while the header sticks to
   top: 0, so the bar covers the header's top 32px (46px on mobile) for
   anyone logged in. Pin the header below it.

   Core switches the bar to `position: absolute` at <=600px
   (admin-bar.css), so down there it scrolls away with the page and the
   `html { margin-top: 46px }` reservation is only correct at scroll top.
   Keeping a 46px offset there left a 46px hole above the pinned navbar on
   phones -- so the offsets only exist above 600px, and <=600px inherits
   `top: 0`. */
@media (min-width: 601px) {
	.admin-bar .sf-header {
		top: 32px;
	}
}

@media (min-width: 601px) and (max-width: 782px) {
	.admin-bar .sf-header {
		top: 46px;
	}
}

.sf-header {
	position: sticky;
	top: 0;
	z-index: 60;
	box-shadow: 0 1px 0 rgba(4, 26, 56, 0.08), 0 6px 20px rgba(4, 26, 56, 0.05);
}

/* The header is the last box inside its `wp-block-template-part` wrapper, so
   the wrapper ends exactly where the header ends and sticky has nowhere to
   travel. Drop the wrapper out of the box tree and the header sticks to the
   viewport for the whole page. */
.wp-block-template-part:has(.sf-header) {
	display: contents;
}

.sf-header__inner {
	max-width: var(--sf-wide);
	margin: 0 auto;
	padding: 12px 16px;
	gap: 20px;
}

.sf-header__brand {
	gap: 12px;
	min-width: 0;
}

.sf-header__logo img,
.sf-footer__logo img {
	display: block;
}

.sf-header__nav-wrap {
	gap: 16px;
}

/* Navigation */
.sf-nav .wp-block-navigation__container {
	flex-wrap: nowrap;
	gap: 0 14px;
}

.sf-nav .wp-block-navigation-item__content {
	font-size: 0.75rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	color: var(--sf-navy);
	text-decoration: none;
	padding: 6px 0;
	white-space: nowrap;
	transition: color 0.18s ease;
}

.sf-nav .wp-block-navigation-item__content:hover,
.sf-nav .wp-block-navigation-item__content:focus {
	color: var(--sf-red);
}

/* Core renders the overlay menu white with zero padding and black links; its
   :not(.has-background)/:not(.has-text-color) selectors sit at (0,5,0) and
   outrank ours, so these three declarations have to be forced. */
.sf-nav .wp-block-navigation__responsive-container.is-menu-open {
	background: var(--sf-navy) !important;
	padding: 34px 24px !important;
	color: #fff !important;
}

.sf-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	font-size: 1.125rem;
	padding: 11px 0;
	color: #fff;
}

.sf-nav .wp-block-navigation__responsive-container.is-menu-open a:hover,
.sf-nav .wp-block-navigation__responsive-container.is-menu-open a:focus {
	color: var(--sf-red-bright);
}

/* One-line nav: core only collapses to a hamburger below 600px, so the
   breakpoint is raised here. Core also ships the burger at 24x24, which is
   thin for a thumb; the hit area goes to 44x44 and the -10px margin cancels
   the extra 20px so the icon stays optically put and the header does not
   reflow. */
@media (max-width: 1099px) {
	.sf-nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		margin: -10px;
	}

	.sf-nav .wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__responsive-container-close {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 44px;
		height: 44px;
		margin: -10px;
	}

	.sf-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none;
	}
}

/* Social icons */
.sf-social {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	align-items: center;
	gap: 8px;
}

.sf-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	background: var(--sf-red);
	color: #fff;
	text-decoration: none;
	transition: background 0.18s ease, transform 0.18s ease;
}

.sf-social a:hover,
.sf-social a:focus {
	background: var(--sf-navy);
	transform: translateY(-2px) scale(1.08);
}

/* ------------------------------------------------------------------ Hero */
/* The root blockGap (1.5rem) leaves a 24px white seam between the sticky
   header and the hero, making 122px of blank white before the image. */
.sf-hero {
	position: relative;
	margin-top: 0;
	min-height: min(86vh, 720px);
	display: flex;
	align-items: center;
	background-color: var(--sf-navy);
	background-size: cover;
	background-position: center;
	overflow: hidden;
}

.sf-hero__veil {
	position: absolute;
	inset: 0;
	background: linear-gradient(90deg, rgba(4, 26, 56, 0.95) 0%, rgba(4, 26, 56, 0.8) 45%, rgba(4, 26, 56, 0.35) 100%);
}

.sf-hero__inner {
	position: relative;
	z-index: 1;
	max-width: var(--sf-wide);
	width: 100%;
	margin: 0 auto;
	padding: 96px 16px;
}

.sf-hero__eyebrow {
	margin: 0 0 18px;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.75);
}

.sf-hero__title {
	margin: 0;
	color: #fff;
	font-size: clamp(2.6rem, 7vw, 5.2rem);
	line-height: 1.02;
	font-weight: 800;
	letter-spacing: -0.03em;
}

.sf-hero__line {
	display: block;
}

.sf-hero__line--brand em {
	display: block;
	font-style: normal;
	color: var(--sf-red);
	text-transform: uppercase;
}

/* Trademark mark in the headline: same small superscript treatment as the
   firm's logo, so the ® doesn't run at full display size. Both values are em
   against the mark's own 0.3em box, so the ratio holds across the clamp() range. */
.sf-tm {
	font-size: 0.3em;
	position: relative;
	top: -1.75em;
	margin-left: 0.1em;
}

.sf-hero__sub {
	margin: 26px 0 0;
	max-width: 34ch;
	font-size: clamp(1.05rem, 2vw, 1.4rem);
	line-height: 1.5;
	color: rgba(255, 255, 255, 0.92);
	font-weight: 500;
}

.sf-hero__cta {
	display: inline-block;
	margin-top: 32px;
	padding: 15px 34px;
	background: var(--sf-red);
	color: #fff;
	font-weight: 700;
	font-size: 0.85rem;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	text-decoration: none;
	border-radius: var(--sf-radius);
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.25s ease;
}

.sf-hero__cta:hover,
.sf-hero__cta:focus {
	background: #fff;
	color: var(--sf-navy);
	transform: translateY(-2px);
}

/* -------------------------------------------------------------- Sections */
/* `clip` rather than `hidden`. The two clip identically, but `hidden` makes
   the section a SCROLL CONTAINER, and a `view()` timeline binds to the
   NEAREST scroll container — so every heading was measured against a 935px
   box that never scrolls, the timeline froze at a fixed progress, and the
   wipe locked onto its end frame and never played. `clip` produces the same
   clipped rendering without creating a scrollport, which leaves the root as
   the only one and lets the heading's own position drive the wipe. */
.sf-section {
	/* Progressive enhancement, last-declaration-wins: engines without
	   `clip` (Safari <=15, Chrome <=90) keep `hidden` and still clip, so a
	   section can never open a horizontal scrollbar. Those same engines also
	   lack animation-timeline, so they take the timed @supports-not path
	   below, which never needed the section to stop being a scroll
	   container. */
	overflow: hidden;
	overflow: clip;
}

/* Rows now run the full 1240px measure, so running text is held to an
   editorial line length instead of stretching with them. Core forces
   `margin-left: auto !important`, which would centre the capped box, so the
   offset is recomputed from the row width to keep the text flush with the
   headings. `sf-` blocks keep their own (often centred) sizing rules. */
.is-layout-constrained:not(.entry-content) > p:not([class*="sf-"], .aligncenter, .alignleft, .alignright, .alignwide) {
	max-width: 68ch;
	margin-left: max(0px, calc((100% - var(--wp--style--global--content-size)) / 2)) !important;
}

/* Alternating bands. Every section owns a surface and no two neighbours match:
   hero (photo) - links tint - stats navy - about cloud - why tint -
   specialties cloud - vmm tint - testimonials navy - contact cloud - cta red.
   `--sf-tint` is a solid token rather than a 5% wash: the wash was only ~1%
   off white, so three sections in a row read as one continuous background.
   The light bands sit on `--sf-cloud` rather than pure white for the same
   reason: an elevated panel is white, so on a white band it had no edge at
   all and the copy inside read as unstyled text. Cloud keeps the panel, the
   hairline and the shadow legible while still reading as "the white section".
   `.sf-vmm` and `.sf-contact` carry core's `has-cloud-background-color`; this
   stylesheet loads after global styles, so these same-specificity rules win. */
.sf-links,
.sf-why,
.sf-vmm {
	background-color: var(--sf-tint);
}

.sf-about,
.sf-specialties,
.sf-contact {
	background-color: var(--sf-cloud);
}

/* Core's flow layout gives every direct child `margin-block-start: 1.5rem`
   (the root blockGap), so each seam between sections opened a 24px white
   stripe. Invisible while the tint was a 5% wash; a visible fault once the
   bands had real colour. Bands butt together. */
.sf-front-content > .sf-section {
	margin-block-start: 0;
}

/* Section rhythm: the content pads bands with `spacing-70` (4rem/64px), which
   sits under the 80px floor for desktop sections. Inline padding outranks the
   stylesheet, so the desktop value is asserted here; the tighter stats band
   (`spacing-60`, 40px) is deliberately excluded. */
@media (min-width: 821px) {
	.sf-front-content > .sf-section:not(.sf-stats) {
		padding-block: 5rem !important;
	}
}

/* Elevated text surfaces: the section header, the About body column and both
   Specialties columns. Kept flush with the card rows above/below them.
   `box-sizing` has to be explicit: core leaves `.wp-block-column` on
   content-box, so the padding would otherwise widen the column past its row.
   The Contact panel joins the set: it holds the whole section - heading,
   copy, CTA and details - now that the column split is gone. */
.sf-intro,
.sf-about__body,
.sf-specialties__grid > .wp-block-column,
.sf-contact__card {
	box-sizing: border-box;
	background: var(--sf-white);
	border: 1px solid rgba(4, 26, 56, 0.1);
	border-radius: var(--sf-radius-lg);
	box-shadow: 0 1px 2px rgba(4, 26, 56, 0.04), 0 16px 36px rgba(4, 26, 56, 0.08);
	padding: 40px;
}

.sf-intro > *:last-child {
	margin-bottom: 0;
}

.sf-intro p {
	max-width: 68ch;
}

/* Neighbouring colour blocks must butt together - no white block-gap hairlines */
.site-main.sf-front-main,
.site-main.sf-front-main + .sf-cta,
.sf-cta + .wp-block-template-part {
	margin-top: 0;
}

.sf-eyebrow {
	margin: 0 0 10px;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--sf-red-text);
}

.sf-eyebrow--light {
	color: rgba(255, 255, 255, 0.7);
}

.sf-section__title {
	margin: 0 0 18px;
	font-size: clamp(1.75rem, 3.4vw, 2.6rem);
	color: var(--sf-navy);
	letter-spacing: -0.02em;
}

.sf-section__title--light {
	color: #fff;
}

.sf-subhead {
	margin: 26px 0 10px;
	font-size: 1.15rem;
	color: var(--sf-navy);
	padding-left: 13px;
	border-left: 3px solid var(--sf-red);
	line-height: 1.3;
}

/* Bind body copy to the subhead above it. Core's flow layout adds 24px of
   block gap between siblings, which collapsed with this rule's own margins to
   24px below the heading and 26px above the next one in the Specialties list:
   near enough to identical that a paragraph could read as belonging to either
   heading. Dropping the body's top margin restores 10px in / 26px out. */
.sf-subhead + p {
	margin-top: 0;
}

/* ----------------------------------------------------------------- About */
.sf-about__cards {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-rows: 1fr;
	gap: 24px;
	margin-top: 44px;
}

.sf-about__card,
.sf-why__card {
	background: var(--sf-white);
	border-top: 4px solid var(--sf-red);
	border-radius: var(--sf-radius-lg);
	padding: 24px;
	box-shadow: var(--sf-shadow);
	border-left: 1px solid rgba(4, 26, 56, 0.06);
	border-right: 1px solid rgba(4, 26, 56, 0.06);
	border-bottom: 1px solid rgba(4, 26, 56, 0.06);
}

.sf-about__card p {
	margin: 0;
	font-size: 1rem;
	line-height: 1.7;
	color: var(--sf-slate);
}

/* Even card grids: identical columns, identical rows, no stray block-gap margins */
.sf-about__cards > *,
.sf-why__cards > *,
.sf-links__grid > *,
.sf-testi__grid > *,
.sf-vmm__grid > *,
.sf-specialties__grid > * {
	margin: 0;
}

.sf-about__card .sf-ticklist {
	margin-top: 16px;
}

.sf-card__title {
	margin: 0 0 10px;
	font-size: 1.15rem;
	color: var(--sf-navy);
	line-height: 1.3;
}

/* The closing statement was its own centred card under the grid; it now
   closes the bio panel, so it takes up the body column's measure and colour
   instead of announcing itself a second time. */
.sf-about__closing {
	margin: 26px 0 0;
	font-size: 1rem;
	line-height: 1.65;
	color: var(--sf-slate);
}

/* The counter and licence close the portrait rail. As plain left-aligned
   text they read as an afterthought under the photo, so they get a card:
   white against the cloud section, a red cap echoing the stats band, and
   the pair centred so the number, its label and the licence line up as one
   badge instead of three loose lines. */
.sf-about__proof {
	margin-top: 24px;
	padding: 22px 18px 18px;
	background: var(--sf-white);
	border: 1px solid rgba(4, 26, 56, 0.08);
	border-top: 3px solid var(--sf-red);
	border-radius: var(--sf-radius-lg);
	box-shadow: var(--sf-shadow);
	text-align: center;
}

.sf-about__proof .sf-stat {
	margin-top: 0;
	justify-content: center;
}

.sf-about__proof .sf-license {
	margin-top: 14px;
	padding-top: 12px;
	border-top: 1px solid rgba(4, 26, 56, 0.1);
	font-size: 0.75rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--sf-gray);
}

/* Portrait rail and bio panel share one flex line, so their bottoms have to
   land on the same rule. Both columns stretch to the line, and the portrait
   grows to absorb the difference: a few percent off each side of a centred
   studio shot, with the full height kept. The counter below it never moves,
   so the rail can only ever grow downward from the image. */
@media (min-width: 821px) {
	.sf-about__grid > .wp-block-column {
		align-self: stretch;
	}

	.sf-about__media {
		display: flex;
		flex-direction: column;
	}

	.sf-about__media .sf-about__photo {
		flex: 1 0 auto;
		margin-bottom: 0;
	}

	.sf-about__media .sf-about__photo img {
		height: 100%;
		object-fit: cover;
		object-position: 50% 30%;
	}
}

/* ----------------------------------------------------------- Stats band */
.sf-stats {
	border-top: 4px solid var(--sf-red);
}

.sf-stats__grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
	margin-top: 30px;
}

.sf-stats .sf-stat {
	margin: 0;
	padding-left: 26px;
	border-left: 1px solid rgba(255, 255, 255, 0.16);
}

.sf-stats .sf-stat__number {
	font-size: clamp(2.6rem, 4.4vw, 3.6rem);
}

.sf-stats .sf-stat:first-child {
	padding-left: 0;
	border-left: 0;
}

.sf-stats .sf-stat__label {
	color: rgba(255, 255, 255, 0.68);
	font-size: 0.75rem;
	letter-spacing: 0.2em;
	line-height: 1.5;
}

.sf-about__photo,
.sf-why__photo,
.sf-specialties__photo {
	margin: 0 0 22px;
	border-radius: var(--sf-radius-lg);
	overflow: hidden;
	box-shadow: var(--sf-shadow-lg);
}

.sf-about__photo img,
.sf-why__photo img,
.sf-specialties__photo img {
	display: block;
	width: 100%;
	border-radius: var(--sf-radius-lg);
}

.sf-about__awards {
	/* Was 437px wide under the portrait, where a 995x203 banner read as a
	   thumbnail; it now closes the bio panel at the panel's measure. */
	margin: 30px auto 0;
	max-width: 995px;
}

.sf-about__awards img {
	display: block;
	width: 100%;
	border-radius: var(--sf-radius-lg);
	background: #fff;
}

.sf-stat {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 2px;
	margin: 4px 0 0;
}

.sf-stat__number {
	font-size: clamp(3rem, 6vw, 4.4rem);
	font-weight: 800;
	line-height: 1;
	color: var(--sf-red);
	letter-spacing: -0.04em;
}

.sf-stat__suffix {
	font-size: clamp(2rem, 4vw, 3rem);
	font-weight: 800;
	color: var(--sf-red);
	line-height: 1;
}

.sf-stat__label {
	flex: 1 0 100%;
	font-size: 0.75rem;
	font-weight: 700;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--sf-gray);
	margin-top: 4px;
}

.sf-license {
	margin: 14px 0 0;
	font-size: 0.82rem;
	font-weight: 700;
	color: var(--sf-navy);
}

.sf-ticklist {
	list-style: none;
	margin: 18px 0 0;
	padding: 0;
	display: grid;
	gap: 9px;
}

.sf-ticklist li {
	position: relative;
	padding-left: 30px;
	font-weight: 600;
	color: var(--sf-slate);
}

.sf-ticklist li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 3px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: var(--sf-red) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3E%3C/svg%3E") center / 12px no-repeat;
}

/* ------------------------------------------------- Vision / Mission / Motto */
.wp-block-columns.sf-vmm__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-rows: 1fr;
	gap: 24px;
}

.wp-block-columns.sf-vmm__grid > .wp-block-column {
	display: grid;
}

.sf-vmm__card {
	box-sizing: border-box;
	background: var(--sf-white);
	border-top: 4px solid var(--sf-red);
	border-radius: var(--sf-radius-lg);
	padding: 24px;
	box-shadow: var(--sf-shadow);
	height: 100%;
}

.sf-vmm__title {
	margin: 0 0 10px;
	font-size: 1.15rem;
	color: var(--sf-navy);
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.sf-vmm__quote {
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	font-size: 1rem;
	line-height: 1.7;
	color: var(--sf-slate);
}

.sf-vmm__quote p {
	margin: 0;
}

/* ------------------------------------------------------- How can I help */
.sf-links__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-rows: 1fr;
	gap: 24px;
}

.sf-links__card {
	background: var(--sf-white);
	border-top: 4px solid var(--sf-red);
	border-radius: var(--sf-radius-lg);
	padding: 24px;
	box-shadow: var(--sf-shadow);
	height: 100%;
}

.sf-links__title {
	margin: 0 0 10px;
	font-size: 1.15rem;
	color: var(--sf-navy);
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.sf-links__text {
	margin: 0 0 16px;
	font-size: 1rem;
	line-height: 1.7;
	color: var(--sf-slate);
}

.sf-links__more {
	margin: 0;
	font-size: 0.86rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.09em;
}

.sf-links__more a {
	display: inline-block;
	min-height: 24px;
	padding-block: 4px;
	margin-block: -4px;
	color: var(--sf-red);
	text-decoration: none;
}

.sf-links__more a::after {
	content: " \2192";
}

/* --------------------------------------------------------- Why choose us */
.sf-why__cards {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-rows: 1fr;
	gap: 24px;
	margin-top: 30px;
}

.sf-why__card .sf-subhead {
	margin: 0 0 10px;
	padding-left: 0;
	border-left: 0;
	font-size: 1.15rem;
}

.sf-why__card p {
	margin: 0;
	font-size: 1rem;
	line-height: 1.7;
	color: var(--sf-slate);
}

.sf-why__feature {
	margin-top: 46px;
}

/* The commitment callout sat as bare text on the tinted band while the six
   reason cards above it were boxed, so it read as an afterthought. Box it in
   the same card language: white, red top rule, radius, shadow. */
.sf-why__feature > .wp-block-column:last-child {
	box-sizing: border-box;
	background: var(--sf-white);
	border-top: 4px solid var(--sf-red);
	border-left: 1px solid rgba(4, 26, 56, 0.06);
	border-right: 1px solid rgba(4, 26, 56, 0.06);
	border-bottom: 1px solid rgba(4, 26, 56, 0.06);
	border-radius: var(--sf-radius-lg);
	box-shadow: var(--sf-shadow);
	padding: 32px;
}

/* Match the title treatment of every other card in the section. */
.sf-why__feature > .wp-block-column:last-child .sf-subhead {
	margin: 0 0 10px;
	padding-left: 0;
	border-left: 0;
	font-size: 1.15rem;
}

.sf-why__photo {
	margin-bottom: 0;
}

/* ----------------------------------------------------------- Testimonials */
.sf-testi__grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-rows: 1fr;
	gap: 24px;
}

.sf-testi__grid > .sf-testi__card {
	margin: 0;
	padding: 24px;
	background: rgba(255, 255, 255, 0.06);
	border-left: 4px solid var(--sf-red);
	border-radius: var(--sf-radius-lg);
	color: rgba(255, 255, 255, 0.88);
	font-size: 1rem;
	line-height: 1.7;
}

.sf-testi__card p {
	margin: 0 0 14px;
	font-family: var(--wp--preset--font-family--serif);
}

.sf-testi__card cite {
	display: block;
	font-style: normal;
	font-size: 0.82rem;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: rgba(255, 255, 255, 0.6);
}

.sf-testi__card cite strong {
	color: var(--sf-red-bright);
}

/* ------------------------------------------------------------ Specialties */
.sf-specialties__grid {
	align-items: center;
	gap: 24px;
}

@media (min-width: 821px) {
	/* The media column stretches to match the text column so the two panels
	   align top and bottom. With space-between, only two children (photo and
	   closing note) were pinned to opposite ends of a ~1200px panel, stranding
	   the note 467px below the photo. Centering keeps the pair together as one
	   group while the panels stay equal height. */
	.sf-specialties__grid > .wp-block-column:last-child {
		align-self: stretch !important;
		display: flex;
		flex-direction: column;
		justify-content: center;
		gap: 24px;
	}
}

/* ------------------------------------------------------------------- CTA */
.sf-cta {
	background: linear-gradient(135deg, var(--sf-red) 0%, var(--sf-red-dark) 100%);
	padding: 64px 16px;
}

.sf-cta__inner {
	max-width: var(--sf-wide);
	margin: 0 auto;
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 24px;
	justify-content: space-between;
}

.sf-cta__text {
	margin: 0;
	flex: 1 1 460px;
	color: #fff;
	font-size: clamp(1.05rem, 2vw, 1.35rem);
	line-height: 1.5;
	font-weight: 500;
}

.sf-cta__btn {
	display: inline-block;
	padding: 15px 34px;
	background: var(--sf-navy);
	color: #fff;
	font-weight: 700;
	font-size: 0.85rem;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	text-decoration: none;
	border-radius: var(--sf-radius);
	transition: background 0.18s ease, transform 0.18s ease, box-shadow 0.25s ease;
}

.sf-cta__btn:hover,
.sf-cta__btn:focus {
	background: #fff;
	color: var(--sf-navy);
	transform: translateY(-2px);
	box-shadow: 0 14px 30px rgba(2, 7, 24, 0.35);
}

/* --------------------------------------------------------------- Contact */
.sf-contact__grid {
	gap: 34px;
}

/* The section lost its form column, so the panel now carries the heading,
   the copy, the CTA and the contact details in one flow. Held to a readable
   measure and centred: a full-width card would have stranded all of it in the
   left half, which is the same half-empty read the split left behind. */
.sf-contact__card {
	max-width: 960px;
	margin-inline: auto;
}

.sf-contact__card > p:not(.sf-eyebrow, .sf-contact-firm, .sf-contact-license) {
	max-width: 68ch;
}

/* The details read as their own band at the foot of the card rather than as
   a continuation of the copy above it. */
.sf-contact__card .sf-contact-firm {
	margin-block-start: 44px;
}

.sf-contact__card .sf-contact-firm,
.sf-contact__card .sf-contact-license {
	max-width: none;
	text-align: center;
}

.sf-contact__card .sf-contact-list li {
	justify-content: center;
}

@media (min-width: 821px) {
	/* Four short rows centred in a 960px panel leave a dead right edge; two
	   per row fills the measure without a second content column. */
	.sf-contact__card .sf-contact-list {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 34px;
	}
}

.sf-contact-list {
	list-style: none;
	margin: 20px 0 0;
	padding: 0;
	display: grid;
	gap: 12px;
}

.sf-contact-list li {
	display: flex;
	align-items: flex-start;
	gap: 11px;
	font-size: 1rem;
	color: var(--sf-slate);
}

.sf-contact-list .sf-icon {
	margin-top: 4px;
	color: var(--sf-red);
}

.sf-contact-list a {
	color: inherit;
	text-decoration: none;
}

.sf-contact-list a:hover {
	color: var(--sf-red-text);
}

/* --------------------------------------------------------------- Buttons */
.wp-block-button:not(.is-style-outline) .wp-block-button__link:hover {
	transform: translateY(-2px);
	box-shadow: 0 12px 26px rgba(4, 26, 56, 0.24);
}

.is-style-outline .wp-block-button__link {
	padding-top: 13px;
	padding-bottom: 13px;
	border: 2px solid var(--sf-navy);
	background: transparent;
	color: var(--sf-navy);
}

.is-style-outline .wp-block-button__link:hover {
	background: var(--sf-navy);
	color: #fff;
}

.is-style-outline-white .wp-block-button__link {
	padding-top: 13px;
	padding-bottom: 13px;
	border: 2px solid rgba(255, 255, 255, 0.55);
	background: transparent;
	color: #fff;
}

.is-style-outline-white .wp-block-button__link:hover {
	background: #fff;
	color: var(--sf-navy);
	border-color: #fff;
}

/* Two places where the uppercase label outgrows its box: the footer's slim
   column and phones under 400px. Tighter gutters keep every button on one
   line instead of letting it break mid-label. */
.sf-footer .wp-block-button__link {
	padding-inline: 16px;
}

@media (max-width: 400px) {
	.wp-block-button__link {
		padding-inline: 26px;
	}

	.is-style-outline .wp-block-button__link,
	.is-style-outline-white .wp-block-button__link {
		padding-inline: 24px;
	}
}

/* --------------------------------------------------------------- Footer */
.sf-footer {
	background: var(--sf-navy);
}

.sf-footer__logo {
	margin-bottom: 16px;
	background: #fff;
	display: inline-block;
	padding: 8px 12px;
	border-radius: var(--sf-radius);
}

.sf-footer__blurb {
	color: rgba(255, 255, 255, 0.7);
	font-size: 1rem;
	line-height: 1.7;
	max-width: 42ch;
	margin: 0 0 20px;
}

.sf-footer__title {
	font-size: 0.85rem;
	text-transform: uppercase;
	letter-spacing: 0.2em;
	color: #fff;
	margin: 0 0 18px;
	padding-bottom: 12px;
	border-bottom: 2px solid var(--sf-red);
}

.sf-footer__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 10px;
}

.sf-footer__list a {
	display: inline-block;
	min-height: 24px;
	padding-block: 4px;
	margin-block: -4px;
	color: rgba(255, 255, 255, 0.74);
	text-decoration: none;
	font-size: 0.92rem;
	transition: color 0.18s ease, padding-left 0.18s ease;
}

.sf-footer__list a:hover {
	color: var(--sf-red-bright);
	padding-left: 4px;
}

.sf-footer .sf-contact-list li,
.sf-footer .sf-contact-list a {
	color: rgba(255, 255, 255, 0.74);
}

/* Also rendered in the light contact band, so the base rule inherits; only the
   navy footer gets the explicit white. */
.sf-contact-firm {
	margin: 0 0 14px;
	font-size: 1.08rem;
	font-weight: 700;
	line-height: 1.35;
	color: inherit;
}

.sf-footer .sf-contact-firm {
	color: #fff;
}

/* Licensee line: names the agent and their licence directly under the firm so
   the affiliation is never in doubt. Negative top margin tucks it up under the
   firm name while keeping the gap before the contact list. */
.sf-contact-license {
	margin: -8px 0 14px;
	font-size: 0.93rem;
	line-height: 1.45;
	color: inherit;
}

.sf-footer .sf-contact-license {
	color: rgba(255, 255, 255, 0.74);
}

/* Licence / affiliation callout in the bio: states plainly that the visitor is
   dealing with a licensed agent under the firm, not an independent business. */
.sf-license-note {
	margin: 0 0 22px;
	padding-left: 15px;
	border-left: 3px solid var(--sf-red);
	font-size: 0.97rem;
	line-height: 1.6;
	color: var(--sf-slate);
}

.sf-footer__btn {
	margin-top: 22px;
}

.sf-footer__rule {
	border-color: rgba(255, 255, 255, 0.14);
	margin: 40px 0 22px;
}

.sf-footer__bottom {
	gap: 16px;
	justify-content: center;
	text-align: center;
}

.sf-copyright {
	margin: 0;
	font-size: 0.84rem;
	color: rgba(255, 255, 255, 0.6);
}

.sf-footer__legal {
	margin: 0;
	font-size: 0.84rem;
	color: rgba(255, 255, 255, 0.6);
}

.sf-footer__legal a {
	color: rgba(255, 255, 255, 0.74);
	text-decoration: none;
	transition: color 0.18s ease;
}

.sf-footer__legal a:hover,
.sf-footer__legal a:focus {
	color: var(--sf-red-bright);
}

/* ----------------------------------------------------------- Responsive */
@media (max-width: 1024px) {
	.sf-about__cards,
	.sf-why__cards,
	.sf-links__grid,
	.sf-testi__grid,
	.wp-block-columns.sf-vmm__grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.sf-stats__grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.sf-stats .sf-stat {
		padding-left: 0;
		border-left: 0;
	}
}

@media (max-width: 700px) {
	.sf-about__cards,
	.sf-why__cards,
	.sf-links__grid,
	.sf-testi__grid,
	.wp-block-columns.sf-vmm__grid {
		grid-template-columns: 1fr;
	}

	.sf-stats__grid {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 820px) {
	/* One row on phones: tap-to-call on the left, social on the right.
	   The email and the address both live in the contact section and the
	   footer, and stacking them here pushed the bar to 111px (155px at
	   320px) before the fold. */
	.sf-topbar__item--email,
	.sf-topbar__item--place {
		display: none;
	}

	.sf-topbar__inner {
		gap: 6px 16px;
		font-size: 0.75rem;
	}

	.sf-hero {
		min-height: 68vh;
	}

	.sf-hero__inner {
		padding: 72px 16px;
	}

	.sf-about__grid,
	.sf-why__feature,
	.sf-specialties__grid,
	.sf-contact__grid {
		flex-direction: column !important;
	}

	.sf-about__grid > .wp-block-column,
	.sf-why__feature > .wp-block-column,
	.sf-specialties__grid > .wp-block-column,
	.sf-contact__grid > .wp-block-column {
		flex-basis: 100% !important;
		width: 100% !important;
		max-width: 100% !important;
	}

	/* Re-set the section padding alongside the rest of the phone block: the
	   base 64px is tuned for a row, and the stacked CTA was reading heavy. */
	.sf-cta {
		padding: 48px 16px;
	}

	/* In column flow flex-basis drives HEIGHT, so the desktop `1 1 460px`
	   (a min text width there) was forcing the paragraph to 460px tall and
	   leaving ~410px of empty red above the button. */
	.sf-cta__inner {
		flex-direction: column;
		align-items: flex-start;
		gap: 20px;
	}

	.sf-cta__text {
		flex: 0 0 auto;
	}

	/* 32px of card padding eats too much of a phone-width column. */
	.sf-why__feature > .wp-block-column:last-child,
	.sf-contact__card {
		padding: 24px;
	}
}


/* --------------------------------------------------------------- Motion */
/* Reveal on scroll. `.sf-anim` is set by an inline script in <head> (see
   functions.php) before the stylesheet prints, so the hidden state can never
   flash; it is removed again if theme.js fails to boot, and it is never
   added under prefers-reduced-motion. The selector list is mirrored in
   assets/js/theme.js — keep both in sync. Nothing in here nests inside
   another entry, so each block animates exactly once. Layout blocks — the
   hero, the two-column splits, the CTA — reveal as ONE unit (their container,
   not each child): the motion budget is 1-2 animated elements per viewport.
   The six repeating CARD grids are the deliberate exception, because six
   identical cards landing as a single block reads as a jump rather than a
   list; those cascade child by child below. */
@media (prefers-reduced-motion: no-preference) {
	.sf-anim .sf-hero__line--brand,
	.sf-anim .sf-hero__sub,
	.sf-anim .sf-hero__cta,
	.sf-anim .sf-intro,
	.sf-anim .sf-about__grid,
	.sf-anim .sf-why__feature,
	.sf-anim .sf-specialties__grid,
	.sf-anim .sf-contact__grid,
	.sf-anim .sf-cta__inner {
		opacity: 0;
		transform: translate3d(0, 18px, 0);
		transition: opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
			transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
		transition-delay: var(--sf-delay, 0ms);
	}

	.sf-anim .is-in {
		opacity: 1;
		transform: none;
	}

	/* A — cascade. These six containers keep being observed (so they keep
	   receiving .is-in) but stop carrying their own opacity/transform: the
	   cards do the moving, so nothing in a section is animated twice. The
	   hidden state therefore lives on the children, and the container being
	   plain-visible before .is-in is harmless because every child is at
	   opacity 0. Delays are explicit nth-child steps rather than --sf-delay
	   because CSS cannot read a child's index into a custom property. */
	.sf-anim .sf-links__grid > *,
	.sf-anim .sf-stats__grid > *,
	.sf-anim .sf-about__cards > *,
	.sf-anim .sf-why__cards > *,
	.sf-anim .sf-vmm__grid > *,
	.sf-anim .sf-testi__grid > * {
		opacity: 0;
		transform: translate3d(0, 18px, 0);
		transition: opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
			transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
	}

	.sf-anim .sf-links__grid.is-in > *,
	.sf-anim .sf-stats__grid.is-in > *,
	.sf-anim .sf-about__cards.is-in > *,
	.sf-anim .sf-why__cards.is-in > *,
	.sf-anim .sf-vmm__grid.is-in > *,
	.sf-anim .sf-testi__grid.is-in > * {
		opacity: 1;
		transform: none;
	}

	/* 60ms steps, so the widest grid (nine testimonials) settles over ~480ms
	   — one cascade per section, never nine independent entrances. Only
	   sf-testi__grid reaches past six children, so 7-9 are scoped to it. */
	.sf-anim .sf-links__grid > :nth-child(1),
	.sf-anim .sf-stats__grid > :nth-child(1),
	.sf-anim .sf-about__cards > :nth-child(1),
	.sf-anim .sf-why__cards > :nth-child(1),
	.sf-anim .sf-vmm__grid > :nth-child(1),
	.sf-anim .sf-testi__grid > :nth-child(1) {
		transition-delay: 0ms;
	}

	.sf-anim .sf-links__grid > :nth-child(2),
	.sf-anim .sf-stats__grid > :nth-child(2),
	.sf-anim .sf-about__cards > :nth-child(2),
	.sf-anim .sf-why__cards > :nth-child(2),
	.sf-anim .sf-vmm__grid > :nth-child(2),
	.sf-anim .sf-testi__grid > :nth-child(2) {
		transition-delay: 60ms;
	}

	.sf-anim .sf-links__grid > :nth-child(3),
	.sf-anim .sf-stats__grid > :nth-child(3),
	.sf-anim .sf-about__cards > :nth-child(3),
	.sf-anim .sf-why__cards > :nth-child(3),
	.sf-anim .sf-vmm__grid > :nth-child(3),
	.sf-anim .sf-testi__grid > :nth-child(3) {
		transition-delay: 120ms;
	}

	.sf-anim .sf-links__grid > :nth-child(4),
	.sf-anim .sf-stats__grid > :nth-child(4),
	.sf-anim .sf-about__cards > :nth-child(4),
	.sf-anim .sf-why__cards > :nth-child(4),
	.sf-anim .sf-vmm__grid > :nth-child(4),
	.sf-anim .sf-testi__grid > :nth-child(4) {
		transition-delay: 180ms;
	}

	.sf-anim .sf-links__grid > :nth-child(5),
	.sf-anim .sf-stats__grid > :nth-child(5),
	.sf-anim .sf-about__cards > :nth-child(5),
	.sf-anim .sf-why__cards > :nth-child(5),
	.sf-anim .sf-vmm__grid > :nth-child(5),
	.sf-anim .sf-testi__grid > :nth-child(5) {
		transition-delay: 240ms;
	}

	.sf-anim .sf-links__grid > :nth-child(6),
	.sf-anim .sf-stats__grid > :nth-child(6),
	.sf-anim .sf-about__cards > :nth-child(6),
	.sf-anim .sf-why__cards > :nth-child(6),
	.sf-anim .sf-vmm__grid > :nth-child(6),
	.sf-anim .sf-testi__grid > :nth-child(6) {
		transition-delay: 300ms;
	}

	.sf-anim .sf-testi__grid > :nth-child(7) {
		transition-delay: 360ms;
	}

	.sf-anim .sf-testi__grid > :nth-child(8) {
		transition-delay: 420ms;
	}

	.sf-anim .sf-testi__grid > :nth-child(9) {
		transition-delay: 480ms;
	}

	/* The cascade above is a REVEAL-only delay, but it lives on
	   `transition-delay` — the same property the hover polish below reads.
	   Left in place it leaks into every mouseover: testimonial 1 answers
	   instantly while testimonial 9 sits out 480ms. `.is-settled` is stamped
	   by theme.js once the reveal has played out, so the stagger is dropped
	   everywhere at once. The child selector needs the parent class to reach
	   specificity (0,3,0) and tie the :nth-child rules above. */
	.sf-anim .is-settled {
		transition-delay: 0s;
	}

	.sf-anim .sf-links__grid.is-settled > *,
	.sf-anim .sf-stats__grid.is-settled > *,
	.sf-anim .sf-about__cards.is-settled > *,
	.sf-anim .sf-why__cards.is-settled > *,
	.sf-anim .sf-vmm__grid.is-settled > *,
	.sf-anim .sf-testi__grid.is-settled > * {
		transition-delay: 0s;
	}

	/* B+C — every section heading (8 eyebrows + 8 headlines) wipes open
	   left-to-right instead of simply rising. Two mechanisms, one result:
	     * view() present  -> the wipe is scroll-driven, so it tracks the
	       scrollbar and can be scrubbed backwards. `animation-timeline` is
	       NOT Baseline (Firefox <159, Safari <=18.7, older Android), so...
	     * view() absent   -> the same wipe runs as a timed transition.
	   Splitting on @supports rather than feature-detecting in JS keeps both
	   paths in the stylesheet with no flash between them.

	   First path: headings that sit OUTSIDE their revealing grid (stats,
	   vmm, testi) must carry their own opacity/transform, because nothing
	   else moves them. Gated on :has() so an engine without it keeps visible
	   static headings rather than ever stranding them at opacity 0. */
	@supports not (animation-timeline: view()) {
		@supports selector(:has(a)) {
			.sf-anim .sf-stats > .sf-eyebrow,
			.sf-anim .sf-vmm > .sf-eyebrow,
			.sf-anim .sf-testi > .sf-eyebrow,
			.sf-anim .sf-stats > .sf-section__title,
			.sf-anim .sf-vmm > .sf-section__title,
			.sf-anim .sf-testi > .sf-section__title {
				opacity: 0;
				transform: translate3d(0, 18px, 0);
				clip-path: inset(-10% 100% -10% 0);
				transition: opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
					transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
					clip-path 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
			}

			.sf-anim .sf-stats:has(> .sf-stats__grid.is-in) > .sf-eyebrow,
			.sf-anim .sf-vmm:has(> .sf-vmm__grid.is-in) > .sf-eyebrow,
			.sf-anim .sf-testi:has(> .sf-testi__grid.is-in) > .sf-eyebrow,
			.sf-anim .sf-stats:has(> .sf-stats__grid.is-in) > .sf-section__title,
			.sf-anim .sf-vmm:has(> .sf-vmm__grid.is-in) > .sf-section__title,
			.sf-anim .sf-testi:has(> .sf-testi__grid.is-in) > .sf-section__title {
				opacity: 1;
				transform: none;
				clip-path: inset(-10% -10% -10% -10%);
			}
		}

		/* Second path: the other five headings are NESTED inside a target
		   that already reveals, so they need no :has() at all — the plain
		   .is-in their own container receives is the trigger. They get the
		   clip only; their container's opacity fade supplies the soft edge,
		   so nothing here can strand them hidden on its own. */
		.sf-anim .sf-intro .sf-eyebrow,
		.sf-anim .sf-about__grid .sf-eyebrow,
		.sf-anim .sf-specialties__grid .sf-eyebrow,
		.sf-anim .sf-contact__grid .sf-eyebrow,
		.sf-anim .sf-intro .sf-section__title,
		.sf-anim .sf-about__grid .sf-section__title,
		.sf-anim .sf-specialties__grid .sf-section__title,
		.sf-anim .sf-contact__grid .sf-section__title {
			clip-path: inset(-10% 100% -10% 0);
			transition: clip-path 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
		}

		.sf-anim .sf-intro.is-in .sf-eyebrow,
		.sf-anim .sf-about__grid.is-in .sf-eyebrow,
		.sf-anim .sf-specialties__grid.is-in .sf-eyebrow,
		.sf-anim .sf-contact__grid.is-in .sf-eyebrow,
		.sf-anim .sf-intro.is-in .sf-section__title,
		.sf-anim .sf-about__grid.is-in .sf-section__title,
		.sf-anim .sf-specialties__grid.is-in .sf-section__title,
		.sf-anim .sf-contact__grid.is-in .sf-section__title {
			clip-path: inset(-10% -10% -10% -10%);
		}
	}

	/* Scroll-driven path. The general rule covers all 16 headings; the more
	   specific one below re-points the three whose heading sits outside its
	   grid at sf-wipe-rise so they keep their own rise. Declaring
	   animation-timeline AFTER the animation shorthand is required — it is a
	   reset-only property the shorthand cannot carry. This whole path also
	   depends on `.sf-section` using `overflow: clip` (see Sections above);
	   with `hidden` the timeline binds to the section instead of the root. */
	@supports (animation-timeline: view()) {
		.sf-anim .sf-section__title,
		.sf-anim .sf-eyebrow {
			animation: sf-wipe linear both;
			animation-timeline: view();
			/* `cover`, not `entry`. The `entry` named range resolves to a
			   hair over a heading's own height on this engine — `entry 0% to
			   entry 40%` moved the whole wipe across 10px of scroll, which
			   is a snap rather than a wipe. `cover` spans the heading's full
			   journey across the scrollport: 25% of it is ~200px of scroll,
			   enough to read as a wipe while still finishing before the
			   heading rises out of the bottom of the viewport, so it can
			   never be left resting half-masked. */
			animation-range: entry 0% cover 25%;
		}

		.sf-anim .sf-stats > .sf-eyebrow,
		.sf-anim .sf-vmm > .sf-eyebrow,
		.sf-anim .sf-testi > .sf-eyebrow,
		.sf-anim .sf-stats > .sf-section__title,
		.sf-anim .sf-vmm > .sf-section__title,
		.sf-anim .sf-testi > .sf-section__title {
			animation-name: sf-wipe-rise;
		}
	}

	/* M3 — the three photographs settle in behind their grid, growing the last
	   4% into place. The FIGURE carries the reveal, never the img, so the
	   hover scale(1.05) stays on an untransitioned element and the two
	   transforms can never compound. It grows FROM 0.96 rather than shrinking
	   from 1.04 so the box never overflows its column and cannot open a
	   horizontal scrollbar mid-reveal. */
	.sf-anim .sf-about__photo,
	.sf-anim .sf-why__photo,
	.sf-anim .sf-specialties__photo {
		opacity: 0;
		transform: scale(0.96);
		transition: opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
			transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
		transition-delay: 80ms;
	}

	.sf-anim .sf-about__grid.is-in .sf-about__photo,
	.sf-anim .sf-why__feature.is-in .sf-why__photo,
	.sf-anim .sf-specialties__grid.is-in .sf-specialties__photo {
		opacity: 1;
		transform: none;
	}

	/* M1 — the mobile menu was the one element on the page that moved not at
	   all (core ships `transition: all 0s` on it), so the overlay snapped in
	   with every row at once. Only the contents animate: the container itself
	   is off-limits, because core toggles `display` on it AND the same element
	   is the plain desktop nav, so giving it its own opacity/transform would
	   fight both. Entrance only — closing stays instant, which is what makes
	   it feel snappy rather than laggy. */
	.wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__responsive-container-content {
		animation: sf-menu-panel 0.3s cubic-bezier(0.22, 0.61, 0.36, 1) both;
	}

	.wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation__responsive-container-close {
		animation: sf-menu-panel 0.3s cubic-bezier(0.22, 0.61, 0.36, 1) 0.06s both;
	}

	.wp-block-navigation__responsive-container.is-menu-open
		.wp-block-navigation-item__content {
		animation: sf-menu-row 0.34s cubic-bezier(0.22, 0.61, 0.36, 1) both;
	}

	.wp-block-navigation__responsive-container.is-menu-open
		li:nth-child(1) .wp-block-navigation-item__content { animation-delay: 0.04s; }
	.wp-block-navigation__responsive-container.is-menu-open
		li:nth-child(2) .wp-block-navigation-item__content { animation-delay: 0.08s; }
	.wp-block-navigation__responsive-container.is-menu-open
		li:nth-child(3) .wp-block-navigation-item__content { animation-delay: 0.12s; }
	.wp-block-navigation__responsive-container.is-menu-open
		li:nth-child(4) .wp-block-navigation-item__content { animation-delay: 0.16s; }
	.wp-block-navigation__responsive-container.is-menu-open
		li:nth-child(5) .wp-block-navigation-item__content { animation-delay: 0.2s; }
	.wp-block-navigation__responsive-container.is-menu-open
		li:nth-child(n + 6) .wp-block-navigation-item__content { animation-delay: 0.24s; }
}

@keyframes sf-menu-panel {
	from {
		opacity: 0;
		transform: translate3d(0, -10px, 0);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes sf-menu-row {
	from {
		opacity: 0;
		transform: translate3d(0, 14px, 0);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

@keyframes sf-sheen {
	from {
		transform: translate3d(-160%, 0, 0) skewX(-18deg);
	}
	to {
		transform: translate3d(320%, 0, 0) skewX(-18deg);
	}
}

/* Headline wipe. The vertical insets are NEGATIVE so the clip box sits just
   outside the border box — inset(0) would cut descenders on a tight line box.
   Every stop stays in percentages so the right edge can sweep 100% -> -10%
   without interpolating a percentage against a length.

   The wipe is clip-path ONLY: no opacity. Fading a masked heading at the same
   rate left it half-transparent AND half-cut mid-wipe, which reads as a
   loading state rather than as motion. Held at full opacity the text stays
   crisp and the sweep reads as a deliberate edge. Before the range starts,
   fill-mode:backwards holds the `from` frame, whose right inset of 100% gives
   a zero-width box — so the heading is hidden by the mask alone. */
@keyframes sf-wipe {
	from {
		clip-path: inset(-10% 100% -10% 0);
	}
	to {
		clip-path: inset(-10% -10% -10% -10%);
	}
}

/* Same wipe, plus the 18px rise, for the three headings whose section never
   reveals its own header block. */
@keyframes sf-wipe-rise {
	from {
		clip-path: inset(-10% 100% -10% 0);
		transform: translate3d(0, 18px, 0);
	}
	to {
		clip-path: inset(-10% -10% -10% -10%);
		transform: none;
	}
}

/* ------------------------------------------------- Interaction polish */
/* Transitions live outside the hover media query so a device that does report
   hover still animates smoothly into it. */
.sf-links__card,
.sf-about__card,
.sf-why__card,
.sf-vmm__card,
.sf-testi__grid > .sf-testi__card {
	transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1),
		box-shadow 0.35s cubic-bezier(0.22, 0.61, 0.36, 1),
		background-color 0.35s ease;
}

.sf-about__photo img,
.sf-why__photo img,
.sf-specialties__photo img {
	transition: transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.sf-links__more a::after {
	display: inline-block;
	transition: transform 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
}

@media (hover: hover) and (pointer: fine) {
	.sf-links__card:hover,
	.sf-about__card:hover,
	.sf-why__card:hover,
	.sf-vmm__card:hover {
		transform: translateY(-6px);
		box-shadow: var(--sf-shadow-lg);
	}

	.sf-testi__grid > .sf-testi__card:hover {
		transform: translateY(-4px);
		background: rgba(255, 255, 255, 0.11);
	}

	.sf-about__photo:hover img,
	.sf-why__photo:hover img,
	.sf-specialties__photo:hover img {
		transform: scale(1.05);
	}

	.sf-links__card:hover .sf-links__more a {
		color: var(--sf-red-dark);
	}

	.sf-links__card:hover .sf-links__more a::after {
		transform: translateX(5px);
	}

	/* Restated below the motion block: `.sf-anim .is-in` sits at the same
	   specificity and would otherwise cancel the lift. */
	.sf-hero__cta:hover,
	.sf-hero__cta:focus {
		transform: translateY(-2px);
		box-shadow: 0 14px 30px rgba(2, 7, 24, 0.4);
	}
}

/* Nav links: a red rule that wipes in from the left. Disabled inside the
   full-screen overlay, where the padded rows would strand it. */
.sf-nav .wp-block-navigation-item__content {
	position: relative;
}

.sf-nav .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2px;
	background: var(--sf-red);
	transform: scaleX(0);
	transform-origin: left center;
	transition: transform 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.sf-nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content::after {
	display: none;
}

@media (hover: hover) and (pointer: fine) {
	.sf-nav .wp-block-navigation-item__content:hover::after,
	.sf-nav .wp-block-navigation-item__content:focus-visible::after {
		transform: scaleX(1);
	}
}

/* --------------------------------------------------------- Button sheen */
/* Both primary buttons invert to WHITE on hover — `.sf-hero__cta:hover` and
   `.sf-cta__btn:hover` each set `background: #fff` — so a conventional white
   gloss would vanish on the very state it is meant to enrich. The sweep is
   navy-tinted instead, which reads as light crossing a dark surface both
   before and during the flip. z-index -1 inside an isolated stacking context
   puts it over the button's own background and under its label; overflow
   clips it to the radius. Filled buttons only: an outline button has no
   background to carry a band across. Runs as a one-shot animation rather than
   a transition so it never plays backwards out of the button on mouseleave. */
.sf-hero__cta,
.sf-cta__btn,
.wp-block-button:not(.is-style-outline) .wp-block-button__link {
	position: relative;
	overflow: hidden;
	isolation: isolate;
}

.sf-hero__cta::after,
.sf-cta__btn::after,
.wp-block-button:not(.is-style-outline) .wp-block-button__link::after {
	content: "";
	position: absolute;
	top: -60%;
	bottom: -60%;
	left: 0;
	width: 55%;
	z-index: -1;
	pointer-events: none;
	background: linear-gradient(
		90deg,
		transparent,
		rgba(4, 26, 56, 0.18),
		transparent
	);
	transform: translate3d(-160%, 0, 0) skewX(-18deg);
}

@media (prefers-reduced-motion: no-preference) {
	@media (hover: hover) and (pointer: fine) {
		.sf-hero__cta:hover::after,
		.sf-cta__btn:hover::after,
		.wp-block-button:not(.is-style-outline) .wp-block-button__link:hover::after {
			animation: sf-sheen 0.6s cubic-bezier(0.22, 0.61, 0.36, 1) both;
		}
	}

	.sf-hero__cta:focus-visible::after,
	.sf-cta__btn:focus-visible::after,
	.wp-block-button:not(.is-style-outline) .wp-block-button__link:focus-visible::after {
		animation: sf-sheen 0.6s cubic-bezier(0.22, 0.61, 0.36, 1) both;
	}
}

/* -------------------------------------------------- Page-level polish */
/* Anchored jumps (#contact-form) must clear the sticky header. */
html {
	scroll-padding-top: 118px;
}

@media (min-width: 601px) {
	html.admin-bar {
		scroll-padding-top: 150px;
	}
}

@media (min-width: 601px) and (max-width: 782px) {
	html.admin-bar {
		scroll-padding-top: 164px;
	}
}

::selection {
	background: var(--sf-navy);
	color: #fff;
}

html {
	scrollbar-color: rgba(4, 26, 56, 0.55) transparent;
	scrollbar-width: thin;
}

::-webkit-scrollbar {
	width: 11px;
	height: 11px;
}

::-webkit-scrollbar-track {
	background: transparent;
}

::-webkit-scrollbar-thumb {
	background: rgba(4, 26, 56, 0.55);
	background-clip: padding-box;
	border: 3px solid transparent;
	border-radius: 999px;
}

::-webkit-scrollbar-thumb:hover {
	background: rgba(4, 26, 56, 0.9);
	background-clip: padding-box;
}

/* Cross-fade between pages; browsers without view transitions ignore this. */
@view-transition {
	navigation: auto;
}

@media (prefers-reduced-motion: no-preference) {
	::view-transition-old(root) {
		animation-duration: 0.22s;
	}

	::view-transition-new(root) {
		animation-duration: 0.34s;
	}
}

/* Reading position: a hairline at the foot of the sticky header. */
.sf-header__progress {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2px;
	background: var(--sf-red);
	transform: scaleX(0);
	transform-origin: 0 50%;
	pointer-events: none;
}

.sf-header.is-scrolled {
	box-shadow: 0 1px 0 rgba(4, 26, 56, 0.08), 0 12px 32px rgba(4, 26, 56, 0.14);
}

/* Reduced motion keeps every hover affordance as a plain state change. */
@media (prefers-reduced-motion: reduce) {
	.sf-links__card:hover,
	.sf-about__card:hover,
	.sf-why__card:hover,
	.sf-vmm__card:hover,
	.sf-testi__grid > .sf-testi__card:hover,
	.sf-about__photo:hover img,
	.sf-why__photo:hover img,
	.sf-specialties__photo:hover img,
	.wp-block-button:not(.is-style-outline) .wp-block-button__link:hover,
	.sf-hero__cta:hover,
	.sf-hero__cta:focus,
	.sf-cta__btn:hover,
	.sf-cta__btn:focus,
	.sf-social a:hover,
	.sf-social a:focus {
		transform: none;
	}
}
