/* Peninsula CRE Group - main stylesheet.
   ------------------------------------------------------------------
   1. Tokens        - mirrors of the Figma variables
   2. Reset         - minimal
   3. Base type     - body and headings only
   4. Scaffolding   - the ten grey section bands, unchanged
   ------------------------------------------------------------------
   Figma variable names use a slash (neutral/ink). A slash is not valid
   in a CSS identifier, so each one becomes a hyphen here and nothing
   else about the name changes: neutral/ink -> --neutral-ink. */

/* ---------- 1. Tokens ---------- */

:root {

	/* Colour - from Figma variables, one to one. */
	--surface-default:       #ffffff;
	--neutral-ink:           #2e2a25;
	--neutral-muted:         #6b655d;
	--neutral-ink-inverse:   #f6f2ec;
	--neutral-muted-inverse: #b8b2aa;
	--neutral-border:        #e4ded5;
	--brand-coral-dark:      #3d2019;
	--brand-ocean:           #6e92a5;
	--brand-ocean-deep:      #4e6d7e;  /* same hue, 5.51:1 on white - for links */
	--brand-ocean-tint:      #e7eef1;
	--brand-ocean-dark:      #17212e;

	/* Colour - used in the design but NOT bound to a Figma variable.
	   Tokenised here so they are never hardcoded into a section later. */
	--gradient-stop-coral:   #d18875;  /* gradient `to` stop   */
	/* The Articles feed cards run ocean, coral and a green the palette did
	   not have. Matched by eye to sit with the other two - confirm against
	   the Figma value when the file is reachable again. */
	--brand-sage:            #7d9470;
	--gradient-stop-navy:    #191d3d;  /* gradient `from` stop */

	/* Form states. Neither is in the Figma palette - the form was drawn with
	   no error and no confirmation. Both are existing families darkened until
	   they carry text: coral for the error, sage for the success. 6.66:1 and
	   6.56:1 on white, so both clear AA on the 14-15px they are used at. */
	--state-error:         #9c3f28;
	--state-error-tint:    #fdf1ee;
	--state-success:       #4f6344;
	--state-success-tint:  #eef3ea;

	/* Scrims, overlays and shadows - all raw rgba in the frame. */
	--scrim-white-0:         rgba(255, 255, 255, 0);
	--scrim-white-12:        rgba(255, 255, 255, 0.12);
	--scrim-white-60:        rgba(255, 255, 255, 0.6);
	--scrim-white-75:        rgba(255, 255, 255, 0.75);
	--scrim-white-85:        rgba(255, 255, 255, 0.85);
	--scrim-white-90:        rgba(255, 255, 255, 0.9);
	--scrim-ocean-dark-0:    rgba(23, 33, 46, 0);      /* #17212e at 0   */
	--scrim-ocean-dark-90:   rgba(23, 33, 46, 0.9);    /* #17212e at 0.9 */
	--scrim-slate-62:        rgba(26, 41, 48, 0.62);   /* #1a2930        */
	--tint-blush-60:         rgba(255, 224, 215, 0.6); /* #ffe0d7        */
	--tint-coral-45:         rgba(194, 104, 78, 0.45); /* #c2684e        */
	--shadow-black-0:        rgba(0, 0, 0, 0);
	--shadow-black-10:       rgba(0, 0, 0, 0.1);
	--shadow-black-16:       rgba(0, 0, 0, 0.16);  /* dropdown lift - no Figma source */

	/* Spacing scale. */
	--space-8:   8px;
	--space-10:  10px;
	--space-12:  12px;
	--space-16:  16px;
	--space-20:  20px;
	--space-24:  24px;
	--space-32:  32px;
	--space-40:  40px;
	--space-48:  48px;
	--space-60:  60px;   /* 100px cut by 40% */
	--space-96:  96px;
	--space-100: 100px;

	/* Hero rhythm - tune these three, nothing else. */
	--hero-space-top:    80px;   /* above the H1            */
	--hero-space-middle: 280px;  /* subhead -> CTA          */
	--hero-space-bottom: 64px;   /* below the answer panel  */
	--space-160: 160px;

	/* Geometry. */
	--radius:          8px;
	--radius-12:       12px;
	--radius-25:       25px;
	--radius-pill:     999px;
	--border-width:    1px;
	--container-width: 1190px;   /* Figma frame width, reference only */
	--container-max:   1400px;   /* content stops spreading here */
	--gutter:          32px;     /* horizontal breathing room at any width */

	/* Type. */
	--font-body:      "Karla", sans-serif;
	--font-heading:   "Lora", serif;
	--font-size-13:   13px;
	--font-size-14:   14px;
	--font-size-15:   15px;
	--font-size-16:   16px;
	--font-size-18:   18px;
	--font-size-19:   19px;
	--font-size-24:   24px;
	--font-size-28:   28px;
	--font-size-30:   30px;
	--font-size-32:   32px;
	--font-size-34:   34px;
	--font-size-40:   40px;
	--font-size-20:   20px;
	--font-size-22:   22px;
	--font-size-base: 16px;
	--font-size-36:   36px;
	--font-size-46:   46px;
	--font-size-52:   52px;
	--font-size-48:   48px;
	--font-size-58:   58px;
	--cta-scale: 1.1;   /* header CTA size multiplier - one knob to tune */

	/* Type roles - the responsive layer retunes these four, nothing else. */
	--type-h1:   var(--font-size-58);
	--type-h2:   var(--font-size-46);
	--type-h3:   var(--font-size-24);
	--type-body: var(--font-size-22);

	/* Vertical rhythm of a section, likewise. */
	--section-space: var(--space-100);

	--font-weight-regular:  400;
	--font-weight-semibold: 600;

	/* Scaffold only - not design values. Placeholder boxes stand in for
	   images until the media library is populated. */
	--placeholder-bg:  #d8d8d8;
	--placeholder-ink: #555555;
}

/* ---------- 1b. Layout container ---------- */

/* One container for every full-bleed section's contents, so the header
   and the hero line up on the same left and right edges. */
.container {
	width: 100%;
	max-width: var(--container-max);
	margin-inline: auto;
	padding-inline: var(--gutter);
}

/* ---------- 2. Reset ---------- */

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

body {
	margin: 0;
}

/* ---------- 3. Base type ---------- */

body {
	font-family: var(--font-body);
	font-size: var(--font-size-base);
	font-weight: var(--font-weight-regular);
	color: var(--neutral-ink);
}

h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var(--font-heading);
	font-weight: var(--font-weight-semibold);
}

/* ---------- 3a. Skip link ----------
   The first focusable element on every page, and the only way past a header
   that costs ten tab stops. Hidden exactly the way .screen-reader-text is -
   clipped to a single pixel rather than display:none, which would take it out
   of the tab order and leave it useless.

   :focus rather than :focus-visible on purpose. The link is unreachable by
   mouse or touch, so any focus it gets is a keyboard visitor who needs to see
   it, and :focus-visible heuristics are not worth the risk here.

   Colours are the existing dark band and its text: #f6f2ec on #17212e is
   14.56:1, comfortably clear of the 4.5:1 the focused state has to meet. */

.skip-link {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.skip-link:focus {
	/* Fixed, not absolute, so it lands in the same corner no matter how far
	   the page happens to be scrolled when it is focused. */
	position: fixed;
	top: var(--space-8);
	left: var(--space-8);
	z-index: 100;
	width: auto;
	height: auto;
	margin: 0;
	padding: var(--space-12) var(--space-16);
	overflow: visible;
	clip-path: none;
	border-radius: var(--radius);
	background: var(--brand-ocean-dark);
	font-family: var(--font-body);
	font-size: var(--font-size-16);
	font-weight: var(--font-weight-semibold);
	line-height: 1;
	color: var(--neutral-ink-inverse);
	text-decoration: none;
	outline: 2px solid var(--brand-ocean-deep);
	outline-offset: 2px;
}

/* The skip target itself. It takes tabindex="-1" so it can receive focus, and
   that would otherwise draw a focus ring around the whole page when the link
   is used. The ring belongs on the link, not on everything below it. */
.site-main:focus {
	outline: none;
}

/* ---------- 4. Scaffolding ----------
   Structural placeholders only. Greys and borders here are scaffold
   values, not design values, and come out when sections are built. */

.site-main .scaffold {
	display: flex;
	align-items: center;
	justify-content: center;
	border-bottom: 1px solid #999;
	background: #fff;
}

.site-main .scaffold:nth-of-type(even) {
	background: #f0f0f0;
}

.section-label {
	line-height: 1.4;
	text-align: center;
}


/* Figma section heights - scaffold placeholders only.
   Built sections carry no fixed height and no min-height. */
.services            { min-height: 470px; }
.broker-loyalty      { min-height: 520px; }
.one-principal       { min-height: 1009px; }
.proven-results      { min-height: 300px; }
.recent-win          { min-height: 769px; }
.client-testimonials { min-height: 314px; }
.recognition         { min-height: 373px; }
.not-for-everyone    { min-height: 834px; }
.final-cta           { min-height: 327px; }

/* ---------- 5. Hero (Figma node 212:100) ---------- */

.placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--placeholder-bg);
	color: var(--placeholder-ink);
	text-align: center;
}


/* No fixed height and no min-height: the section sizes to its content.
   Vertical rhythm is padding + gap, never leftover space. */
.hero {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--hero-space-middle);
	padding-top: var(--hero-space-top);
	padding-bottom: var(--hero-space-bottom);
	overflow: hidden;
}

.hero__media {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.hero__photo {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	/* Source is 3122x2138, 1.46:1. The band has no fixed height - it sizes to
	   its text - so its ratio runs from about 1.29 at 1280 to 2.76 at 2560.
	   Wherever the band is wider in proportion than the photograph, cover
	   scales by width, crops top and bottom, and this value is what decides
	   which slice survives. Where the band is narrower - tablet and phone,
	   where it is taller than it is wide - cover scales by height instead,
	   the whole height of the photograph shows, and this value does nothing.
	   Worth knowing before reaching for it to fix a phone.

	   60% rather than centred because the top of the frame is blown-out
	   window: at 35% a wide viewport spent a third of the band on empty sky
	   and left Corina small and low. 60% holds the crop below that. */
	object-position: center 60%;
}

.hero__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to bottom,
		var(--scrim-white-90) 20.947%,
		var(--scrim-white-0) 50.136%
	);
}

.hero__intro,
.hero__actions {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	width: 100%;
}

.hero__intro  { gap: 28px; }
.hero__actions { gap: 20px; }

.hero__headline {
	width: 100%;
	max-width: 1300px;
	margin: 0;
	font-size: var(--type-h1);
	line-height: 1.18;
	letter-spacing: -0.18px;
	color: var(--neutral-ink);
	text-align: center;
}

.hero__headline em {
	font-style: italic;
}

/* Each sentence holds its own line - the second must never trail the first. */
.hero__headline-line {
	display: block;
}

.hero__subhead {
	width: 100%;
	max-width: 900px;
	margin: 0;
	font-size: var(--font-size-22);
	line-height: 1.2;
	letter-spacing: -0.32px;
	color: var(--neutral-ink);
	text-align: center;
	overflow-wrap: break-word;
}

/* Everything is em off one font-size, so --cta-scale-main moves the whole
   button. Figma's spec is scale 1 (16px label, 13/26 inner, 3/18 wrapper);
   both instances - hero and Final CTA - run at 1.25. */
.cta-button {
	--cta-scale-main: 1.25;
	display: inline-flex;
	align-items: center;
	padding: 0.125em;
	border-radius: var(--radius-pill);
	background: var(--scrim-white-60);
	box-shadow: 0 0 25px 5px var(--tint-blush-60);
	font-size: calc(var(--font-size-base) * var(--cta-scale-main));
	text-decoration: none;
}

.cta-button__inner {
	display: flex;
	align-items: center;
	gap: 0.5em;
	padding: 0.1875em 1.125em 0.1875em 0.1875em;
	border-radius: var(--radius-25);
	background: var(--shadow-black-0);
}

.cta-button__label {
	padding: 0.8125em 1.625em;
	border-radius: var(--radius-pill);
	background: linear-gradient(
		to right,
		var(--gradient-stop-navy),
		var(--gradient-stop-coral)
	);
	font-weight: var(--font-weight-semibold);
	font-size: 1em;
	color: var(--neutral-ink-inverse);
	white-space: nowrap;
}

.cta-button__icon {
	display: block;
	width: 1.125em;
	height: 1.125em;
	flex: none;
}

.hero__trust {
	display: flex;
	justify-content: center;
	padding: var(--space-32);
	border-radius: var(--radius-12);
	/* The alpha belongs on the background, not on the element. opacity here
	   fades the panel AND the words inside it, and the words are the thing
	   that has to survive being read over a photograph. Measured at 1440 with
	   opacity: 0.9 the copy ran 3.91:1 against the 4.5 it needs; with the same
	   translucency moved into the background it clears comfortably.

	   Making the panel more see-through, which is the instinctive fix, makes
	   it worse - 0.60 measures 3.37:1. */
	background: var(--scrim-white-85);
}

