/* ==========================================================================
   Jason Sims, REALTOR®
   Decatur, GA — Keller Williams Realty Metro Atlanta

   The world, in one paragraph: a warm white ground, deep navy used at page
   scale for anchoring bands, and brass reserved for rules, numerals and the
   surname — never for body text, because #9E7A41 measures 3.95:1 on white and
   cannot legally carry copy. Type is a chiselled editorial serif over an
   American gothic sans; the pairing is meant to read as brass hardware and
   engraved building numbers rather than as a real-estate template.

   Palette is Jason's own, from his 2026-08-04 brief. Measured contrast on
   white: Navy 15.1:1, Ink Slate 9.6:1, Deep Teal 7.3:1, Brass 3.95:1.
   Brass Light on Navy is 6.15:1, which is why it, not Brass, carries small
   text inside dark bands.
   ========================================================================== */

:root {
	--navy: #16273D;
	--navy-deep: #0E1B2C;
	--brass: #9E7A41;
	--brass-light: #C2A06A;
	/* Brass at its brand value measures 3.95:1 on white. That clears the 3:1 bar
	   for large display type but FAILS the 4.5:1 body bar, so any small text or
	   button label on a light ground uses this deeper shade (5.05:1) instead.
	   Same hue family, indistinguishable at 12px, and legible. */
	--brass-deep: #8A6935;
	--teal: #0E5E76;
	--ink: #34465E;
	--ink-soft: #5A6B82;
	--white: #FFFFFF;
	--paper: #F7F5F1;
	--hairline: #DFD9D0;

	--font-display: Spectral, Georgia, "Times New Roman", serif;
	--font-body: "Libre Franklin", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

	/* One spacing rhythm for the whole site. */
	--s1: 0.5rem;
	--s2: 1rem;
	--s3: 1.75rem;
	--s4: 3rem;
	--s5: 5rem;
	--s6: 7.5rem;

	--measure: 68ch;
	--gutter: clamp(1.25rem, 4vw, 3.5rem);
	--content: 68rem;
	--wide: 84rem;

	--ease: cubic-bezier(0.16, 1, 0.3, 1);
	--header-h: 76px;
}

/* --------------------------------------------------------------- reset -- */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

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

body {
	margin: 0;
	background: var(--white);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: 1.0625rem;
	line-height: 1.65;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

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

h1, h2, h3, h4 {
	font-family: var(--font-display);
	font-weight: 500;
	line-height: 1.12;
	color: var(--navy);
	margin: 0 0 var(--s2);
	text-wrap: balance;
	letter-spacing: -0.012em;
}

h1 { font-size: clamp(2.5rem, 5.5vw + 0.5rem, 5rem); }
h2 { font-size: clamp(1.875rem, 3vw + 0.75rem, 3rem); }
h3 { font-size: clamp(1.25rem, 1.2vw + 0.9rem, 1.625rem); }
h4 { font-size: 1.125rem; }

p { margin: 0 0 var(--s2); max-width: var(--measure); }

a { color: var(--teal); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--navy); }

:focus-visible {
	outline: 2px solid var(--teal);
	outline-offset: 3px;
	border-radius: 2px;
}

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

.skip-link {
	position: absolute; left: -9999px; top: 0; z-index: 999;
	background: var(--navy); color: #fff; padding: var(--s2) var(--s3);
}
.skip-link:focus { left: 0; }

/* -------------------------------------------------------------- layout -- */

.wrap { width: min(100% - (var(--gutter) * 2), var(--content)); margin-inline: auto; }
.wrap--wide { width: min(100% - (var(--gutter) * 2), var(--wide)); margin-inline: auto; }