.hero__trust p {
	width: 100%;
	max-width: 900px;
	margin: 0;
	font-size: var(--font-size-22);
	line-height: 1.2;
	letter-spacing: -0.32px;
	color: var(--neutral-ink);
	text-align: center;
	overflow-wrap: break-word;
}

/* ---------- 6. Site header (Figma node 212:88) ---------- */

.site-header {
	background: var(--surface-default);
	border-bottom: var(--border-width) solid var(--neutral-border);
}

/* Interior variant (Figma node 223:86). Identical to the default header in
   every respect except the background fill: brand/ocean-tint. Not applied
   to any page yet. */
.site-header--interior {
	background: var(--brand-ocean-tint);
}

.site-header__inner {
	display: flex;
	align-items: center;
	gap: var(--space-32);
	padding-block: var(--space-10);
}

/* Logo takes the slack, so nav + CTA sit together on the right. */
.site-header__logo {
	margin-inline-end: auto;
}

.site-header__logo {
	display: block;
	flex: none;
	line-height: 0;
}

.site-header__logo-img {
	display: block;
	width: 280px;
	height: auto;
}

/* --- Primary navigation --- */

.site-nav__list,
.site-nav__list .sub-menu {
	display: flex;
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-nav__list {
	gap: var(--space-16);
	align-items: center;
}

.site-nav__list li {
	position: relative;
}

.site-nav__list a,
.site-nav__list .menu-label {
	display: block;
	padding: 8px 16px;
	border-radius: var(--radius-pill);
	font-size: var(--font-size-18);
	line-height: 1.4;
	color: var(--neutral-ink);
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
}

/* Current page: tinted pill, darker ink, heavier weight. */
.site-nav__list .current-menu-item > a,
.site-nav__list .current_page_item > a,
.site-nav__list .current-menu-ancestor > a {
	background: var(--brand-ocean-tint);
	font-weight: var(--font-weight-semibold);
	color: var(--brand-ocean-dark);
}

/* Hover/focus wins over the active state - solid ocean, inverse ink. */
.site-nav__list a:hover,
.site-nav__list a:focus-visible,
.site-nav__list .menu-label:hover,
.site-nav__list .menu-label:focus-visible,
.site-nav__list .current-menu-item > a:hover,
.site-nav__list .current_page_item > a:hover {
	background: var(--brand-ocean);
	color: var(--neutral-ink-inverse);
}

/* --- Dropdowns (desktop hover / keyboard focus) --- */

.site-nav__list .sub-menu {
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 10;
	display: none;
	flex-direction: column;
	gap: 2px;
	min-width: 220px;
	padding: var(--space-8);
	border: var(--border-width) solid var(--neutral-border);
	border-radius: var(--radius-12);
	background: var(--surface-default);
	box-shadow:
		0 16px 40px var(--shadow-black-16),
		0 2px 6px var(--shadow-black-10);
}

.site-nav__list > li:hover > .sub-menu,
.site-nav__list > li:focus-within > .sub-menu {
	display: flex;
}

.site-nav__list .sub-menu a {
	border-radius: var(--radius);
	font-size: var(--font-size-base);
	white-space: normal;
}

/* --- Header CTA (Figma node 544:344, "CTA Button - Coral Header") --- */

/* Sized in em from one font-size so --cta-scale moves the whole button.
   Base (scale 1) is the Figma spec: 14px label, 9/18 inner, 4/9 outer. */
.header-cta {
	display: inline-flex;
	flex: none;
	align-items: center;
	/* Even inset all round. The lopsided version was inherited from the hero
	   button, where the extra right-hand padding makes room for the arrow
	   icon. This button has no arrow, so that allowance just read as the pill
	   being off-centre inside its border. */
	padding: 0.286em;
	border: 2px solid var(--brand-coral-dark);
	border-radius: var(--radius-pill);
	font-size: calc(var(--font-size-14) * var(--cta-scale));
	filter: drop-shadow(0 0 12px var(--tint-coral-45));
	text-decoration: none;
}

.header-cta__label {
	padding: 0.643em 1.286em;
	border-radius: var(--radius-pill);
	background: linear-gradient(
		to right,
		var(--gradient-stop-navy),
		var(--gradient-stop-coral)
	);
	font-weight: var(--font-weight-semibold);
	font-size: 1em;
	color: var(--neutral-ink-inverse);
	white-space: nowrap;
}

/* ---------- 7. Site footer (Figma node 212:254) ----------
   Appearance from Figma; content from the locked document and BIL 2.2. */

.site-footer {
	position: relative;
	overflow: hidden;
	padding-block: var(--space-100) var(--space-160);
	background: var(--brand-ocean-dark);
	color: var(--neutral-ink-inverse);
}

/* Figma places this at 520x524 inside a 1200x389 footer, offset to x780 /
   y-20 - so roughly 19% is cropped off the right edge and a quarter off the
   bottom. It is meant to read as a fragment bleeding out of the corner, not
   as a complete logo sitting in space. Scaled to our taller footer, the same
   proportions mean a larger mark hung off the right and bottom. */
.site-footer__watermark {
	position: absolute;
	top: -26px;
	right: -130px;
	width: 690px;
	height: auto;
	opacity: 0.05;
	pointer-events: none;
}

.site-footer__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: var(--space-40);
}

.site-footer__top {
	/* Three equal columns spread across the container rather than packed
	   left. All three align to their own left edge. */
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--space-48);
	align-items: start;
	text-align: left;
}

/* --- Brand + social --- */

.site-footer__brand {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: var(--space-24);
}

/* White logo. Figma's footer has no logo image - it uses a 20px text
   lockup in a 262px column - so the mark is sized to sit inside that
   column, and smaller than the header's 280px so the footer stays
   subordinate. */
.site-footer__logo {
	display: block;
	width: 100%;
	max-width: 240px;
	height: auto;
}

.site-footer__social {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-12) var(--space-16);
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Colour and underline are reset explicitly: until these links carried text
   they were an image apiece, so the browser default never showed. */
.site-footer__social a {
	display: flex;
	align-items: center;
	gap: var(--space-8);
	line-height: 0;
	color: inherit;
	text-decoration: none;
	opacity: 0.85;
}

.site-footer__social a:hover,
.site-footer__social a:focus-visible {
	opacity: 1;
}

.site-footer__social img {
	display: block;
	width: 24px;
	height: auto;
}

/* The firm's LinkedIn and Corina's own share one glyph, so each is named in
   the open. Small, tracked and muted: enough to tell them apart at a glance
   without the labels competing with the marks they sit beside. */
.site-footer__social-name {
	font-size: var(--font-size-13);
	font-weight: var(--font-weight-semibold);
	line-height: 1;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: var(--neutral-muted-inverse);
	white-space: nowrap;
}

.site-footer__social a:hover .site-footer__social-name,
.site-footer__social a:focus-visible .site-footer__social-name {
	color: var(--neutral-ink-inverse);
}

/* --- NAP --- */

.site-footer__nap {
	display: flex;
	flex-direction: column;
	gap: 2px;
	font-style: normal;
	line-height: 1.5;
	color: var(--neutral-muted-inverse);
}

.site-footer__nap-name {
	color: var(--neutral-ink-inverse);
}

.site-footer__nap a {
	color: var(--neutral-muted-inverse);
	text-decoration: none;
}

.site-footer__nap a:hover,
.site-footer__nap a:focus-visible {
	color: var(--neutral-ink-inverse);
	text-decoration: underline;
}

/* --- Footer navigation (WordPress 'footer' menu) --- */

.site-footer__nav-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-12);
	margin: 0;
	padding: 0;
	list-style: none;
}

.site-footer__nav-list a {
	color: var(--neutral-muted-inverse);
	text-decoration: none;
	white-space: nowrap;
}

.site-footer__nav-list a:hover,
.site-footer__nav-list a:focus-visible {
	color: var(--neutral-ink-inverse);
	text-decoration: underline;
}

/* --- Rule + licences --- */

.site-footer__rule {
	width: 100%;
	height: var(--border-width);
	margin: 0;
	border: 0;
	background: var(--neutral-border);
	opacity: 0.25;
}

.site-footer__licences {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--space-8) var(--space-24);
	text-align: center;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: var(--font-size-15);
	line-height: 1.5;
	color: var(--neutral-muted-inverse);
}

.site-footer__licences li + li::before {
	content: "\00b7";
	margin-inline-end: var(--space-24);
}

.site-footer__copyright {
	margin: var(--space-16) 0 0;
	text-align: center;
	font-size: var(--font-size-13);
	line-height: 1.5;
	color: var(--neutral-muted-inverse);
}

/* ---------- 8. Reusable section + card patterns ----------
   These classes are shared: later pages reuse them rather than
   restyling per section. */

.section {
	padding-block: var(--section-space);
}

.section__eyebrow {
	margin: 0 0 var(--space-20);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-13);
	letter-spacing: 1.04px;
	color: var(--neutral-muted);
	text-align: center;
	text-transform: uppercase;
}

.section__title {
	max-width: 900px;
	margin: 0 auto var(--space-32);
	font-size: var(--type-h2);
	line-height: 1.18;
	letter-spacing: -0.18px;
	color: var(--neutral-ink);
	text-align: center;
}

.section__title--wide {
	max-width: 1100px;
}

.section__title--left {
	margin-inline: 0;
	text-align: left;
}

.section__subtitle {
	max-width: 814px;
	margin: var(--space-48) auto var(--space-20);
	font-family: var(--font-heading);
	font-weight: var(--font-weight-semibold);
	font-size: var(--type-h3);
	line-height: 1.18;
	letter-spacing: -0.12px;
	color: var(--neutral-ink);
	text-align: center;
}

.section__lead {
	margin: 0 0 var(--space-20);
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

/* Body copy blocks - max-width, never width. */
.prose {
	display: flex;
	flex-direction: column;
	gap: var(--space-16);
	max-width: 700px;
	margin: 0 auto;
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

.prose--centered { text-align: center; }
.prose--wide     { max-width: 900px; }
.prose p         { margin: 0; }

/* Content links: the palette blue darkened to clear AA on body-size text.
   Scoped to paragraphs inside main, so every text block is covered no matter
   which layout wrapper it sits in - card and button links are unaffected. */
.site-main p a {
	color: var(--brand-ocean-deep);
	text-decoration-color: var(--brand-ocean);
	text-underline-offset: 3px;
}

.site-main p a:hover,
.site-main p a:focus-visible {
	color: var(--brand-ocean-dark);
	text-decoration-color: currentColor;
}

/* --- Card grids: fr columns, never fixed pixels --- */

.card-grid {
	display: grid;
	gap: var(--space-20);
	margin: var(--space-32) 0 0;
	padding: 0;
	list-style: none;
}

.card-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.card-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Region cards read better without running the full container width. */
.region-grid {
	max-width: 1100px;
	margin-inline: auto;
}

/* --- Card base --- */

.card {
	display: flex;
	flex-direction: column;
	padding: var(--space-24);
	border-radius: var(--radius-12);
}

/* --- Service card: dark panel, cream icon and text --- */

.service-card {
	position: relative;
	overflow: hidden;
	/* aspect-ratio, not a fixed height - the card scales with its column. */
	aspect-ratio: 212 / 293;
	gap: var(--space-12);
	justify-content: flex-end;
	background: var(--brand-ocean-dark);
	color: var(--neutral-ink-inverse);
}

.service-card__media {
	position: absolute;
	inset: 0;
	display: block;
}

.service-card__photo {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Figma's gradient: transparent at the top, near-solid ocean-dark by 65%,
   so the icon and copy stay legible over any photo. */
.service-card__media::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to bottom,
		var(--scrim-ocean-dark-0) 0%,
		var(--scrim-ocean-dark-90) 65%
	);
}

.service-card > *:not(.service-card__media) {
	position: relative;
	z-index: 1;
}

.service-card__icon {
	width: 100px;
	height: auto;
	margin-bottom: var(--space-8);
	align-self: center;
}

.service-card__title {
	margin: 0;
	font-family: var(--font-body);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-24);
	line-height: 1.2;
	color: var(--neutral-ink-inverse);
	text-align: center;
}

.service-card__text {
	margin: 0;
	font-size: var(--font-size-18);
	line-height: 1.4;
	color: var(--neutral-ink-inverse);
}

/* --- Region card: white to ocean-tint, lifted --- */

.region-card {
	gap: var(--space-16);
	height: 100%;
	background: linear-gradient(to bottom, var(--surface-default), var(--brand-ocean-tint));
	box-shadow: 0 6px 16px var(--shadow-black-10);
	text-decoration: none;
	text-align: left;
}

.region-card:hover,
.region-card:focus-visible {
	box-shadow: 0 10px 24px var(--shadow-black-16);
}

/* --- Corridor variant: a solid tint instead of the white-to-tint gradient,
   so the card holds a defined edge against the page rather than dissolving
   into it. Scoped to the county corridor grids on purpose - the homepage
   region grid keeps the gradient and must stay byte-identical. Radius,
   shadow, padding and type all inherit from .card / .region-card. --- */

.region-card--corridor {
	background: var(--brand-ocean-tint);
}

/* --brand-ocean #6e92a5 measures 2.83:1 on the solid tint - under 4.5:1 and
   under even the 3:1 large-text floor, because the title sits at the top of
   the card where the gradient used to still be white. --brand-ocean-deep is
   the same hue one step down the ramp and measures 4.69:1. Corridor-scoped
   so the homepage heading colour does not move. */
.region-card--corridor .region-card__title {
	color: var(--brand-ocean-deep);
}

.region-card__title {
	margin: 0;
	font-family: var(--font-body);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-24);
	line-height: 1.3;
	color: var(--brand-ocean);
}

.region-card__lead {
	margin: 0;
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-18);
	line-height: 1.4;
	color: var(--neutral-ink);
}

.region-card__lead span {
	font-weight: var(--font-weight-regular);
	font-size: var(--font-size-16, 16px);
	color: var(--neutral-muted);
}

.city-columns {
	columns: 2;
	column-gap: var(--space-24);
	margin: 0;
	padding-inline-start: 1.1em;
	list-style: disc;
	font-size: var(--font-size-18);
	line-height: 1.35;
	color: var(--neutral-muted);
}

.city-columns li {
	break-inside: avoid;
}

.city-columns li::marker {
	color: var(--brand-ocean);
}

/* --- Callout: tinted pull-quote box --- */

.callout {
	padding: var(--space-20);
	border-radius: var(--radius-12);
	background: var(--brand-ocean-tint);
}