.section { padding-block: clamp(3.5rem, 8vw, var(--s6)); }
.section--tight { padding-block: clamp(2.5rem, 5vw, var(--s5)); }
.section--paper { background: var(--paper); }
.section--navy { background: var(--navy); color: #DCE3EC; }
.section--navy h2, .section--navy h3 { color: #fff; }

/* More space above a heading than below it. */
.section > * + h2 { margin-top: var(--s4); }

.rule {
	width: 64px; height: 0;
	border: 0; border-top: 2px solid var(--brass);
	margin: var(--s3) 0;
}
.rule--center { margin-inline: auto; }

/* ------------------------------------------------------------- buttons -- */

.btn {
	display: inline-flex; align-items: center; justify-content: center;
	gap: 0.5em;
	font-family: var(--font-body);
	font-size: 0.8125rem;
	font-weight: 600;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	text-decoration: none;
	padding: 1.05em 1.9em;
	border: 1px solid var(--navy);
	border-radius: 2px;
	background: var(--navy);
	color: #fff;
	cursor: pointer;
	transition: background 0.35s var(--ease), color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.btn:hover { background: var(--navy-deep); border-color: var(--navy-deep); color: #fff; }

.btn--ghost { background: transparent; color: var(--navy); }
.btn--ghost:hover { background: var(--navy); color: #fff; }

.btn--brass { background: var(--brass-deep); border-color: var(--brass-deep); color: #fff; }
.btn--brass:hover { background: #6F5429; border-color: #6F5429; }

.btn--onDark { background: transparent; border-color: rgba(255,255,255,0.5); color: #fff; }
.btn--onDark:hover { background: #fff; border-color: #fff; color: var(--navy); }

/* -------------------------------------------------------------- header -- */

.site-header {
	position: fixed; inset: 0 0 auto 0; z-index: 100;
	display: flex; align-items: center;
	height: var(--header-h);
	transition: background 0.4s var(--ease), box-shadow 0.4s var(--ease), border-color 0.4s var(--ease);
	border-bottom: 1px solid transparent;
}

/* Over the homepage hero the bar is glass on a dark photograph. Everywhere
   else, and once scrolled, it is solid white so the navy nav stays legible. */
/* A short gradient under the overlay bar. Without it the nav sits on whatever
   the top of the photograph happens to be — on the Decatur hero that is bright
   sky, and white 12px type over it fails contrast outright. */
.site-header--overlay {
	background: linear-gradient(to bottom, rgba(9,18,30,0.55), rgba(9,18,30,0));
	height: auto;
	min-height: var(--header-h);
	padding-bottom: var(--s2);
}
.site-header--overlay .site-header__inner { color: #fff; }
.site-header--overlay .nav__list a,
.site-header--overlay .wordmark { color: #fff; }
.site-header--overlay .nav__list a::after { background: var(--brass-light); }

.site-header--solid,
.site-header.is-stuck {
	background: rgba(255,255,255,0.96);
	backdrop-filter: saturate(1.6) blur(10px);
	border-bottom-color: var(--hairline);
	height: var(--header-h);
	min-height: 0;
	padding-bottom: 0;
}

/*
	The bar is fixed, so the first section of every inner page would otherwise
	start underneath it. Clearance is added to that first section's own top
	padding rather than to #main, because a hero section is full-bleed and
	padding on #main would open a white strip above its photograph.

	:not(.hero) because hero sections already clear the bar from the inside —
	they need the image to run under it, not start below it.
*/
.site-header--solid + #main > :first-child:not(.hero) {
	padding-top: calc(var(--header-h) + clamp(2rem, 4vw, 3.5rem));
}
.site-header.is-stuck .nav__list a,
.site-header.is-stuck .wordmark,
.site-header--solid .nav__list a,
.site-header--solid .wordmark { color: var(--navy); }

.site-header__inner {
	width: min(100% - (var(--gutter) * 2), var(--wide));
	margin-inline: auto;
	display: flex; align-items: center; gap: var(--s3);
}

.wordmark {
	font-family: var(--font-display);
	font-size: 1.3125rem;
	font-weight: 500;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	color: var(--navy);
	text-decoration: none;
	white-space: nowrap;
	transition: color 0.4s var(--ease);
}
.wordmark img { max-height: 44px; width: auto; }

/* The surname takes the brass, per the brief's note that brass carries "the
   surname in the lockup". */
.wordmark__last { color: var(--brass); }
.site-header--overlay:not(.is-stuck) .wordmark__last { color: var(--brass-light); }

/* The nav is itself a flex row: the menu list and the booking button are
   siblings, and without this the button wraps onto a second line and lands on
   top of the hero. */
.nav { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }
.nav__list { display: flex; align-items: center; gap: clamp(0.7rem, 1.1vw, 1.35rem); list-style: none; margin: 0; padding: 0; }
.nav__list a {
	position: relative;
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--navy);
	padding-block: 0.4em;
	white-space: nowrap;
	transition: color 0.3s var(--ease);
}
.nav__list a::after {
	content: ""; position: absolute; left: 0; bottom: 0;
	width: 100%; height: 1px; background: var(--brass);
	transform: scaleX(0); transform-origin: left;
	transition: transform 0.4s var(--ease);
}
.nav__list a:hover::after,
.nav__list .current-menu-item > a::after { transform: scaleX(1); }

/* Estate Sales is a second front door for a different audience, so it is set
   apart in the bar rather than sitting in the run of consumer pages. */
.nav__list .menu-item-estate > a {
	padding-inline: 0.9em;
	border-left: 1px solid var(--hairline);
	border-right: 1px solid var(--hairline);
	color: var(--teal);
}
.site-header--overlay:not(.is-stuck) .menu-item-estate > a {
	color: #fff;
	border-color: rgba(255,255,255,0.35);
}

/* Nine top-level items plus a button do not fit beside the wordmark until
   about 1300px. Below that the button steps out of the bar — Contact is
   already in the menu, so nothing is lost — and returns in the mobile panel. */
.nav__cta { display: none; }
@media (min-width: 1300px) {
	.nav__cta { display: inline-flex; }
}

.nav-toggle {
	display: none;
	margin-left: auto;
	background: none; border: 1px solid currentColor; border-radius: 2px;
	color: inherit; padding: 0.6em 0.8em; cursor: pointer;
}
.nav-toggle__bars { display: block; width: 20px; height: 2px; background: currentColor; position: relative; }
.nav-toggle__bars::before, .nav-toggle__bars::after {
	content: ""; position: absolute; left: 0; width: 20px; height: 2px; background: currentColor;
}
.nav-toggle__bars::before { top: -6px; }
.nav-toggle__bars::after { top: 6px; }

/* ---------------------------------------------------------------- hero -- */

.hero {
	position: relative;
	min-height: min(94svh, 900px);
	display: grid;
	align-items: center;
	isolation: isolate;
	background: var(--navy);
}

.hero__media { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero__media img, .hero__media video {
	width: 100%; height: 100%; object-fit: cover;
}

/*
	Inner-page header bands are far wider than they are tall — around 2.7:1 at
	desktop against a 16:9 source — so `cover` throws away the top and bottom of
	the frame. Centred, that decapitates anyone photographed standing up, which
	is exactly what it did to Jason on the About page.

	Anchoring to the top keeps the subject's head in frame. Landscape scenery
	loses a little foreground, which costs nothing.
*/
.hero--band .hero__media img { object-position: center top; }

/*
	The scrim. Two layers, not one: a flat navy wash for overall contrast plus
	a bottom-weighted gradient so the action bar has something solid to sit on
	while the top of the frame stays open. A single flat overlay dark enough for
	the caption would kill the photograph.
*/
.hero__scrim {
	position: absolute; inset: 0; z-index: -1;
	background:
		linear-gradient(to top, rgba(9,18,30,0.88) 0%, rgba(9,18,30,0.28) 46%, rgba(9,18,30,0.66) 100%),
		rgba(22,39,61,0.34);
}

/*
	A lighter scrim for footage that is already dark.
	The values above were tuned against the bright, midday Decatur Square
	footage. Laid over a golden-hour street they crushed the porches and
	rooflines into silhouette, which defeats the point of a residential hero —
	you cannot sell a neighbourhood the visitor cannot see.
	The flat wash comes off entirely and the gradient is pulled back; the
	headline keeps its legibility from a slightly stronger shadow instead,
	because the sun flare sits directly behind it and no amount of even scrim
	fixes a bright spot under white type.
*/
.hero--dusk .hero__scrim {
	background:
		/* A soft pool behind the text block only. The sun flare sits directly
		   under the subheading, and white type on a blown highlight fails
		   contrast no matter how even the overall scrim is. Darkening locally
		   fixes the type without pushing the houses back into silhouette. */
		radial-gradient(ellipse 58% 42% at 50% 40%, rgba(9,18,30,0.62) 0%, rgba(9,18,30,0.28) 55%, transparent 78%),
		linear-gradient(to top, rgba(9,18,30,0.86) 0%, rgba(9,18,30,0.16) 52%, rgba(9,18,30,0.55) 100%),
		rgba(22,39,61,0.10);
}
.hero--dusk .hero__title { text-shadow: 0 2px 12px rgba(9,18,30,0.72), 0 0 46px rgba(9,18,30,0.5); }
.hero--dusk .hero__sub { text-shadow: 0 1px 5px rgba(9,18,30,0.8); }

.hero__inner {
	width: min(100% - (var(--gutter) * 2), var(--wide));
	margin-inline: auto;
	padding-top: var(--header-h);
	padding-bottom: clamp(9rem, 16vw, 12rem);
	text-align: center;
	color: #fff;
}

.hero__title {
	color: #fff;
	font-size: clamp(2.75rem, 7vw, 5.5rem);
	font-weight: 400;
	line-height: 1.04;
	margin: 0 auto var(--s3);
	max-width: 15ch;
	text-shadow: 0 2px 18px rgba(9,18,30,0.38);
}

.hero__sub {
	font-size: clamp(0.95rem, 0.6vw + 0.8rem, 1.1875rem);
	color: #EAE4DA;
	max-width: 46ch;
	margin: 0 auto;
	/* A tight shadow, not a wide one. At 14px blur the halo reads as a dirty
	   grey plate behind the line rather than as contrast. */
	text-shadow: 0 1px 3px rgba(9,18,30,0.55);
}

.hero__rule {
	width: 76px; border: 0; border-top: 2px solid var(--brass-light);
	margin: 0 auto var(--s3);
}

/*
	Action bar. Jason's brief names three homepage CTAs; this is them. It is
	deliberately NOT a property-search box — the IDX feed is a separate paid
	licence in his name and is not connected yet, and a search field that
	returns nothing is worse than no search field.
*/
.hero__actions {
	position: absolute; left: 50%; bottom: 0;
	transform: translate(-50%, 45%);
	width: min(100% - (var(--gutter) * 2), 60rem);
	display: grid; grid-template-columns: repeat(3, 1fr);
	background: #fff;
	border: 1px solid var(--hairline);
	box-shadow: 0 24px 60px -28px rgba(14,27,44,0.42);
	z-index: 3;
}

.hero__action {
	display: flex; flex-direction: column; gap: 0.35rem;
	padding: clamp(1.15rem, 2vw, 1.75rem) clamp(1rem, 2vw, 1.9rem);
	text-decoration: none;
	border-right: 1px solid var(--hairline);
	transition: background 0.35s var(--ease);
}
.hero__action:last-child { border-right: 0; }
.hero__action:hover { background: var(--paper); }

.hero__action-label {
	font-family: var(--font-display);
	font-size: 1.125rem;
	color: var(--navy);
	line-height: 1.2;
}
.hero__action-note {
	font-size: 0.75rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--ink-soft);
}
.hero__action-arrow {
	color: var(--brass);
	transition: transform 0.35s var(--ease);
	display: inline-block;
}
.hero__action:hover .hero__action-arrow { transform: translateX(4px); }

/* The hero sits above a band of white so the floating bar has a ground. */
.hero + * { padding-top: clamp(6rem, 11vw, 8.5rem); }

/* --------------------------------------------------------------- split -- */

.split {
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: center;
	gap: clamp(2rem, 5vw, var(--s5));
}
.split--reverse .split__media { order: 2; }
.split__media img, .split__media video { width: 100%; }
.split__body { max-width: 34rem; }

.split__figure { position: relative; }
/* A brass corner rule, drawn only where the photograph meets white space. It
   is the same gesture as the rules elsewhere, at architectural scale. */
.split__figure::before {
	content: "";
	position: absolute; left: -14px; bottom: -14px;
	width: 46%; height: 46%;
	border-left: 2px solid var(--brass);
	border-bottom: 2px solid var(--brass);
	pointer-events: none;
}

/* ------------------------------------------------- neighborhood explorer -- */

.jsmap {
	display: grid;
	grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
	gap: clamp(1.5rem, 4vw, var(--s4));
	align-items: start;
}

/* The detail panel is taller than the map. Centring the map in its cell stops
   a column of dead space opening underneath it. */
.jsmap__stage { position: relative; align-self: center; }

.jsmap__svg { width: 100%; height: auto; overflow: visible; }

.jsmap__land {
	fill: var(--navy);
	stroke: var(--white);
	stroke-width: 3;
	transition: fill 0.45s var(--ease);
}
.jsmap__grid {
	fill: url(#jsmap-streets);
	stroke: none;
	pointer-events: none;
	transition: opacity 0.45s var(--ease);
}

.jsmap__region { cursor: pointer; }
.jsmap__region:hover .jsmap__land,
.jsmap__region.is-active .jsmap__land { fill: var(--brass); }
.jsmap__region.is-active .jsmap__grid { opacity: 0.55; }

/* Keyboard users get the same affordance as the mouse. */
.jsmap__region:focus-visible { outline: none; }
.jsmap__region:focus-visible .jsmap__land {
	fill: var(--brass);
	stroke: var(--teal);
	stroke-width: 5;
}

.jsmap__anchor-halo { fill: rgba(194,160,106,0.28); }
.jsmap__anchor-dot { fill: var(--brass-light); stroke: #fff; stroke-width: 2; }

/* Labels are HTML positioned by percentage, never <text> inside the SVG:
   scaled type inside a viewBox goes soft and cannot inherit the page's font
   loading. */
.jsmap__labels { position: absolute; inset: 0; pointer-events: none; }
.jsmap__label {
	position: absolute;
	transform: translate(-50%, -50%);
	font-size: clamp(0.5625rem, 0.75vw, 0.75rem);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: #fff;
	text-align: center;
	line-height: 1.25;
	text-shadow: 0 1px 6px rgba(9,18,30,0.65);
	white-space: nowrap;
}

.jsmap__panel {
	border: 1px solid var(--hairline);
	background: var(--white);
	padding: clamp(1.5rem, 3vw, var(--s4));
	position: sticky;
	top: calc(var(--header-h) + 1.5rem);
}
.jsmap__panel-media {
	aspect-ratio: 16 / 10;
	background: var(--paper);
	margin: 0 0 var(--s3);
	overflow: hidden;
}
.jsmap__panel-media img, .jsmap__panel-media video { width: 100%; height: 100%; object-fit: cover; }

.jsmap__panel-title { margin-bottom: var(--s1); }
.jsmap__panel-zips {
	font-size: 0.75rem; letter-spacing: 0.1em; text-transform: uppercase;
	color: var(--brass-deep); font-weight: 600; margin-bottom: var(--s2);
}
.jsmap__facts { margin: var(--s3) 0 0; padding: 0; list-style: none; }
.jsmap__fact { border-top: 1px solid var(--hairline); padding: 0.85rem 0; }
.jsmap__fact-label {
	display: block;
	font-size: 0.6875rem; letter-spacing: 0.11em; text-transform: uppercase;
	color: var(--ink-soft); margin-bottom: 0.2rem;
}
.jsmap__fact-value { font-size: 0.9375rem; color: var(--ink); }

.jsmap__tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: var(--s2) 0 0; padding: 0; list-style: none; }
.jsmap__tag {
	font-size: 0.6875rem; letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--teal); border: 1px solid var(--hairline);
	padding: 0.35em 0.7em; border-radius: 2px;
}

/* The matcher — four questions, then a recommendation. */
.matcher { border-top: 1px solid var(--hairline); margin-top: var(--s4); padding-top: var(--s4); }
.matcher__q { margin-bottom: var(--s3); }
.matcher__legend {
	font-family: var(--font-display); font-size: 1.25rem; color: var(--navy);
	margin-bottom: var(--s2); padding: 0; border: 0;
}
.matcher__opts { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.matcher__opt {
	position: relative;
	font-size: 0.8125rem;
	border: 1px solid var(--hairline);
	background: #fff;
	color: var(--ink);
	padding: 0.7em 1.1em;
	border-radius: 2px;
	cursor: pointer;
	transition: border-color 0.3s var(--ease), background 0.3s var(--ease), color 0.3s var(--ease);
}
.matcher__opt:hover { border-color: var(--brass); }
.matcher__opt[aria-pressed="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }

.matcher__result { margin-top: var(--s3); }
.matcher__result[hidden] { display: none; }

/* A live neighbourhood map, shown only once a Google Maps key is set. */
.community-map__wrap { margin-top: var(--s4); }
.community-map {
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	border: 1px solid var(--hairline);
	filter: saturate(0.85);
}

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

.grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
	gap: clamp(1.25rem, 2.5vw, var(--s3));
}

.card { display: flex; flex-direction: column; text-decoration: none; color: inherit; }
.card__media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--paper); margin-bottom: var(--s2); }
.card__media img, .card__media video { width: 100%; height: 100%; object-fit: cover; transition: transform 0.9s var(--ease); }
.card:hover .card__media img, .card:hover .card__media video { transform: scale(1.045); }
.card__title { font-family: var(--font-display); font-size: 1.3125rem; color: var(--navy); margin: 0 0 0.35rem; }
.card__meta { font-size: 0.75rem; letter-spacing: 0.09em; text-transform: uppercase; color: var(--brass-deep); font-weight: 600; }
.card__text { font-size: 0.9375rem; color: var(--ink); margin: 0.5rem 0 0; }

/* When a community has no photograph yet, the card falls back to the map
   fragment rather than a grey box or, worse, a stock photo of somewhere else. */
.card__media--drawn { background: var(--navy); display: grid; place-items: center; }
.card__media--drawn svg { width: 70%; height: auto; opacity: 0.9; }

/* ------------------------------------------------------- estate section -- */

/*
	The Estate Sales page is a second front door, aimed at attorneys and
	executors rather than at buyers. It runs cooler and more formal: navy
	ground, no photography, numbered points, and a plain intake form. The tone
	shift is the brief's, in its own words: "professional, efficient, and
	process-oriented".
*/
.estate { background: var(--navy); color: #DCE3EC; }
.estate h1, .estate h2, .estate h3 { color: #fff; }
.estate a { color: var(--brass-light); }

.estate__points { list-style: none; margin: var(--s4) 0 0; padding: 0; counter-reset: pt; }
.estate__point {
	counter-increment: pt;
	display: grid; grid-template-columns: 3.5rem 1fr; gap: var(--s2);
	padding: var(--s3) 0;
	border-top: 1px solid rgba(194,160,106,0.32);
}
.estate__point::before {
	content: counter(pt, decimal-leading-zero);
	font-family: var(--font-display);
	font-size: 1.5rem;
	color: var(--brass-light);
	line-height: 1;
}
.estate__point p { margin: 0; color: #C9D3E0; }

/*
	The same numbered list on a white ground. Brass Light is chosen for the
	numerals inside navy bands because it measures 6.15:1 there — on white it
	drops to roughly 2.8:1 and fails even the large-text bar, so the numerals
	step down to full Brass (3.95:1, which clears 3:1 for display sizes).
*/
.points--light .estate__point { border-color: var(--hairline); }
.points--light .estate__point::before { color: var(--brass); }
.points--light .estate__point p { color: var(--ink); }

/* -------------------------------------------------- homepage market band -- */

/*
	A ruled ledger, not a row of stat cards. Six identical boxes is the shape
	every agent template ships; a market report in print is a table, and a table
	reads down a phone without restacking into six lonely squares.
*/
.mkt-band__head {
	display: flex; align-items: baseline; justify-content: space-between;
	gap: var(--s3); flex-wrap: wrap;
}
.mkt-band__head h2 { margin-bottom: 0; }

.mkt-band__asof {
	margin: 0;
	font-size: 0.6875rem; letter-spacing: 0.13em; text-transform: uppercase;
	font-weight: 600; color: var(--brass-light);
}
.mkt-band__src {
	display: block; margin-top: 0.3rem;
	letter-spacing: 0.09em; font-weight: 400; color: #93A1B5;
}

.mkt-band__list { margin: var(--s4) 0 0; padding: 0; }

.mkt-row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: baseline;
	gap: var(--s3);
	padding: 1.15rem 0;
	border-top: 1px solid rgba(194,160,106,0.28);
}
.mkt-row:last-child { border-bottom: 1px solid rgba(194,160,106,0.28); }

.mkt-row__label {
	font-size: 0.8125rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: #C9D3E0;
	font-weight: 500;
}

.mkt-row__value {
	margin: 0;
	font-family: var(--font-display);
	font-size: clamp(1.75rem, 3vw + 1rem, 2.75rem);
	line-height: 1;
	color: var(--brass-light);
	display: flex; align-items: baseline; gap: 0.6rem;
	white-space: nowrap;
}

.mkt-row__delta {
	font-family: var(--font-body);
	font-size: 0.75rem;
	letter-spacing: 0.06em;
	font-weight: 600;
	white-space: nowrap;
}
/* Deltas are tinted from the band's own hues rather than from stock red and
   green: #7FB8A0 and #D98E7A both clear 4.5:1 on this navy, where the obvious
   signal colours do not. */
.mkt-row__delta--up { color: #7FB8A0; }
.mkt-row__delta--down { color: #D98E7A; }
.mkt-row__delta--flat { color: #93A1B5; }

.mkt-band__cta { margin-top: var(--s4); }

@media (max-width: 620px) {
	.mkt-row { grid-template-columns: 1fr; gap: 0.35rem; }
	.mkt-row__value { justify-content: flex-start; }
}

/* ------------------------------------------------------ market update -- */

/*
	The charts come out of KW's Inspire Network feed as near-black images and
	Jason cannot re-render them. So the page moves to meet them: it runs on the
	navy already in the system, and the charts sit on their own ground instead
	of punching six holes in a white page.
*/
.market__stamp {
	font-size: 0.6875rem; letter-spacing: 0.13em; text-transform: uppercase;
	font-weight: 600; color: var(--brass-light); margin-top: var(--s3);
}

.market__note {
	border: 1px dashed rgba(194,160,106,0.42);
	padding: var(--s3);
	margin-bottom: var(--s4);
	font-size: 0.875rem;
	color: #C9D3E0;
}

.market__content { color: #C9D3E0; }
.market__content p { max-width: 62ch; }
.market__content strong { color: #fff; }

/* Each chart gets a hairline and room to breathe. They are wide and dense, so
   they stack one per row rather than tiling — two of these side by side are
   unreadable at any width. */
.market__content figure,
.market__content .wp-block-image {
	margin: var(--s4) 0 0;
	max-width: none;
}
.market__content img {
	width: 100%;
	border: 1px solid rgba(194,160,106,0.3);
	background: #0B0B0C;
}
.market__content a:has(img) { display: block; }
.market__content a:has(img):hover img { border-color: var(--brass-light); }

.market__content figcaption {
	margin-top: 0.7rem;
	font-size: 0.75rem;
	letter-spacing: 0.06em;
	color: #93A1B5;
	text-align: left;
}

/* On a phone a 1800px dense chart is unreadable inline, so every chart links
   to its full-size file. This says so rather than leaving it to be discovered. */
.market__hint {
	font-size: 0.75rem; letter-spacing: 0.05em; color: #93A1B5;
	border-top: 1px solid rgba(194,160,106,0.28);
	padding-top: var(--s2); margin-top: var(--s4);
}

/* --------------------------------------------------------------- forms -- */

.field { margin-bottom: var(--s3); }
.field label {
	display: block;
	font-size: 0.6875rem; letter-spacing: 0.11em; text-transform: uppercase;
	font-weight: 600; color: var(--ink-soft); margin-bottom: 0.45rem;
}
.field input, .field textarea, .field select {
	width: 100%;
	font-family: var(--font-body); font-size: 1rem;
	padding: 0.85em 1em;
	border: 1px solid var(--hairline);
	border-radius: 2px;
	background: #fff; color: var(--ink);
	transition: border-color 0.3s var(--ease);
}
.field input:focus, .field textarea:focus { border-color: var(--teal); }
.field input::placeholder, .field textarea::placeholder { color: #8A95A5; }
.estate .field label { color: var(--brass-light); }
.estate .field input, .estate .field textarea {
	background: rgba(255,255,255,0.06);
	border-color: rgba(194,160,106,0.4);
	color: #fff;
}
.estate .field input::placeholder, .estate .field textarea::placeholder { color: #9FB0C4; }

/* ------------------------------------------------ Cloud CMA valuation -- */

/*
	#F9FAFB is not one of our tokens — it is Cloud CMA's own page background,
	copied deliberately. The widget is a cross-origin iframe that will not tell
	us its height, so the frame has to be over-tall to guarantee no inner
	scrollbar. Painting the section in the widget's exact background makes that
	spare height disappear: the iframe stops looking like a box on the page and
	starts looking like part of it. Change this only if Cloud CMA restyles.
*/
.cma { background: #F9FAFB; }

.cma__frame {
	position: relative;
	width: 100%;
	height: var(--cma-h, 880px);
}
.cma__frame iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
}

/*
	The Cloud CMA button.

	Their script injects `a.cloud_cma_button_class` with its own inline <style>
	block: a lime gradient, Helvetica, rounded corners. Dropped into this page
	untouched it looks like someone else's software bolted onto the side.

	These rules restate every property that block sets, because it is injected
	into the document at runtime and we cannot rely on winning on source order
	alone — hence the specificity of the selector and the !important on the
	background, which is the one declaration their gradient stack fights hardest
	for. If Cloud CMA ever changes their class name this stops applying and the
	green returns, which is the visible symptom to look for.
*/
.cma-instant { margin-top: var(--s4); padding-top: var(--s3); border-top: 1px solid var(--hairline); }
.cma-instant__title { font-size: 1.25rem; margin-bottom: 0.35rem; }
.cma-instant__note { font-size: 0.875rem; color: var(--ink-soft); margin-bottom: var(--s2); }

.cma-instant a.cloud_cma_button_class,
a.cloud_cma_button_class {
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	background: var(--brass-deep) !important;
	background-image: none !important;
	border: 1px solid var(--brass-deep) !important;
	border-radius: 2px !important;
	color: #fff !important;
	font-family: var(--font-body) !important;
	font-size: 0.8125rem !important;
	font-weight: 600 !important;
	letter-spacing: 0.09em !important;
	text-transform: uppercase !important;
	text-decoration: none !important;
	text-shadow: none !important;
	box-shadow: none !important;
	padding: 1.05em 1.9em !important;
	line-height: 1 !important;
	transition: background 0.35s var(--ease), border-color 0.35s var(--ease);
}
.cma-instant a.cloud_cma_button_class:hover,
a.cloud_cma_button_class:hover {
	background: #6F5429 !important;
	border-color: #6F5429 !important;
	color: #fff !important;
}

.cma__note {
	margin: var(--s3) auto 0;
	text-align: center;
	font-size: 0.875rem;
	color: var(--ink-soft);
}

/* Phones need more height, not less: the form stacks. */
@media (max-width: 880px) {
	.cma__frame { height: calc(var(--cma-h, 880px) + 160px); }
}

/* --------------------------------------------------- IDX placeholder ---- */

/*
	Shown wherever the MLS search will live until Jason's IDX account is signed.
	It states plainly what is missing instead of rendering a dead search box —
	an empty widget reads as a broken site, a note reads as a site mid-launch.
*/
.idx-pending {
	border: 1px dashed var(--hairline);
	background: var(--paper);
	padding: var(--s4);
	text-align: center;
}
.idx-pending p { margin-inline: auto; color: var(--ink-soft); font-size: 0.9375rem; }

/* -------------------------------------------------------------- footer -- */

.site-footer { background: var(--navy); color: #B9C4D4; padding-block: var(--s5) var(--s3); }
.site-footer a { color: #DCE3EC; text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }

.footer__top {
	display: grid;
	grid-template-columns: minmax(0, 1.3fr) repeat(2, minmax(0, 1fr));
	gap: var(--s4);
	padding-bottom: var(--s4);
	border-bottom: 1px solid rgba(255,255,255,0.14);
}
.footer__wordmark {
	font-family: var(--font-display); font-size: 1.5rem; letter-spacing: 0.14em;
	text-transform: uppercase; color: #fff; display: block; margin-bottom: var(--s2);
}
.footer__heading {
	font-family: var(--font-body);
	font-size: 0.6875rem; letter-spacing: 0.13em; text-transform: uppercase;
	color: var(--brass-light); margin-bottom: var(--s2); font-weight: 600;
}
.footer__list { list-style: none; margin: 0; padding: 0; }
.footer__list li { margin-bottom: 0.5rem; font-size: 0.9375rem; }

.social { display: flex; gap: 0.75rem; margin-top: var(--s2); }
.social a {
	display: grid; place-items: center;
	width: 38px; height: 38px;
	border: 1px solid rgba(255,255,255,0.25); border-radius: 50%;
	transition: background 0.3s var(--ease), border-color 0.3s var(--ease);
}
.social a:hover { background: rgba(255,255,255,0.12); border-color: var(--brass-light); }
.social svg { width: 16px; height: 16px; fill: currentColor; }

/*
	GREC disclosure. `.grec__name` is shared by the agent name, the brokerage
	and the broker so that "equal or greater size" is structural and cannot be
	broken by a later edit to one of them. Do not split this rule.
*/
.grec { padding-top: var(--s3); font-size: 0.8125rem; line-height: 1.7; color: #A7B4C6; }
.grec__line { margin: 0 0 0.25rem; max-width: none; }
.grec__name { font-size: 0.9375rem; font-weight: 600; color: #E6EBF2; }
.grec__meta { color: #A7B4C6; }
.grec__sep { color: var(--brass); padding-inline: 0.6em; }
.grec__eho { display: flex; align-items: center; gap: 0.75rem; margin-top: var(--s2); font-size: 0.75rem; color: #93A1B5; }
.grec__eho img { filter: invert(1) opacity(0.75); flex: none; }

/* -------------------------------------------------------------- motion -- */

/*
	One authored moment: content rises into place as its section arrives, once,
	staggered by position. Everything starts visible — .is-revealed is added by
	JS only after it confirms IntersectionObserver support, so a failed script
	leaves a readable page rather than a blank one.
*/
.js-reveal { opacity: 1; }

.has-observer .js-reveal {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.has-observer .js-reveal.is-revealed { opacity: 1; transform: none; }
.has-observer .js-reveal:nth-child(2) { transition-delay: 0.08s; }
.has-observer .js-reveal:nth-child(3) { transition-delay: 0.16s; }
.has-observer .js-reveal:nth-child(4) { transition-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
	.has-observer .js-reveal { opacity: 1; transform: none; transition: none; }
	.hero__media video { display: none; }
	.card__media img, .card__media video { transition: none; }
	*, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ---------------------------------------------------------- responsive -- */

@media (max-width: 1024px) {
	.jsmap { grid-template-columns: 1fr; }
	.jsmap__panel { position: static; }
	.footer__top { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 880px) {
	:root { --header-h: 64px; }

	.nav-toggle { display: block; }

	/*
		The panel is revealed by animating clip-path, not max-height. A
		max-height transition relayouts the document on every frame of the
		open, which is exactly the phone this site is mostly read on doing the
		most expensive possible work during its most visible animation.
		clip-path stays on the compositor and the panel's real height is never
		in question, so the menu cannot half-open at the wrong size.

		visibility is delayed by the length of the transition on close so the
		hidden panel stops taking pointer events only once it is out of sight.
	*/
	.nav {
		position: fixed; inset: var(--header-h) 0 auto 0;
		background: #fff;
		border-bottom: 1px solid var(--hairline);
		max-height: 80vh; overflow-y: auto;
		margin-left: 0;
		/* Undo the desktop row: in the panel the list and the button stack. */
		flex-direction: column;
		align-items: stretch;
		gap: 0;

		clip-path: inset(0 0 100% 0);
		opacity: 0;
		visibility: hidden;
		transition:
			clip-path 0.45s var(--ease),
			opacity 0.3s var(--ease),
			visibility 0s linear 0.45s;
	}
	.nav__cta { display: inline-flex; margin: 0 var(--gutter) var(--s3); }
	.nav.is-open {
		clip-path: inset(0 0 0 0);
		opacity: 1;
		visibility: visible;
		transition:
			clip-path 0.45s var(--ease),
			opacity 0.25s var(--ease),
			visibility 0s;
	}
	.nav__list { flex-direction: column; align-items: stretch; gap: 0; padding: var(--s2) var(--gutter) var(--s3); }
	.nav__list a { color: var(--navy) !important; padding-block: 0.9em; border-bottom: 1px solid var(--hairline); display: block; }
	.nav__list a::after { display: none; }
	.nav__list .menu-item-estate > a { border-left: 0; border-right: 0; padding-inline: 0; }
	.nav__cta { margin: var(--s2) 0 0; }

	.split { grid-template-columns: 1fr; }
	.split--reverse .split__media { order: 0; }
	.split__figure::before { display: none; }

	/* The action bar restacks; it never scrolls sideways. */
	.hero__actions {
		grid-template-columns: 1fr;
		position: static; transform: none;
		width: min(100% - (var(--gutter) * 2), 60rem);
		margin: 0 auto;
	}
	.hero__action { border-right: 0; border-bottom: 1px solid var(--hairline); }
	.hero__action:last-child { border-bottom: 0; }
	.hero { min-height: auto; padding-bottom: var(--s4); }
	.hero__inner { padding-bottom: var(--s4); }
	.hero + * { padding-top: clamp(2.5rem, 8vw, 4rem); }
}

@media (max-width: 620px) {
	.footer__top { grid-template-columns: 1fr; gap: var(--s3); }
	.estate__point { grid-template-columns: 2.5rem 1fr; }
	.grec__sep { display: block; height: 0; overflow: hidden; padding: 0; }
	.grec__line { margin-bottom: 0.5rem; }
}

/* Labels crowd badly on a phone; below this the map hands off to the cards. */
@media (max-width: 560px) {
	.jsmap__label { font-size: 0.5rem; letter-spacing: 0.04em; }
}

/* ---------------------------------------------------------------- misc -- */

.entry-content > * + * { margin-top: var(--s2); }
.entry-content h2 { margin-top: var(--s4); }
.entry-content h3 { margin-top: var(--s3); }
.entry-content ul, .entry-content ol { max-width: var(--measure); padding-left: 1.25em; }
.entry-content li { margin-bottom: 0.4rem; }

blockquote {
	margin: var(--s4) 0;
	padding-left: var(--s3);
	border-left: 1px solid var(--brass);
	font-family: var(--font-display);
	font-size: clamp(1.125rem, 1.4vw + 0.9rem, 1.5rem);
	line-height: 1.45;
	color: var(--navy);
}
blockquote cite {
	display: block;
	margin-top: var(--s2);
	font-family: var(--font-body);
	font-size: 0.8125rem;
	font-style: normal;
	letter-spacing: 0.09em;
	text-transform: uppercase;
	color: var(--ink-soft);
}