.callout p {
	max-width: 579px;
	margin: 0;
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

/* --- Split layout: copy beside an image --- */

.split {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
	gap: var(--space-48);
	align-items: center;
}

.split__body {
	display: flex;
	flex-direction: column;
	gap: var(--space-24);
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

.split__body > p { margin: 0; max-width: 640px; }

.split__media { justify-self: center; }

.split__photo {
	display: block;
	width: 100%;
	max-width: 420px;
	height: auto;
}

/* ---------- 9. Section-specific ---------- */

.services {
	background: var(--surface-default);
}

.broker-loyalty {
	/* No bottom padding: the portrait is bottom-aligned and finishes flush
	   with the section edge. */
	padding-bottom: 0;
	background: var(--surface-default);
}

.one-principal {
	position: relative;
	overflow: hidden;
	background: var(--surface-default);
}

/* Figma tints this section's map with an ocean mix-blend-screen. A low
   opacity map reads the same way while keeping the copy legible. */
.one-principal__map {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	opacity: 0.16;
	pointer-events: none;
}

.one-principal__inner {
	position: relative;
}

/* ---------- 10. More reusable patterns ---------- */

.section--dark {
	position: relative;
	overflow: hidden;
	background: var(--brand-ocean-dark);
	color: var(--neutral-ink-inverse);
}

.section__title--inverse { color: var(--neutral-ink-inverse); }

.section__subtitle--left {
	margin-inline: 0;
	margin-top: 0;
	text-align: left;
}

.section__subtitle--flush { margin-top: 0; }

/* Sized to the page's H2s. The element stays <h3> - the locked document
   sets the level, this only matches the size. */
.section__subtitle--lg {
	max-width: 900px;
	font-size: var(--type-h2);
}

.section__subtitle--accent { color: var(--brand-ocean); }

.prose--inverse { color: var(--neutral-muted-inverse); }
.prose--inverse a { color: var(--neutral-ink-inverse); }

.card-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* Two-up override. The testimonials row carries two cards, so the shared
   three-column grid would leave its third column empty. The county submarket
   grids still want three, hence a modifier rather than an edit to
   .card-grid--3 itself.

   Bounded at min-width 769 on purpose: .card-grid--3 collapses to one column
   inside the 768 and 600 max-width blocks below, and those single-class rules
   would lose to this two-class selector. Keeping this above the breakpoint
   leaves the existing stacking untouched. */
@media (min-width: 769px) {
	.card-grid--3.card-grid--two-up { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- Stat bar --- */

.stat-grid {
	/* A little more air between the heading and the figures. */
	margin-top: var(--space-48);
	text-align: center;
}

.stat {
	display: flex;
	flex-direction: column;
	gap: var(--space-8);
	align-items: center;
}

.stat__value {
	margin: 0;
	font-family: var(--font-heading);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-40);
	line-height: 1.04;
	letter-spacing: -0.34px;
	color: var(--neutral-ink-inverse);
}

.stat__label {
	/* Wider measure so the bump to 16px doesn't add extra wrapped lines.
	   Colour stays --neutral-muted-inverse: it must read as secondary to
	   the figure above it. */
	max-width: 280px;
	margin: 0;
	font-size: var(--font-size-16);
	line-height: 1.35;
	color: var(--neutral-muted-inverse);
}

/* --- Split modifier: image first --- */

.split--media-first {
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
}

.split--media-first .split__media { order: -1; justify-self: stretch; }

.split__photo--framed {
	max-width: 100%;
	border-radius: var(--radius-12);
}

/* Lifts a photo off a tinted background - same shadow language as the
   region cards, so it reads as one system. */
.split__photo--raised {
	box-shadow: 0 6px 16px var(--shadow-black-16);
}

/* --- Review cards --- */

.review-card {
	gap: var(--space-16);
	background: var(--surface-default);
	border: var(--border-width) solid var(--neutral-border);
	box-shadow: 0 6px 16px var(--shadow-black-10);
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

/* The third review has a quote glyph where the others carry a source mark. */
.review-card__quote {
	display: block;
	font-family: var(--font-heading);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-46);
	line-height: 0.6;
	color: var(--brand-ocean);
}

.review-card p { margin: 0; }

.review-card__mark {
	width: 28px;
	height: auto;
}

/* --- Objection list --- */

.objection-list {
	max-width: 1000px;
	margin: 0 auto var(--space-48);
	padding: 0;
	list-style: none;
}

.objection {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	column-gap: var(--space-32);
	/* Lines inside a pair are tight; the padding between pairs is wider, so
	   a condition and its response group together instead of reading as two
	   parallel lists. */
	padding-block: var(--space-24);
	border-bottom: var(--border-width) solid var(--neutral-border);
	line-height: 1.25;
	letter-spacing: -0.32px;
}

.objection:last-child { border-bottom: 0; }

.objection__if,
.objection__then { margin: 0; }

/* The condition: quieter and a step smaller. */
.objection__if {
	font-size: var(--font-size-20);
	font-weight: var(--font-weight-regular);
	color: var(--neutral-muted);
}

/* The response: full size, full ink, heavier - this is the answer. */
.objection__then {
	font-weight: var(--font-weight-semibold);
	color: var(--neutral-ink);
}

/* --- Emphasised callout --- */

.callout--emphasis {
	max-width: 1000px;
	margin-inline: auto;
	text-align: center;
}

.callout--emphasis p {
	max-width: 794px;
	margin-inline: auto;
	font-style: italic;
	font-size: var(--font-size-24);
	color: var(--neutral-ink);
}

/* --- More wins block --- */

.more-wins { margin-top: var(--space-48); }

/* Recent Win sits on the pale blue, and its two headings are sized to the
   page's H2s. The elements stay <h3> - the locked document sets the level,
   this only matches the size. Deliberately scoped: What Clients Say and
   Recognition were asked to stay at H3 size. */
.recent-win {
	background: var(--brand-ocean-tint);
}


/* --- Recognition --- */

.recognition__logo {
	width: 240px;
	height: auto;
}

/* --- Final CTA --- */

.final-cta { background: var(--brand-ocean-tint); }

.final-cta__bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	pointer-events: none;
}

.final-cta__scrim {
	position: absolute;
	inset: 0;
	background: var(--scrim-slate-62);
	pointer-events: none;
}

.final-cta__inner {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--space-24);
}

.final-cta .section__title { margin-bottom: 0; }


/* ---------- 11. Section body scale + broker layout ---------- */

/* Reusable: a section whose body copy runs at the larger 22px size.
   Anything that sets its own font-size (titles, cards) is unaffected. */
.section--body-lg {
	font-size: var(--type-body);
}

.section__title--flush { margin-top: 0; }

/* Most Brokers: two columns, but the callout spans the whole row and the
   portrait sits above it - the arrangement Figma draws. */
.broker-grid {
	display: grid;
	grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
	/* Fourth row is a slack absorber. The portrait is taller than the copy
	   stack, and without it the browser shares that extra height out across
	   the three content rows - which shows up as oversized gaps between the
	   lead line, the callout and the paragraphs. The 1fr row soaks it up and
	   drops it below the copy instead. */
	grid-template-rows: auto auto auto 1fr;
	column-gap: var(--space-48);
	row-gap: var(--space-24);
	align-items: start;
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

.broker-grid__intro   { grid-column: 1; grid-row: 1; }

/* The lead line is the last thing in the intro block - its own bottom margin
   stacked on top of the grid row-gap, which read as a double gap above the
   callout. The row-gap alone now sets that distance. */
.broker-grid__intro > :last-child { margin-bottom: 0; }
.broker-grid__callout { grid-column: 1 / -1; grid-row: 2; }
.broker-grid__rest    { grid-column: 1; grid-row: 3; }

.broker-grid__media {
	position: relative;
	z-index: 1;               /* portrait sits over the full-width callout */
	grid-column: 2;
	grid-row: 1 / -1;
	align-self: end;
	justify-self: center;
}

/* The portrait fills its column rather than stopping at the shared 420px cap,
   which left 128px of the 548px column empty and made her look undersized
   against the copy beside her. align-self: end above keeps her bottom flush
   with the section, which has no bottom padding - she is what closes it.

   Bounded to the two-column layout on purpose. Below 993 the grid stacks and
   the column becomes the full container, where 100% would be far too large;
   the stacked sizes are set in the 992 and 768 blocks. Those cannot simply
   override this one - this selector is more specific than the bare
   .split__photo they use, and specificity beats source order across media
   queries - so this rule has to be the one that stays out of their way. */
@media (min-width: 993px) {
	/* 484 rather than the 548 the column would allow. Filling the column
	   outright was too much - half that increase reads better against the
	   copy beside her.

	   The negative margin is the point of the pair. She is bottom-anchored to
	   a section with no bottom padding, so making her taller would otherwise
	   grow the section and push her bottom edge down the page. Pulling her up
	   by 60 lets the extra height go into the white space above her instead,
	   where it was wanted: the section grows 28px rather than 175. */
	.broker-grid__media .split__photo { max-width: 484px; }
	.broker-grid__media { margin-top: -60px; }
}

.broker-grid__rest {
	display: flex;
	flex-direction: column;
	gap: var(--space-24);
}

.broker-grid__rest p { margin: 0; max-width: 100%; }

/* Full-width panel, but the copy stops clear of the portrait. */
.broker-grid__callout p { max-width: 68%; }

/* ---------- 12. Recognition panel (Figma node 295:299) ----------
   Conference photo behind a white wash, GlobeSt lockup left, copy right. */

/* Recognition sits tighter to its neighbours: 60px a side rather than 100,
   which halves-ish the 200px gaps above and below. */
.recognition { padding-block: var(--space-60); }
.client-testimonials { padding-bottom: var(--space-60); }
.not-for-everyone { padding-top: var(--space-60); }

.recognition-panel {
	position: relative;
	overflow: hidden;
	border-radius: var(--radius-12);
	box-shadow: 0 6px 16px var(--shadow-black-10);
}

.recognition-panel__bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.recognition-panel__scrim {
	position: absolute;
	inset: 0;
	background: var(--scrim-white-75);
}

.recognition-panel__inner {
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
	gap: var(--space-48);
	align-items: start;
	padding: var(--space-48);
}

.recognition-panel__logo {
	display: block;
	width: 100%;
	max-width: 300px;
	height: auto;
	/* "WOMEN OF INFLUENCE SERIES" is baked into this PNG at #a3a9b1, far too
	   light. The file is transparent-backed and the wordmark is pure black,
	   so a brightness multiplier darkens the grey subtitle while black stays
	   black. Proper fix is a replacement asset. */
	filter: brightness(0.62);
}

.recognition-panel__body {
	display: flex;
	flex-direction: column;
	gap: var(--space-16);
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-ink);
}

.recognition-panel__body p { margin: 0; }

/* ---------- 13. Nav toggle (desktop: hidden, panel is display:contents) ---------- */

.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Panel dissolves on desktop so nav + CTA remain direct children of the
   header row. Desktop layout is therefore completely unchanged. */
.site-header__panel { display: contents; }

.nav-toggle {
	display: none;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 48px;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
	display: block;
	width: 26px;
	height: 2px;
	background: var(--neutral-ink);
	transition: transform 0.18s ease, opacity 0.18s ease;
}

.nav-toggle__bars {
	position: relative;
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
	content: "";
	position: absolute;
	left: 0;
}

.nav-toggle__bars::before { top: -8px; }
.nav-toggle__bars::after  { top: 8px; }

.is-nav-open .nav-toggle__bars { background: transparent; }
.is-nav-open .nav-toggle__bars::before { transform: translateY(8px) rotate(45deg); }
.is-nav-open .nav-toggle__bars::after  { transform: translateY(-8px) rotate(-45deg); }

/* ---------- 14. Responsive ----------
   Desktop-first: every rule below is a max-width query, so nothing here can
   alter the locked desktop rendering. */

/* --- 1200: type eases down, wide headings release their caps --- */
@media (max-width: 1200px) {
	:root {
		--type-h1: var(--font-size-52);
		--type-h2: var(--font-size-40);
		--gutter: 28px;
		--section-space: 80px;
	}

	.hero__headline,
	.section__title,
	.section__title--wide,
	.section__subtitle--lg { max-width: 100%; }

	.hero {
		--hero-space-top: 64px;
		--hero-space-middle: 200px;
		--hero-space-bottom: 56px;
	}
}

/* --- 992: columns halve, splits stack, mobile nav takes over --- */
/* --- 1180: the header hands over to the panel ---
   Measured, not guessed: with the full menu the header row needs 1125px and
   overflows the page below that. It used to hand over at 992, which left a
   band from 993 to 1124 where the desktop nav was still on and the page
   scrolled sideways by up to 132px - on all 14 pages, and invisible unless you
   happen to test inside that band.

   1180 gives 55px of margin over the measured 1125, so a menu item can be
   added without this reopening. Nothing here shrinks the logo, the nav type or
   the CTA; it is the existing panel treatment, starting earlier.

   assets/js/main.js matches on (min-width: 1181px) to reset the open panel
   when the viewport grows back past this. The two have to agree. */
@media (max-width: 1180px) {
	/* Header becomes a panel */
	.site-header { position: relative; }

	.nav-toggle { display: inline-flex; }

	.site-header__logo { margin-inline-end: auto; }

	.site-header__logo-img { width: 220px; }

	.site-header__panel {
		display: none;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		z-index: 30;
		flex-direction: column;
		align-items: flex-start;
		gap: var(--space-24);
		padding: var(--space-24) var(--gutter) var(--space-32);
		background: var(--surface-default);
		border-top: var(--border-width) solid var(--neutral-border);
		box-shadow: 0 16px 40px var(--shadow-black-16);
	}

	.is-nav-open .site-header__panel { display: flex; }

	.site-nav { width: 100%; }

	.site-nav__list {
		flex-direction: column;
		align-items: stretch;
		gap: var(--space-8);
		width: 100%;
	}

	/* Dropdowns are always open in the panel - there is no hover on touch. */
	.site-nav__list .sub-menu {
		position: static;
		display: flex;
		min-width: 0;
		margin-inline-start: var(--space-16);
		padding: 0;
		border: 0;
		border-radius: 0;
		background: none;
		box-shadow: none;
	}

	.site-nav__list a,
	.site-nav__list .menu-label { padding: 10px 12px; }

}

@media (max-width: 992px) {
	:root {
		--type-h1: var(--font-size-46);
		--type-h2: var(--font-size-36);
		--gutter: 24px;
		--section-space: 72px;
	}

	.hero {
		--hero-space-middle: 150px;
	}

	/* Multi-column groups halve */
	.card-grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	/* Splits and panels stack */
	.split,
	.split--media-first,
	.broker-grid,
	.recognition-panel__inner {
		grid-template-columns: minmax(0, 1fr);
	}

	.split--media-first .split__media { order: 0; }

	.broker-grid__intro,
	.broker-grid__callout,
	.broker-grid__rest,
	.broker-grid__media {
		grid-column: 1;
		grid-row: auto;
	}

	.broker-grid__media { justify-self: center; }
	.broker-grid__rest p,
	.broker-grid__callout p { max-width: 100%; }

	.broker-loyalty { padding-bottom: var(--section-space); }

	.region-grid { max-width: 100%; }

	.split__photo { max-width: 420px; }

	.site-footer__watermark { width: 480px; right: -90px; }
}

/* --- 768: single column, mobile type --- */
@media (max-width: 768px) {
	:root {
		--type-h1: var(--font-size-40);
		--type-h2: var(--font-size-30);
		/* h3 goes to 28 so it stays clear of 24px body copy. */
		--type-h3: var(--font-size-28);
		--type-body: var(--font-size-24);
		--gutter: 20px;
		--section-space: 56px;
	}

	.hero {
		--hero-space-top: 48px;
		/* 221 rather than the original 96. On a tablet the crop is still
		   horizontal, so Corina is drawn large; 146 was enough to clear her
		   jaw but read tight, so this adds another 75. The band grows with it,
		   which is fine here. Phones override this again below. */
		--hero-space-middle: 221px;
		--hero-space-bottom: 40px;
	}

	.hero__subhead,
	.hero__trust p { font-size: var(--type-body); }

	.hero__trust { padding: var(--space-24); }

	.site-header__logo-img { width: 180px; }

	/* Tablet keeps two columns - a single stack makes these far too large.
	   The phone query below drops them to one. */
	.card-grid--4,
	.card-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

	.card-grid--3 { grid-template-columns: minmax(0, 1fr); }

	/* Corina's portrait was filling the whole column once stacked. */
	.broker-grid__media .split__photo { max-width: 400px; }

	/* Breathing room under the last paragraph of that section. */
	.broker-loyalty { padding-bottom: var(--section-space); }

	.service-card__text { font-size: var(--font-size-20); }

	/* Lease photo to a widescreen crop so it stops dominating the page.
	   Biased upward so the LEASE APPROVED stamp survives the crop. */
	.recent-win .split__photo {
		width: 100%;
		max-width: 100%;
		aspect-ratio: 16 / 9;
		object-fit: cover;
		object-position: center 30%;
	}

	/* Footer centres completely */
	.site-footer__top {
		justify-items: center;
		text-align: center;
	}

	.site-footer__brand { align-items: center; }
	.site-footer__social { justify-content: center; }
	.site-footer__nap { align-items: center; }
	.site-footer__nav-list { align-items: center; }

	.service-card {
		aspect-ratio: auto;
		justify-content: flex-start;
		padding-top: var(--space-32);
	}

	.service-card__icon { width: 76px; }

	/* Stat bar reads as a stacked list */
	.stat__value { font-size: var(--font-size-32); }

	.city-columns { columns: 1; }

	/* Condition above response, still grouped as a pair */
	.objection {
		grid-template-columns: minmax(0, 1fr);
		row-gap: var(--space-8);
	}

	.callout--emphasis p { font-size: var(--type-h3); }

	/* Footer stacks */
	.site-footer__top { grid-template-columns: minmax(0, 1fr); }

	.site-footer__licences {
		flex-direction: column;
		align-items: center;
		gap: var(--space-8);
	}

	.site-footer__licences li + li::before { content: none; margin: 0; }

	.site-footer { padding-block: var(--space-60) var(--space-96); }

	.site-footer__watermark { width: 360px; right: -70px; top: -18px; }

	.recognition-panel__inner { padding: var(--space-24); }

	.recognition-panel__logo { max-width: 220px; }
}

/* --- 600: handsets. Everything to a single column. --- */
@media (max-width: 600px) {
	:root {
		/* 18px read small on a handset; 20 sits better without disturbing
		   the tablet or desktop scale. */
		--type-body: var(--font-size-20);
	}

	/* The button sits directly under the subhead on a phone, so the headline,
	   the subhead and the CTA are all reachable without scrolling. It does
	   cross Corina's face, and that is the accepted trade: clearing her costs
	   more than it is worth here, because the band has no fixed height and
	   grows by whatever is added, carrying her face down with it at about half
	   the rate. The button reached the fold before it reached her chin.

	   Getting the CTA clear of her face AND above the fold needs a phone crop
	   with her lower in frame; object-position cannot do it, because it has no
	   effect while the crop is horizontal. */
	/* The stack above the button is tightened and the 30px that frees is
	   handed to the gap below it. 28 -> 14 between headline and subhead,
	   32 -> 16 between subhead and button, and 150 -> 180 after it.

	   The band comes out the same height, which is the point: Corina sits at a
	   fixed fraction of it, so she does not move, while the button rises 30px
	   and uncovers another 30px of her face. Tightening alone would have moved
	   her up with everything else and shown no more of her. */
	.hero__intro { gap: 14px; }
	.hero { --hero-space-middle: 16px; }

	/* 150 between the button and the answer panel, against 20 everywhere else.
	   This is what makes her face visible on a phone, and it works by a route
	   the subhead gap could not: the button stays put under the subhead, the
	   band grows by the extra 130, and Corina - who sits at a fixed fraction
	   of the band - travels down past the button into the window this opens.
	   Widening the gap above the button instead would have carried her down
	   with it and never uncovered her. */
	.hero__actions { gap: 180px; }

	.card-grid--4,
	.card-grid--3,
	.card-grid--2 { grid-template-columns: minmax(0, 1fr); }

	.broker-grid__media .split__photo { max-width: 100%; }

	.service-card__text { font-size: var(--font-size-20); }

	.hero__subhead,
	.hero__trust p { font-size: var(--font-size-20); }
}

/* ---------- 15. Legal pages (Terms, Privacy) ----------
   Text-only, one measure, with the monogram held fixed behind the copy so
   the text scrolls over it. */

.legal {
	position: relative;
	overflow: hidden;
	padding-block: var(--section-space);
	background: var(--surface-default);
}

/* position:fixed, so the mark stays put while the page scrolls past it. */
.legal__watermark {
	position: fixed;
	top: 50%;
	right: -140px;
	z-index: 0;
	width: 620px;
	height: auto;
	transform: translateY(-50%);
	opacity: 0.04;
	pointer-events: none;
}

.legal__inner {
	position: relative;
	z-index: 1;
	max-width: 900px;
	margin-inline: auto;
	font-size: var(--type-body);
	line-height: 1.55;
	color: var(--neutral-muted);
}

.legal__title {
	margin: 0 0 var(--space-24);
	font-size: var(--type-h1);
	line-height: 1.12;
	letter-spacing: -0.18px;
	color: var(--neutral-ink);
}

.legal__lead {
	margin: 0 0 var(--space-48);
	font-size: var(--type-h3);
	line-height: 1.4;
	color: var(--neutral-ink);
}

.legal__inner h2 {
	margin: var(--space-60) 0 var(--space-20);
	font-size: var(--type-h2);
	line-height: 1.18;
	letter-spacing: -0.18px;
	color: var(--neutral-ink);
}

.legal__inner h2:first-of-type { margin-top: 0; }

.legal__inner p { margin: 0 0 var(--space-20); }
.legal__inner p:last-child { margin-bottom: 0; }

.legal__inner ul {
	margin: 0 0 var(--space-20);
	padding-inline-start: 1.2em;
	list-style: disc;
}

.legal__inner li { margin-bottom: var(--space-8); }
.legal__inner li::marker { color: var(--brand-ocean); }

/* A rule between sections, echoing the horizontal rules in the source doc. */
.legal__inner h2::before {
	content: "";
	display: block;
	width: 100%;
	height: var(--border-width);
	margin-bottom: var(--space-48);
	background: var(--neutral-border);
}

.legal__inner h2:first-of-type::before { content: none; }

/* Contact / licence blocks */
.legal__contact {
	display: flex;
	flex-direction: column;
	gap: 2px;
	margin: 0 0 var(--space-20);
	padding: var(--space-24);
	border-radius: var(--radius-12);
	background: var(--brand-ocean-tint);
	font-style: normal;
	color: var(--neutral-ink);
}

.legal__contact strong { font-weight: var(--font-weight-semibold); }

.legal__licence {
	font-weight: var(--font-weight-semibold);
	color: var(--brand-ocean-dark);
}

@media (max-width: 768px) {
	.legal__watermark { width: 420px; right: -120px; }
	.legal__inner h2 { margin-top: var(--space-48); }
}

/* ---------- 16. Generic page primitives ----------
   Added while building About Us, but written generic rather than
   About-specific so every interior page can use them. Nothing above this
   block was modified. The locked type roles handle their own reflow, so
   these need no breakpoint overrides. */

/* Page H1.
   The base h1-h6 rules set family and weight only - no size - so an unclassed
   heading renders at body size. The two H1s that exist are bound to their
   pages (.hero__headline to the homepage hero, .legal__title to Terms and
   Privacy). This is the neutral one. Alignment is inherited rather than set,
   so it works left or centred without needing a modifier. Line-height and
   letter-spacing match .hero__headline so H1s look identical sitewide. */
.page-title {
	margin: 0 0 var(--space-24);
	font-size: var(--type-h1);
	line-height: 1.18;
	letter-spacing: -0.18px;
	color: var(--neutral-ink);
}

/* Pale background band, the light counterpart to .section--dark. Section
   backgrounds were previously alternated through per-section classes, which
   meant a new page had to re-implement the alternation. */
.section--tint {
	background: var(--brand-ocean-tint);
}

/* A row for one or more CTAs, separated from the copy above it. Centred by
   default; --left for a CTA sitting under left-aligned copy in a split.
   .hero__actions and .final-cta__inner are the homepage-bound equivalents. */
.section__actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-20);
	justify-content: center;
	margin-top: var(--space-48);
}

.section__actions--left {
	justify-content: flex-start;
}

/* A closing block under a card grid or media row. .card-grid sets its own top
   margin but nothing after it does, so a trailing line would otherwise butt
   straight against the grid. */
.section__outro {
	margin-top: var(--space-48);
}

/* ---------- 17. Layered sections, media splits, logo rows, chips ----------
   Added for the About Us design pass. Written generic so any page can use
   them. Nothing above this block was modified. The two scrim tokens follow
   the existing --scrim-<colour>-<alpha> naming. */

:root {
	--scrim-ocean-tint-0:  rgba(231, 238, 241, 0);    /* #e7eef1 at 0    */
	--scrim-ocean-tint-88: rgba(231, 238, 241, 0.88); /* #e7eef1 at 0.88 */
	--space-30: 30px;
	--space-80: 80px;
}

/* --- A section carrying a background image behind its content ---
   .section--dark already positions itself; this is the equivalent for any
   other section that needs to layer a photo and a scrim. */
.section--layered {
	position: relative;
	overflow: hidden;
}

.section__bg {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	pointer-events: none;
}

.section__scrim {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

/* Holds the tint solid over the trailing half and fades it out across the
   leading half, so copy on the right stays legible while the photo shows
   through on the left. */
.section__scrim--tint-right {
	background: linear-gradient(
		to left,
		var(--scrim-ocean-tint-88) 44%,
		var(--scrim-ocean-tint-0) 100%
	);
}

/* Lifts content above .section__bg and .section__scrim. */
.section__content {
	position: relative;
	z-index: 1;
}

/* --- Split variant: media leads, in the narrower column ---
   .split is 1.35fr/1fr with the copy first. .split--media-first reorders
   without changing the track widths, which would put a small image in the
   wide track. This flips the ratio instead, so media written first in the
   markup sits in the narrow leading column and the copy keeps the wide one. */
.split--media-start {
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.8fr);
}

/* --- Photo cropped to a fixed card rather than running at its own height ---
   Ratio is a custom property so a page can set its own without a new class. */
.split__photo--cover {
	--photo-ratio: 9 / 8;
	/* A cap, not 100% - the shared .split__photo cap lives inside a media
	   query, so a percentage here would win once the split stacks and the
	   card would run the full page width. */
	max-width: 620px;
	aspect-ratio: var(--photo-ratio);
	object-fit: cover;
	border-radius: var(--radius-12);
}

/* --- A wrapping row of third-party marks (credentials, press, partners) ---
   Heights are optical, not uniform: a wordmark and a round badge read as the
   same weight only when the badge is allowed to be taller. */
.logo-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	/* Left, on the same edge as the copy above it - the design hangs the row
	   off the text's left margin, not the centre of the band. */
	justify-content: flex-start;
	gap: var(--space-24) var(--space-32);
	margin-top: var(--space-40);
}

.logo-row__item {
	display: block;
	width: auto;
	height: auto;
	max-width: 100%;
	max-height: 38px;
}

/* Square or circular marks, which need more height to match a wordmark. */
.logo-row__item--badge {
	max-height: 88px;
}

/* A credential set as type rather than supplied as a logo. Uppercase and
   tracked out so it carries the weight of a mark standing beside real ones
   instead of reading as a stray line of copy. The height cap is released -
   it constrains an image's intrinsic ratio, and a span has none.

   max-width is the load-bearing rule. Set on one line the type runs ~236px
   against the 175px the logo it replaces occupied, which pushes the row onto
   an extra line at every width. Capped here it breaks after the ampersand
   into a two-line lockup ~118px wide, so the row keeps the line count the
   breakpoints below were tuned for. In em, so it tracks the font size. */
.logo-row__wordmark {
	max-height: none;
	max-width: 8.5em;
	font-family: var(--font-body);
	font-size: var(--font-size-18);
	font-weight: var(--font-weight-semibold);
	line-height: 1.1;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--neutral-ink);
}

/* --- Chips: a row of short pill links --- */
.chip-list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-12);
	margin: var(--space-32) 0 0;
	padding: 0;
	list-style: none;
}

.chip {
	display: inline-block;
	padding: var(--space-8) var(--space-16);
	border: 1.5px solid var(--brand-ocean);
	border-radius: var(--radius-pill);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-18);
	line-height: 1.2;
	color: var(--brand-ocean-deep);
	text-decoration: none;
}

.chip:hover,
.chip:focus-visible {
	background: var(--brand-ocean);
	color: var(--neutral-ink-inverse);
}

/* --- Objection list on a dark section ---
   The component's own colours are tuned for light backgrounds. This is the
   inverse pairing, matching .prose--inverse and .section__title--inverse. */
.objection-list--inverse .objection {
	border-bottom-color: var(--scrim-white-12);
}

.objection-list--inverse .objection__if {
	color: var(--neutral-muted-inverse);
}

.objection-list--inverse .objection__then {
	color: var(--neutral-ink-inverse);
}

/* --- Responsive for the classes above. The shared breakpoints already stack
   .split; this new modifier sets its own columns later in the file, so it
   needs its own override at the same width. --- */

@media (max-width: 992px) {
	.split--media-start {
		grid-template-columns: minmax(0, 1fr);
	}

	/* The scrim's horizontal fade assumes side-by-side columns. Once they
	   stack, hold the tint across the whole band so the copy stays readable
	   over the photo. */
	.section__scrim--tint-right {
		background: var(--scrim-ocean-tint-88);
	}
}

/* The CTA label is nowrap so short labels never break mid-phrase. Long ones
   need permission to wrap once the viewport gets narrow, or the pill runs off
   the side of the screen. */
@media (max-width: 600px) {
	.cta-button--wrap .cta-button__label {
		white-space: normal;
		text-align: center;
	}
}

@media (max-width: 768px) {
	/* Sized to clear one line at 768. At the desktop scale the row is 816px
	   wide against 728px of content, so the fifth mark was stranding itself
	   on a line of its own. */
	.logo-row {
		gap: var(--space-20) var(--space-24);
	}

	.logo-row__item {
		max-height: 28px;
	}

	.logo-row__item--badge {
		max-height: 64px;
	}

	/* max-height is restated because .logo-row__item above resets it at each
	   breakpoint and carries the same specificity, so the later rule wins. */
	.logo-row__wordmark {
		max-height: none;
		font-size: var(--font-size-15);
		letter-spacing: 0.06em;
	}

	.chip-list {
		justify-content: flex-start;
	}
}

/* ---------- 18. Split measure, ratios and rhythm ----------
   Review round: the image needed to be larger, the columns needed to favour
   the copy, the rows needed more air at the sides, and the vertical rhythm
   needed tightening. Generic, additive; nothing above was modified. */

/* Copy leads and takes roughly 70%, media trails at 30%. */
.split--media-narrow {
	grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
}

/* --- A section whose media sits on the boundary with the next one ---
   Removes the bottom padding so a photo can meet the edge, giving the
   following section's background a line for the subject to stand on. */
.section--flush-bottom {
	padding-bottom: 0;
}

.split__media--bottom {
	align-self: end;
}

/* Media that fills its side of the row top to bottom. Used where the copy
   column is the taller of the two - the locked H1 is large enough that a
   photo sized to its own ratio would float with a gap above it. Paired with
   .section--flush-bottom the photo meets the section edge exactly. */
.split__media--fill {
	align-self: stretch;
	justify-self: stretch;
	display: flex;
}

.split__media--fill .split__photo {
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	object-position: center;
}

/* --- Rhythm ---
   Declared after .section--tight so a flush-bottom section still wins. */
.section--tight {
	padding-block: var(--space-60);
}

/* A step more air than --tight. For a band that has to hold its own against
   what sits above it - the intro photo runs flush to the seam, so its
   neighbour needs clearance or the heading crowds the image. */
.section--airy {
	padding-block: var(--space-80);
}

.section--flush-bottom.section--tight {
	padding-bottom: 0;
}

/* A heading directly above copy inside a split, where the parent's own gap
   already separates them and the default 32px reads as a gap too many. */
.section__title--tight {
	margin-bottom: 0;
}

@media (max-width: 992px) {
	.split--media-narrow {
		grid-template-columns: minmax(0, 1fr);
	}

	/* Stacked, a media-led row puts its copy last, so that section needs its
	   floor back or the text collides with the next band. A copy-led row ends
	   on the photo, so it stays flush at every width. */
	.section--flush-bottom.section--flush-desktop,
	.section--flush-bottom.section--flush-desktop.section--tight {
		padding-bottom: var(--space-60);
	}

	.split__media--bottom {
		align-self: auto;
	}

	/* Stacked, there is no taller neighbour to match, so the photo goes back
	   to its own ratio instead of stretching to an arbitrary height. */
	.split__media--fill {
		align-self: auto;
		justify-self: center;
	}

	.split__media--fill .split__photo {
		height: auto;
		max-width: 620px;
	}
}

/* ---------- 19. One page measure ----------
   Review round 3. The page had grown three different row widths (1200 for the
   intro, 1000 for the split rows, 900 for the centred text), which staggered
   the left edge by 150px down the page. Everything now runs off the shared
   container, with the centred text blocks widened to sit as close to it as a
   readable line length allows. The .split--inset / --inset-tight / --even
   classes from round 2 are gone; nothing used them once the insets were
   dropped. */

/* The intro carries a 58px H1 that needs at least 680px to hold three lines,
   measured, and the photo should still be the larger it was asked to be. This
   ratio gives the copy ~700 and the photo ~590 on a 1440 viewport. */
.split--balanced {
	/* The copy track has a hard floor: the 58px H1 needs 680px to hold three
	   lines, measured. Everything left over goes to the photo, and the column
	   gap is tightened to 24px to hand it another 24px. This is the widest the
	   photo can be without pushing the H1 onto a fourth line. */
	grid-template-columns: minmax(0, 1.16fr) minmax(0, 1fr);
	column-gap: var(--space-24);
}

/* Body copy in a split caps at 640px, which was set for the homepage's
   narrower columns. At the full container width that leaves the track visibly
   unfilled. 820px is the same character count the design uses, scaled to our
   larger body size. */
.split--balanced .split__body > p,
.split--media-start .split__body > p,
.split--media-narrow .split__body > p {
	max-width: 820px;
}

/* Media in these rows should fill its track rather than stop at the shared
   420px cap, which was sized for the homepage. */
.split--media-start .split__photo,
.split--media-narrow .split__photo {
	max-width: none;
}

/* A wider measure for centred passages, so a full-width text section lines up
   closer to the split rows above and below it. */
.prose--xwide {
	max-width: 1100px;
}

/* A flush-bottom section drops its padding so the photo can meet the edge.
   The copy column still needs clearance, or the last line sits on the seam. */
.section--flush-bottom .split__body {
	padding-bottom: var(--space-24);
}

@media (max-width: 992px) {
	.split--balanced {
		grid-template-columns: minmax(0, 1fr);
	}

	/* Stacked, the images go back to the shared cap so they do not run the
	   full width of the page. */
	.split--media-start .split__photo,
	.split--media-narrow .split__photo {
		max-width: 420px;
	}
}

/* ---------- 20. One left edge ----------
   The split rows run off the container, so a centred text block sat 150px
   inside them and the page read as three different widths. These put the
   full-width sections on the same left edge and the same 820px copy measure
   the split rows use. The closing CTA stays centred, as the design has it. */

.prose--left {
	max-width: 820px;
	margin-inline: 0;
}

.objection-list--left {
	max-width: 1000px;
	margin-inline: 0;
}

/* ---------- 21. Section watermark and pull quote ----------
   Generic, additive. The watermark is the footer's treatment lifted onto any
   dark section; the pull quote is a richer alternative to .callout--emphasis
   for a quote that needs to carry a section on its own. */

/* The monogram bleeding out of the right edge, as the footer does it. The
   parent needs to be positioned - .section--dark already is.

   The mark is square (400x403), and sized deliberately larger than the band
   is tall so it crops top and bottom as well as right. Roughly half of it is
   off the edge, so it reads as a big sweeping fragment rather than a whole
   logo parked in the corner. */
.section__watermark {
	position: absolute;
	top: 50%;
	right: -430px;
	width: 900px;
	height: auto;
	transform: translateY(-50%);
	opacity: 0.05;
	pointer-events: none;
}

/* Scaled back where the band is narrower than the mark. */
@media (max-width: 992px) {
	.section__watermark {
		right: -240px;
		width: 620px;
	}
}

@media (max-width: 600px) {
	.section__watermark {
		right: -160px;
		width: 440px;
	}
}

/* --- Pull quote --- */

.pull-quote {
	position: relative;
	max-width: 820px;
	margin: var(--space-40) 0;
	/* Left padding opens a gutter for the glyph so it never sits on the
	   lead-in. */
	padding: var(--space-32) var(--space-40) var(--space-32) 104px;
	border-left: 3px solid var(--brand-ocean);
	border-radius: 0 var(--radius-12) var(--radius-12) 0;
	background: var(--scrim-white-12);
}

/* Sits in the left gutter beside the quote - the same oversized glyph
   language as .review-card__quote on the homepage, scaled up. */
.pull-quote__glyph {
	position: absolute;
	top: 6px;
	left: var(--space-24);
	z-index: 0;
	font-family: var(--font-heading);
	font-weight: var(--font-weight-semibold);
	font-size: 130px;
	line-height: 1;
	color: var(--brand-ocean);
	opacity: 0.4;
	pointer-events: none;
	user-select: none;
}

.pull-quote__lead {
	display: block;
	margin-bottom: var(--space-12);
	font-family: var(--font-body);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-13);
	font-style: normal;
	letter-spacing: 1.04px;
	color: var(--brand-ocean);
	text-transform: uppercase;
}

.pull-quote__text {
	position: relative;
	z-index: 1;
	margin: 0;
	font-family: var(--font-heading);
	font-style: italic;
	font-size: var(--type-h3);
	line-height: 1.45;
	letter-spacing: -0.12px;
	color: var(--neutral-ink-inverse);
}

@media (max-width: 768px) {
	.pull-quote {
		padding: var(--space-24) var(--space-24) var(--space-24) 72px;
	}

	.pull-quote__glyph {
		font-size: 96px;
		top: 4px;
		left: var(--space-16);
	}
}

/* On a phone the gutter would take a third of the line, so the glyph moves
   above the quote and the text gets the full width back at body size. */
@media (max-width: 600px) {
	.pull-quote {
		padding: 60px var(--space-20) var(--space-24);
	}

	.pull-quote__glyph {
		top: 6px;
		left: var(--space-16);
		font-size: 80px;
	}

	.pull-quote__text {
		font-size: var(--type-body);
	}
}

/* ---------- 22. Seams between sections that share a background ----------
   Two sections on the same background read as one block, but the padding on
   both sides of the seam adds up - a 60px band each side is a 120px gap that
   looks like a mistake rather than a division. These halve the padding at the
   seam only; the outer edges of the pair keep the page's normal rhythm. */

.section--seam-below {
	padding-bottom: var(--space-16);
}

.section--seam-above {
	padding-top: var(--space-16);
}

/* Stacked, the two columns no longer centre against each other, so the slack
   that padded the seam on desktop disappears. Give it back, or the sections
   collide. */
@media (max-width: 992px) {
	.section--seam-below {
		padding-bottom: var(--space-30);
	}

	.section--seam-above {
		padding-top: var(--space-30);
	}
}

/* ---------- 23. Wider copy measure for the full-width sections ----------
   The 820px measure read as ~60% of the container. The design runs its body
   copy to roughly three quarters of the band, so these sections get a wider
   left-aligned measure. Section 2 is deliberately excluded - it is locked at
   820 and its quote panel is built to that width. */

.prose--left-wide {
	max-width: 1000px;
	margin-inline: 0;
}

/* ---------- 24. Photo scale, and a wide centred measure ---------- */

/* Scales a photo down inside its track without touching the column ratio, so
   the copy beside it keeps its width. The ratio is a custom property, so a
   page can dial it without another class. */
/* Doubled up deliberately: .split--media-start .split__photo clears the cap
   with two classes, so a single-class modifier would lose to it. */
.split__photo.split__photo--scaled {
	max-width: var(--photo-scale, 80%);
}

/* Stacked, a percentage of the full page width is far too big - the same
   doubled selector is needed again to beat the two-class cap above. */
@media (max-width: 992px) {
	.split__photo.split__photo--scaled {
		max-width: 420px;
	}
}

/* The centred counterpart to .prose--left-wide: same measure, centred block,
   centred text. */
.prose--center-wide {
	max-width: 1000px;
	margin-inline: auto;
	text-align: center;
}

/* ---------- 25. CTA pulled closer to its copy ----------
   Where a CTA belongs to the paragraph above it rather than closing out the
   whole section, the default 48px lead-in reads as a disconnect. This halves
   the space above and hands exactly that much back below, so the block's
   height - and therefore the section's - is unchanged. */

.section__actions--tight {
	margin-top: var(--space-16);
	margin-bottom: var(--space-32);
}

/* ---------- 26. Logo row on a phone ----------
   No arrangement of five marks reads well left-aligned across 350px - they
   wrap into four ragged lines with the round badge stranded beside a
   wordmark. Smaller and centred, they settle into two tidy rows. */

@media (max-width: 600px) {
	.logo-row {
		justify-content: center;
		gap: var(--space-20);
	}

	.logo-row__item {
		max-height: 24px;
	}

	.logo-row__item--badge {
		max-height: 52px;
	}

	.logo-row__wordmark {
		max-height: none;
		font-size: var(--font-size-14);
		letter-spacing: 0.05em;
	}
}

/* ---------- 27. Stacked-layout corrections ---------- */

@media (max-width: 992px) {
	/* Line art that carries its own generous internal padding. At the size the
	   photos use, that padding becomes a visible gap between the art and the
	   heading beneath it, so the box is scaled down and the dead space below
	   the artwork is pulled back.

	   Measured off the source files: the assumption icon is 17.8% empty below
	   its artwork and the shield 19.3%, which at a 300px box is ~53px for
	   both. Removing it leaves the layout's own 48px gap doing the spacing
	   instead of the asset's padding. Tune per asset with --art-trim. */
	.split__photo.split__photo--art {
		max-width: 300px;
		margin-bottom: calc(-1 * var(--art-trim, 53px));
	}

	/* Puts the media above the copy once stacked, for a row that is copy-led
	   side by side. Without it, alternating rows read icon/text then
	   text/icon down the page instead of a consistent icon/text rhythm. */
	.split--stack-media-first .split__media {
		order: -1;
	}
}

/* ---------- 28. Services page components ----------
   Added for the Services build. Generic, additive; no existing shared class
   was modified. */

:root {
	/* The closing-statement panel on Who This Isn't For. Figma calls this
	   brand/peach-tint; it is the only warm surface in the palette. */
	--brand-peach-tint: #faeee5;
}

/* --- A narrow leading column for a heading beside its copy ---
   .split is 1.35:1 with the copy leading. This is the inverse shape: a short
   heading held in a narrow first column with the body text beside it. Named
   for what it is rather than for media, because nothing here is an image. */
.split--aside {
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
}

/* --- Dash list ---
   An em-dash bulleted list. .city-columns is the only other list style and it
   is disc-marked and two-column, so it does not fit. */
.dash-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-12);
	margin: 0;
	padding: 0;
	list-style: none;
}

.dash-list li {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: var(--space-12);
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

.dash-list li::before {
	content: "\2014";
	color: var(--brand-ocean);
}

/* --- Peach closing panel ---
   .callout is the ocean-tint box. This is its warm counterpart, used to close
   a section rather than to interrupt one, so it is roomier and centred. */
/* A closing line that has to land, sitting at the foot of a card that ends on
   a result. It borrows .callout's tinted band and changes only what a
   conclusion needs: ink instead of muted, one step up in size, and the full
   measure rather than .callout's 579px Figma width.

   The size is relative rather than a token on purpose. The copy it follows is
   --type-body, which is 22, 24 and 20 across the three breakpoints, so any
   fixed token would read as a step up at one width and level or smaller at
   another. 1.125em is a step up wherever it lands.

   Generic: nothing here names a page, and any card that ends on an outcome can
   carry it. */
/* .split centres its two columns against each other, which is right when the
   copy and the picture are of similar height. Inside a disclosure the picture
   is much the taller of the two, and centring drops the first line of copy a
   long way down the card. Start-aligned reads as one block instead.

   Scoped rather than a change to .split, which is shared and settled. */
.accordion__body .split {
	align-items: start;
}

.callout--outcome {
	background: var(--brand-ocean-deep);
}

.callout--outcome p {
	max-width: 100%;
	font-size: 1.125em;
	font-weight: var(--font-weight-semibold);
	color: var(--neutral-ink-inverse);
}

.callout--peach {
	padding: var(--space-32) var(--space-48);
	background: var(--brand-peach-tint);
	text-align: center;
}

/* .callout p carries a 579px Figma measure that is far too narrow here. */
.callout--peach p {
	max-width: 900px;
	margin-inline: auto;
	color: var(--neutral-ink);
}

/* --- Accordion ---
   Built on <details>/<summary> so it opens and closes with no JavaScript and
   keeps native keyboard and screen-reader behaviour. The document sets these
   headings at H3, so the <h3> lives inside the <summary>, which the HTML spec
   allows. Measure is a custom property rather than a baked-in width. */
.accordion {
	display: flex;
	flex-direction: column;
	gap: var(--space-16);
	max-width: var(--accordion-measure, 1000px);
	margin: var(--space-32) 0 0;
	padding: 0;
	list-style: none;
}

.accordion__item {
	border-radius: var(--radius-12);
	background: var(--surface-default);
}

.accordion__summary {
	display: flex;
	gap: var(--space-20);
	align-items: center;
	padding: var(--space-20) var(--space-24);
	cursor: pointer;
	list-style: none;
}

/* Safari still paints its own disclosure triangle without this. */
.accordion__summary::-webkit-details-marker {
	display: none;
}

.accordion__summary:focus-visible {
	outline: 2px solid var(--brand-ocean-deep);
	outline-offset: 2px;
}

.accordion__num {
	display: flex;
	flex: none;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border-radius: var(--radius-pill);
	background: var(--brand-ocean);
	font-weight: var(--font-weight-bold, 700);
	font-size: var(--font-size-18);
	color: var(--surface-default);
}

.accordion__title {
	flex: 1 1 auto;
	margin: 0;
	font-size: var(--type-h3);
	line-height: 1.18;
	letter-spacing: -0.12px;
	color: var(--neutral-ink);
}

/* Drawn rather than an asset, so it can rotate on open without a second file. */
.accordion__chevron {
	flex: none;
	width: 12px;
	height: 12px;
	border-right: 2px solid var(--neutral-muted);
	border-bottom: 2px solid var(--neutral-muted);
	margin-top: -6px;
	transform: rotate(45deg);
	transition: transform 0.18s ease;
}

.accordion__item[open] .accordion__chevron {
	margin-top: 2px;
	transform: rotate(225deg);
}

.accordion__body {
	display: flex;
	flex-direction: column;
	gap: var(--space-20);
	padding: var(--space-20) var(--space-24) var(--space-32) 92px;
	border-top: var(--border-width) solid var(--neutral-border);
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

.accordion__body > p {
	margin: 0;
}

@media (max-width: 992px) {
	.split--aside {
		grid-template-columns: minmax(0, 1fr);
	}
}

@media (max-width: 768px) {
	/* The 92px indent exists to clear the number badge. On a phone that is a
	   quarter of the line, so the body returns to the card's own padding. */
	.accordion__body {
		padding-left: var(--space-24);
	}

	.callout--peach {
		padding: var(--space-24);
	}
}

/* ---------- 29. Body copy that needs more weight than muted ----------
   --neutral-muted is tuned for body copy on white or on the ocean tint. Over
   a photograph it drops below comfortable reading contrast even when the
   photo is pale. This is a near-black that still sits lighter than the
   headings' --neutral-ink, so the hierarchy between heading and body holds.

   An explicit modifier rather than a rule scoped to .section--layered: a
   layered section with a DARK photo needs .prose--inverse instead, and a
   blanket rule would get that backwards. */

:root {
	--neutral-ink-soft: #3d3d3d;
}

.prose--ink {
	color: var(--neutral-ink-soft);
}

/* ---------- 30. Case study cards ----------
   The Proof This Works card row. Generic: any page needing a photo card that
   links somewhere, with the title reversed out over the image. Added for
   Services; Case Studies will want the same component. */

:root {
	--scrim-black-75: rgba(0, 0, 0, 0.75);
}

/* Holds a card grid to the page's copy measure instead of the full container.
   Everything else in these sections runs to 1000px, and a row that overshoots
   it reads as a different page. */
.card-grid--measure {
	max-width: 1000px;
}

.case-card {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	/* The design's card proportion, not a fixed height - the card scales with
	   its column. */
	aspect-ratio: 210 / 260;
	padding: var(--space-16);
	overflow: hidden;
	border-radius: var(--radius-12);
	text-decoration: none;
}

.case-card__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.3s ease;
}

/* Transparent at the top, near-solid at the base, so the title holds against
   any photo without dimming the whole image. */
.case-card__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		to bottom,
		var(--shadow-black-0) 0%,
		var(--scrim-black-75) 100%
	);
	pointer-events: none;
}

.case-card__badge {
	position: relative;
	display: flex;
	flex: none;
	align-self: flex-end;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: var(--radius-pill);
	background: var(--neutral-ink-inverse);
}

.case-card__badge img {
	display: block;
	width: 14px;
	height: 14px;
}

.case-card__title {
	position: relative;
	margin: 0;
	font-family: var(--font-heading);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-20);
	line-height: 1.2;
	color: var(--neutral-ink-inverse);
}

.case-card:hover .case-card__img,
.case-card:focus-visible .case-card__img {
	transform: scale(1.04);
}

.case-card:focus-visible {
	outline: 2px solid var(--brand-ocean-deep);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.case-card__img {
		transition: none;
	}

	.case-card:hover .case-card__img,
	.case-card:focus-visible .case-card__img {
		transform: none;
	}
}

/* ---------- 31. Pull quote on a light section ----------
   About's .pull-quote is a heavy, section-carrying treatment: tinted panel,
   ocean rule, oversized glyph, all tuned for the dark band it sits in. The
   Services design uses the same idea far more quietly - Lora italic at ink
   weight on white, with nothing around it. So this variant strips the panel
   chrome rather than recolouring it.

   The quotation marks are CSS, not content. The locked document's copy has no
   quote marks and must not gain any; the design uses them as punctuation
   around the line, so they belong in the stylesheet where they stay out of
   the document text. */

.pull-quote--light {
	padding: 0;
	border-left: 0;
	border-radius: 0;
	background: none;
}

.pull-quote--light .pull-quote__text {
	line-height: 1.3;
	color: var(--neutral-ink);
}

.pull-quote--light .pull-quote__text::before {
	content: "\201C";
}

.pull-quote--light .pull-quote__text::after {
	content: "\201D";
}

/* ---------- 32. County hub ----------
   Added for the county pages. Generic; all four counties share it. */

/* --- Photo band that introduces a submarket ---
   Height comes from an aspect ratio rather than a fixed value, so it scales
   with the viewport. Below 768 the ratio would leave too little room for a
   two-line heading, so it reverts to padding-driven height. */
.section--band {
	position: relative;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	aspect-ratio: var(--band-ratio, 1200 / 420);
	padding-bottom: var(--space-48);
	overflow: hidden;
}

/* Transparent at the top so the photograph reads, near-solid at the base so
   the heading holds against any image. */
.section__scrim--bottom {
	background: linear-gradient(
		to bottom,
		var(--shadow-black-0) 0%,
		rgba(0, 0, 0, 0.15) 55%,
		rgba(0, 0, 0, 0.72) 100%
	);
}

/* The submarket sections are jump targets. The header is not fixed on this
   build, so this is breathing room rather than a correction - but it also
   means a sticky header later would not break the anchors. */
.section--band[id] {
	scroll-margin-top: var(--space-24);
}

/* --- Alternating icon-and-text list, for completed transactions --- */
.case-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-24);
	max-width: 1000px;
	margin: var(--space-32) 0 0;
	padding: 0;
	list-style: none;
}

.case-list__item {
	display: grid;
	grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
	gap: var(--space-24);
	align-items: center;
}

/* Every second entry flips, so the eye zigzags down the list. Both the order
   AND the track widths have to flip: moving the icon alone would drop the text
   card into the narrow 200px track and let the icon fill the wide one. */
.case-list__item:nth-child(even) {
	grid-template-columns: minmax(0, 1fr) minmax(0, 200px);
}

.case-list__item:nth-child(even) .case-list__icon {
	order: 2;
}

.case-list__icon img {
	display: block;
	width: 100%;
	height: auto;
}

.case-list__card {
	padding: var(--space-24);
	border-radius: var(--radius-12);
	background: var(--surface-default);
}

.case-list__card p {
	margin: 0;
	line-height: 1.4;
	letter-spacing: -0.32px;
	color: var(--neutral-muted);
}

.case-list__lead {
	font-weight: var(--font-weight-semibold);
	color: var(--neutral-ink);
}

@media (max-width: 768px) {
	.section--band {
		aspect-ratio: auto;
		padding-block: var(--space-96) var(--space-32);
	}

	/* Stacked, every entry is icon first then text - including the flipped
	   ones. Both selectors are needed: the even-row rule above is (0,2,0) and
	   would otherwise keep its two-track template inside this query. */
	.case-list__item,
	.case-list__item:nth-child(even) {
		grid-template-columns: minmax(0, 1fr);
		justify-items: start;
	}

	.case-list__item:nth-child(even) .case-list__icon {
		order: 0;
	}

	.case-list__icon img {
		max-width: 160px;
	}
}

/* ---------- 33. Content measure ----------
   Full width is the default and the reading measure is the exception, not the
   other way round. The base classes still carry their caps - .section__title at
   900px, .prose--left-wide at 1000px and so on - because About Us, Services and
   the homepage were designed against them. Everywhere else those caps are
   released here.

   Written as :not() rather than by re-declaring every measure, so the pages that
   want the reading measure keep the exact values their base classes already set.
   Nothing has to be kept in sync, and a new page is full width without anyone
   remembering to make it so - which is what kept going wrong when this was an
   opt-in .section--full on every individual section. */

.site-main:not(.site-main--measure) .prose,
.site-main:not(.site-main--measure) .section__title,
.site-main:not(.site-main--measure) .section__subtitle,
.site-main:not(.site-main--measure) .objection-list,
.site-main:not(.site-main--measure) .case-list,
.site-main:not(.site-main--measure) .card-grid,
.site-main:not(.site-main--measure) .accordion,
.site-main:not(.site-main--measure) .split__body > p {
	max-width: none;
}

/* --- Eyebrow alignment and colour ---
   .section__eyebrow hardcodes centre alignment and a muted colour, which suits
   a centred light section and nothing else. These are the two variants the
   photo bands need. */
.section__eyebrow--left {
	text-align: left;
}

.section__eyebrow--inverse {
	color: var(--neutral-ink-inverse);
}

/* ---------- 34. Submarket run: sticky sub-navigation ----------
   The county pages run ten near-identical submarket blocks - about two thirds
   of the page, roughly a screen and a half each. The card grid jumps into that
   run but offers no way across or back out of it. This is the way across.

   The nav is sticky inside .submarket-run, so it pins when the run starts and
   releases when the run ends - no JavaScript is involved in showing or hiding
   it. JavaScript only marks which submarket you are currently in. */

.submarket-run {
	position: relative;
}

.submarket-nav {
	position: sticky;
	top: 0;
	z-index: 20;
	background: var(--brand-ocean-dark);
	border-bottom: var(--border-width) solid var(--scrim-white-12);
}

.submarket-nav__list {
	display: flex;
	gap: var(--space-8);
	margin: 0;
	padding: var(--space-10) 0;
	overflow-x: auto;
	list-style: none;
	/* The strip scrolls sideways on narrow screens; the bar itself stays thin. */
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.submarket-nav__list::-webkit-scrollbar {
	display: none;
}

.submarket-nav__link {
	display: block;
	padding: 6px var(--space-12);
	border-radius: var(--radius-pill);
	font-weight: var(--font-weight-semibold);
	font-size: var(--font-size-16, 16px);
	line-height: 1.3;
	color: var(--neutral-muted-inverse);
	white-space: nowrap;
	text-decoration: none;
	transition: background 0.15s ease, color 0.15s ease;
}

.submarket-nav__link:hover,
.submarket-nav__link:focus-visible {
	background: var(--scrim-white-12);
	color: var(--neutral-ink-inverse);
}

/* Set by script on the submarket currently filling most of the viewport. */
.submarket-nav__link.is-current {
	background: var(--brand-ocean);
	color: var(--neutral-ink-inverse);
}

/* The anchors now land under a pinned bar, so the offset is load-bearing
   rather than cosmetic. */
.section--band[id] {
	scroll-margin-top: calc(var(--subnav-height, 56px) + var(--space-16));
}

/* Way back out of the run, at the end of every submarket. */
.section__backlink {
	margin: var(--space-24) 0 0;
	text-align: center;
	font-size: var(--font-size-16, 16px);
}

/* --- Room for a background photograph to be seen ---
   Extra space below the content so a section's background image reads as an
   image rather than a texture behind text. */
.section--bg-room {
	padding-bottom: var(--bg-room, 300px);
}

@media (max-width: 992px) {
	.section--bg-room {
		padding-bottom: 200px;
	}
}

@media (max-width: 768px) {
	.submarket-nav__list {
		padding: var(--space-8) 0;
	}

	.section--bg-room {
		padding-bottom: 140px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.submarket-nav__link {
		transition: none;
	}
}

/* ---------- 35. Awaiting photography ----------
   Temporary. A county whose photographs have not been uploaded yet still has to
   be reviewable, and both of these slots reverse their text out over an image -
   with no image and no background they would render as white on white. Falling
   back to the brand's dark field keeps the section legible and makes the gap
   obvious rather than hiding it. Delete once every county has its imagery. */

.case-card--awaiting-image,
.section--awaiting-image {
	background: var(--brand-ocean-dark);
}

/* ---------- 36. Forms ----------
   The site's form pattern, not a Contact-page one-off. Three independent
   pieces: .form-card is the raised white panel, .form and its parts are the
   fields themselves, and .split--even is the two-column layout it sits in. A form
   can run directly on a section background without the card, and the card can
   hold something other than a form. Nothing here names a page. */

.form {
	/* One knob. The control height drives the dropdown arrow's position, so
	   they cannot drift apart. */
	--control-height: 48px;
}

.form-card {
	padding: var(--space-40);
	border-radius: var(--radius-12);
	background: var(--surface-default);
	box-shadow: 0 18px 40px -12px var(--shadow-black-16);
}

.form-card__title {
	margin: 0 0 var(--space-12);
	font-family: var(--font-heading);
	font-size: var(--type-h3);
	line-height: 1.2;
	color: var(--neutral-ink);
}

.form-card__lede {
	margin: 0 0 var(--space-32);
	font-size: var(--font-size-16);
	line-height: 1.5;
	color: var(--neutral-muted);
}

/* Two fields to a row; a field that needs the full width says so itself. */
.form__grid {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: var(--space-20);
}

.form__field {
	display: flex;
	flex-direction: column;
	gap: var(--space-8);
	min-width: 0;
}

.form__field--full {
	grid-column: 1 / -1;
}

/* Always a real label, always above its control. */
.form__label {
	font-size: var(--font-size-15);
	font-weight: var(--font-weight-semibold);
	line-height: 1.3;
	color: var(--neutral-ink);
}

/* One control style for every input, select and textarea, so a new field type
   inherits the look instead of needing its own rule. */
.form__control {
	width: 100%;
	min-height: var(--control-height);
	padding: var(--space-12) var(--space-16);
	border: var(--border-width) solid var(--neutral-border);
	border-radius: var(--radius);
	background: var(--surface-default);
	font-family: var(--font-body);
	font-size: var(--font-size-16);
	line-height: 1.4;
	color: var(--neutral-ink);
	/* Strip the platform's own control chrome so all three types match. */
	appearance: none;
}

.form__control::placeholder {
	/* Firefox dims placeholders by default; hold them at the muted token. */
	color: var(--neutral-muted);
	opacity: 1;
}

.form__control:hover {
	border-color: var(--brand-ocean);
}

.form__control:focus-visible {
	outline: 2px solid var(--brand-ocean-deep);
	outline-offset: 2px;
	border-color: var(--brand-ocean-deep);
}

.form__control--textarea {
	min-height: 132px;
	resize: vertical;
}

/* appearance:none removed the native dropdown arrow, so the field draws one.
   Built from borders rather than a background image, so it takes the token
   colour instead of hardcoding a hex inside a data URI. Anchored to the
   bottom of the field, which keeps it centred on the control even if a label
   wraps to two lines. */
.form__field--select {
	position: relative;
}

.form__field--select::after {
	content: "";
	position: absolute;
	right: var(--space-16);
	bottom: calc(var(--control-height) / 2);
	width: 8px;
	height: 8px;
	border-right: 2px solid var(--neutral-muted);
	border-bottom: 2px solid var(--neutral-muted);
	transform: translateY(50%) rotate(45deg);
	pointer-events: none;
}

.form__field--select .form__control {
	padding-right: var(--space-40);
}

.form__actions {
	display: flex;
	justify-content: center;
	margin-top: var(--space-32);
}

/* .cta-button is authored as a link. Used as a form control it also has to
   shed the button element's own chrome, and it needs its own focus ring -
   the link version gets one from the anchor. */
button.cta-button {
	border: 0;
	font-family: var(--font-body);
	cursor: pointer;
}

button.cta-button:focus-visible {
	outline: 2px solid var(--brand-ocean-deep);
	outline-offset: 3px;
}

/* ---------- 36a. Form states ----------
Everything the form only shows once it has been submitted: the required marker,
the honeypot, per-field errors, the notice above the form, the consent line and
the confirmation that replaces the form. Part of the form pattern, not of the
Contact page - nothing here names a page. */

/* The required marker. aria-hidden where it is printed: the control carries
   aria-required, so a screen reader states the requirement rather than reading
   out a piece of punctuation. */
.form__required {
	margin-left: 2px;
	color: var(--state-error);
}

/* The honeypot. Deliberately off-screen rather than display:none or
   hidden - a bot that skips genuinely hidden inputs is the bot this is meant
   to catch. Kept out of the tab order and the accessibility tree in the
   markup, so no visitor can reach it by keyboard or hear it announced. */
.form__pot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* An invalid field states it in colour and in text. The border alone would be
   the only signal for anyone who cannot separate the two reds from the border
   token, which is why .form__error always prints as well. */
.form__field--invalid .form__control {
	border-color: var(--state-error);
}

.form__field--invalid .form__control:focus-visible {
	outline-color: var(--state-error);
	border-color: var(--state-error);
}

.form__error {
	margin: 0;
	font-size: var(--font-size-14);
	line-height: 1.4;
	color: var(--state-error);
}

/* Whatever is wrong with the submission as a whole rather than with one
   field. Sits above the form so it is read before the fields are re-read. */
.form-notice {
	margin: 0 0 var(--space-24);
	padding: var(--space-12) var(--space-16);
	border-left: 3px solid transparent;
	border-radius: var(--radius);
	font-size: var(--font-size-15);
	line-height: 1.5;
}

.form-notice--error {
	border-left-color: var(--state-error);
	background: var(--state-error-tint);
	color: var(--neutral-ink);
}

/* The card sits on white, so the site-wide paragraph link colour would read
   as an ordinary link inside a red notice. */
.form-card .form-notice a {
	color: var(--state-error);
	font-weight: var(--font-weight-semibold);
}

/* Quiet on purpose. It is a disclosure, not a selling point, and it must not
   compete with the button immediately above it. */
.form__consent {
	margin: var(--space-16) 0 0;
	font-size: var(--font-size-13);
	line-height: 1.5;
	color: var(--neutral-muted);
	text-align: center;
}

/* The confirmation, which replaces the form rather than sitting above a
   cleared one - an empty form beside a thank you reads as an invitation to
   send it twice. */
.form-sent {
	display: flex;
	flex-direction: column;
	gap: var(--space-16);
	padding-left: var(--space-20);
	border-left: 3px solid var(--state-success);
}

/* Card scale, matching .form-card__lede. The page's .prose is tuned for a
   section's body size and would set this two steps too large inside a card. */
.form-sent p {
	margin: 0;
	font-size: var(--font-size-16);
	line-height: 1.5;
	color: var(--neutral-muted);
}

.form-sent .form-card__title {
	margin: 0;
}

/* The confirmation heading takes focus on load so a screen reader announces
   it instead of starting silently at the top of the page. It carries
   tabindex="-1", so it is not in the tab order and nobody can arrive here by
   tabbing - the browser's focus ring would draw a box round a heading that
   cannot be tabbed to, and change how the confirmation looks. Same reasoning
   as .site-main:focus, which is the skip link's target. */
.form-sent .form-card__title:focus {
	outline: none;
}

.form-sent__aside {
	font-size: var(--font-size-15);
}

/* Two equal columns, aligned to the top. .split is 1.35fr/1fr and centres,
   which floats the shorter column against the taller one - wrong wherever the
   two sides are independent blocks rather than copy beside a picture. Used for
   copy beside a form, and for two short blocks sharing a band. */
.split--even {
	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
	align-items: start;
}

.split__col {
	min-width: 0;
}

/* A short stack of contact details. Used for both the phone/email pair and
   the postal address, so the two read as one treatment. */
.contact-list,
.contact-address {
	display: flex;
	flex-direction: column;
	gap: var(--space-8);
	margin: 0;
	padding: 0;
	list-style: none;
	font-style: normal;
	line-height: 1.5;
}

.contact-list a,
.contact-address a {
	color: var(--brand-ocean-deep);
	text-decoration-color: var(--brand-ocean);
	text-underline-offset: 3px;
}

.contact-list a:hover,
.contact-list a:focus-visible,
.contact-address a:hover,
.contact-address a:focus-visible {
	color: var(--brand-ocean-dark);
	text-decoration-color: currentColor;
}

@media (max-width: 992px) {
	/* Second column drops below the first rather than beside it. */
	.split--even {
		grid-template-columns: minmax(0, 1fr);
	}

	.form-card {
		padding: var(--space-32);
	}
}

@media (max-width: 768px) {
	/* Paired fields unstack - two inputs to a phone row is too tight. */
	.form__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.form-card {
		padding: var(--space-24);
	}
}


/* ---------- 37. Contact: the follow-up block, placed by width ----------
   "What Happens Next" appears once in the markup, in the document's own source
   order - after the form. Below 992 the single column reads in that order and
   needs no rules at all. On desktop, grid placement lifts it into the left
   column under the intro while the form holds column two across both rows.
   Placement only: nothing is duplicated, nothing is display:none. */

@media (min-width: 993px) {
	.contact-top .split--even {
		/* Row one is the intro's own height. Row two takes whatever the taller
		   form leaves over, and the block inside it stays pinned to the top of
		   that row - so it sits directly under the intro rather than drifting
		   down as the form grows. */
		grid-template-rows: auto auto 1fr;
	}

	.contact-top__copy {
		grid-column: 1;
		grid-row: 1;
	}

	.contact-top .form-card {
		grid-column: 2;
		grid-row: 1 / span 3;
	}

	.contact-top__next {
		grid-column: 1;
		grid-row: 2;
		align-self: start;
	}

	.contact-top__works {
		grid-column: 1;
		grid-row: 3;
		align-self: start;
	}
}

/* ---------- 38. A district heading inside a submarket ----------
   .section__subtitle--left zeroes the top margin, which is right when the
   heading opens a section but wrong when several of them run down one, as the
   City of San Diego's five districts do. This restores the space above so the
   districts read as separate blocks, and drops the centred variant's measure
   cap so the heading follows the full-width county measure. */

.section__subtitle--sub {
	max-width: none;
	margin-top: var(--space-48);
}

/* ---------- 39. Article list ----------
   The posts index. Nothing is published yet, so this is written against the
   markup rather than against content: a stacked list of entries, each with its
   date, linked title, excerpt and a way in. Generic - a category or author
   archive would use exactly this. */

.article-list {
	display: flex;
	flex-direction: column;
	gap: var(--space-40);
	margin: var(--space-40) 0 0;
	padding: 0;
	list-style: none;
}

.article-card {
	padding-bottom: var(--space-40);
	border-bottom: var(--border-width) solid var(--neutral-border);
}

.article-card:last-child {
	padding-bottom: 0;
	border-bottom: 0;
}

.article-card__meta {
	margin: 0 0 var(--space-8);
	font-size: var(--font-size-15);
	letter-spacing: 1.04px;
	text-transform: uppercase;
	color: var(--neutral-muted);
}

.article-card__title {
	margin: 0 0 var(--space-12);
	font-family: var(--font-heading);
	font-size: var(--type-h3);
	line-height: 1.2;
	color: var(--neutral-ink);
}

.article-card__title a {
	color: inherit;
	text-decoration: none;
}

.article-card__title a:hover,
.article-card__title a:focus-visible {
	color: var(--brand-ocean-deep);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.article-card__excerpt {
	margin: 0 0 var(--space-12);
	line-height: 1.5;
	color: var(--neutral-muted);
}

.article-card__more {
	margin: 0;
}

.article-card__more a,
.article-card__title a:focus-visible {
	color: var(--brand-ocean-deep);
}

.article-card__more a {
	text-decoration-color: var(--brand-ocean);
	text-underline-offset: 3px;
}

/* Pagination only appears once there are enough posts to need it. */
.pagination {
	margin-top: var(--space-48);
}

.pagination .nav-links {
	display: flex;
	flex-wrap: wrap;
	gap: var(--space-12);
	align-items: center;
}

.pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 44px;
	min-height: 44px;
	padding: 0 var(--space-12);
	border: var(--border-width) solid var(--neutral-border);
	border-radius: var(--radius);
	color: var(--brand-ocean-deep);
	text-decoration: none;
}

.pagination .page-numbers.current {
	background: var(--brand-ocean);
	border-color: var(--brand-ocean);
	color: var(--neutral-ink-inverse);
}

.pagination .page-numbers:focus-visible {
	outline: 2px solid var(--brand-ocean-deep);
	outline-offset: 2px;
}

/* ---------- 40. FAQs ----------
   The page is assembled from existing parts; these are the two things it needs
   that nothing else did. */

/* The jump row sits under the intro rather than between sections, so it needs
   its own space above. */
.faq-jump {
	margin-top: var(--space-32);
}

/* Licence numbers are three separate records, not a sentence. */
.faq-licence {
	display: block;
}

/* ---------- 41. Feed cards ----------
   The Articles feed. Same card as a case study - proportion, radius, badge,
   reversed-out title - with a flat colour where the photograph goes, so a feed
   reads as a feed without needing artwork for every post. The three colours
   cycle, so any number of posts stays on pattern. */

/* --- Submarket tiles ---
   The county grid of city cards. It shares .case-card with the Services and
   Articles cards, so everything here is scoped to the modifier and neither of
   those pages is touched.

   Two differences from the shared card:

   Height. The shared card is 210/260, which is the exact proportion of these
   photographs - nothing was being cropped. A quarter off that is 210/195, and
   the crop that introduces is the reason for the object-position below.

   Scrim. The shared scrim ramps from transparent at the very top to 75% black
   at the bottom, which is a quarter black across the middle of the card and
   left several of these city photographs unreadable. Holding it clear to 55%
   and ramping over the bottom 45% keeps the picture visible in the upper two
   thirds while still putting real darkness behind the label. */
.case-card--submarket {
	aspect-ratio: 210 / 195;
}

/* Cover now has 25% of the photograph's height to lose. Centred would take
   half of it off the top, where the rooflines are. 30% takes less than a third
   from the top and the rest off the foreground. */
.case-card--submarket .case-card__img {
	object-position: center 30%;
}

.case-card--submarket .case-card__scrim {
	background: linear-gradient(
		to bottom,
		var(--shadow-black-0) 0%,
		var(--shadow-black-0) 55%,
		var(--scrim-black-75) 100%
	);
}

.case-card--flat {
	background: var(--feed-card-bg, var(--brand-ocean));
}

.case-card--ocean { --feed-card-bg: var(--brand-ocean); }
.case-card--coral { --feed-card-bg: var(--gradient-stop-coral); }
.case-card--sage  { --feed-card-bg: var(--brand-sage); }

/* With no badge above it the title has nothing to be spaced apart from, so it
   is pushed down rather than centred. */
.case-card--flat .case-card__title {
	margin-top: auto;
}

/* Upcoming topics are not articles yet: no link, so no badge and no hover. */
.case-card--upcoming {
	cursor: default;
}

/* ---------- 42. Back to top ----------
   Fixed bottom right on every page. Hidden until there is enough page behind
   you to make it worth offering, which script decides - so with no JavaScript
   it simply never appears rather than sitting there uselessly at the top of a
   short page.

   Deliberately quiet, and deliberately not a coloured circle: a filled round
   button in this corner reads as a chat widget, which is the one thing it must
   not be mistaken for. Near-white, squared off, a hairline border to hold its
   edge on a white section, and the mark itself doing the work. */

.to-top {
	position: fixed;
	right: var(--space-24);
	bottom: var(--space-24);
	z-index: 25;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border: var(--border-width) solid var(--neutral-border);
	border-radius: var(--radius);
	background: var(--scrim-white-90);
	box-shadow: 0 2px 8px -2px var(--shadow-black-10);
	color: var(--neutral-ink);
	text-decoration: none;

	/* Out of the way and inert until it is wanted. */
	opacity: 0;
	visibility: hidden;
	transform: translateY(8px);
	transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s, background-color 0.2s ease;
}

.to-top.is-visible {
	opacity: 1;
	visibility: visible;
	transform: none;
}

.to-top:hover {
	background: var(--surface-default);
	border-color: var(--brand-ocean);
	color: var(--brand-ocean-deep);
}

.to-top:focus-visible {
	outline: 2px solid var(--brand-ocean-deep);
	outline-offset: 3px;
}

/* Drawn from borders rather than shipped as a file, like the other chevrons. */
.to-top__icon {
	width: 10px;
	height: 10px;
	margin-top: 3px;
	border-top: 2px solid currentColor;
	border-left: 2px solid currentColor;
	transform: rotate(45deg);
}

@media (max-width: 768px) {
	.to-top {
		right: var(--space-16);
		bottom: var(--space-16);
		width: 44px;
		height: 44px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.to-top {
		transition: opacity 0.2s ease, visibility 0.2s;
		transform: none;
	}
}
