/* ==========================================================================
   Metro Hub — /metros/{term}/
   Loaded only on is_tax('metros') from inc/hh-metro-hub.php.

   LIGHT THEME ONLY. There is deliberately no dark-mode block in this file.

   Colour model mirrors assets/css/hh-debt-buster.css: every colour resolves
   through an approved --color-* semantic token with a literal fallback, so
   this page inherits for free if --color-* ever ships globally. Local
   --hh-metro-* aliases are what the rules below actually consume.

   Everything is scoped under .hh-metro / .hh-metro-wrap. Nothing is declared
   on :root and no bare element selector is defined at top level, so nothing
   here can leak into the rest of the site.

   Three inherited behaviours this file has to defend against:
     1. Salient styles bare headings hard (h1 = DM Serif Display 86px
        capitalize, h2 = 70px). Every heading below therefore sets family,
        size, weight and text-transform explicitly.
     2. A site-wide inline WPCode snippet forces h2 to 40px !important below
        1000px. That can only be undone with !important — see the band name.
     3. Salient ships bare dd{padding-left:20px} and a .container-wrap
        background/padding that loads after this file. Both are neutralised
        explicitly below.

   Typography matches the community page: 'Playfair Display' is declared for
   continuity but is NOT loaded anywhere on this site, so the serif renders
   as Georgia — as it already does on every other Hughston page.
   ========================================================================== */

.hh-metro {

	/* ── Surfaces ────────────────────────────────────────────────── */
	--hh-metro-canvas:        var(--color-bg-canvas,          #f5f0e8);  /* Pearl       */
	--hh-metro-surface:       var(--color-bg-surface-raised,  #fbf8f2);  /* Porcelain   */
	--hh-metro-subtle:        var(--color-bg-surface-subtle,  #e4e0da);  /* Pearl Dark  */

	/* ── Text ────────────────────────────────────────────────────── */
	--hh-metro-text:          var(--color-text-primary,       #08090f);  /* Ink         */
	--hh-metro-muted:         var(--color-text-muted,         #5c6e70);  /* Muted Teal  */

	/* ── Action ──────────────────────────────────────────────────── */
	--hh-metro-action:        var(--color-action-primary-bg,        #277253); /* Hughston Green */
	--hh-metro-action-fg:     var(--color-action-primary-fg,        #f5f0e8);
	--hh-metro-action-active: var(--color-action-primary-active-bg, #22443e); /* Deep Green */

	/* ── Lines, focus, accent ────────────────────────────────────── */
	--hh-metro-border:        var(--color-border-subtle,      #d5d2cd);  /* Warm Border */
	--hh-metro-heading:       var(--color-bg-inverse,         #22443e);  /* Deep Green  */
	--hh-metro-focus:         var(--color-focus-ring,         #22443e);

	/* ── Inverse panel (stats strip) ──────────────────────────────────
	   Token mapping follows assets/css/hh-debt-buster.css, which already
	   binds Deep Green to --color-bg-inverse and Mint to --color-selection-bg.
	   Porcelain values reuse --hh-metro-surface rather than
	   --color-text-inverse: that token's house fallback is Pearl (#f5f0e8),
	   and the approved treatment calls for Porcelain (#fbf8f2).
	   Measured contrast on Deep Green #22443e:
	     Mint #a1d2b9 label ....... 6.3:1  (AA at 11px)
	     Porcelain #fbf8f2 value .. 10.1:1 (AAA) */
	--hh-metro-mint:          var(--color-selection-bg,       #a1d2b9);  /* Mint        */
	--hh-metro-panel:         var(--color-bg-inverse,         #22443e);  /* Deep Green  */
	--hh-metro-panel-rule:    rgb(161 210 185 / 26%);

	/* How far the stats panel hangs below the hero's tinted area. Desktop
	   and tablet only — see the 768px block, where stacking wins over
	   overlap. */
	--hh-metro-overlap:       26px;

	/* ── Wash over the community photographs ─────────────────────────
	   Kept within a narrow 88-92% band rather than a wide ramp: the
	   content spans the full width, so an exposed edge would mean
	   inconsistent contrast rather than a nicer picture. The photograph
	   is editorial texture here, not a hero image. */
	--hh-metro-wash-strong:   rgb(245 240 232 / 92%);
	--hh-metro-wash:          rgb(245 240 232 / 88%);
	--hh-metro-wash-soft:     rgb(245 240 232 / 90%);

	/* ── Geometry ────────────────────────────────────────────────── */
	--hh-metro-max:           1400px;
	--hh-metro-gutter:        24px;
	--hh-metro-radius:        10px;
	--hh-metro-radius-pill:   999px;

	/* Jump-link offset. Defaults to Salient's own header custom property
	   (--header-nav-height is 90px desktop / 64px mobile, written into
	   uploads/salient/salient-dynamic-styles.css), so anchors land correctly
	   with JavaScript disabled. assets/js/hh-metro-hub.js replaces it with a
	   measured value that also accounts for the admin bar. */
	--hh-metro-offset:        var(--header-nav-height, 90px);

	/* ── Fonts ───────────────────────────────────────────────────── */
	--hh-metro-serif:         'Playfair Display', Georgia, serif;
	--hh-metro-sans:          'Nunito Sans', sans-serif;

	background: var(--hh-metro-canvas);
	color: var(--hh-metro-text);
	font-family: var(--hh-metro-sans);
	overflow-x: clip;
}

/* The wrapper also carries Salient's .container-wrap, which sets
   background-color and a 40px top padding from a stylesheet that loads AFTER
   this one. At equal specificity that wins on source order and leaves a 40px
   white strip between the fixed header and the Pearl hero (measured: white to
   y=129, Pearl from y=130, on a 1440px render). Doubling the class beats it
   at (0,2,0) without !important. */
.container-wrap.hh-metro-wrap {
	background: var(--color-bg-canvas, #f5f0e8);
	padding-top: 0;
}


/* ==========================================================================
   HERO
   ========================================================================== */

/* The hero carries the page's only tinted surface: a warm Porcelain-to-Pearl
   field lifted by two very low-alpha radial washes (Mint top-right, Hughston
   Green bottom-left). It is painted by a pseudo-element rather than on the
   element itself for one reason — ::before can stop SHORT of the hero's
   bottom edge, which is what lets the Deep Green stats panel straddle the
   boundary instead of merely sitting under it. The literal rgb() values
   follow the same precedent as the community washes further down: these are
   translucent tints, and there is no semantic token for a tint. */
.hh-metro-hero {
	position: relative;
	padding: clamp(68px, 8.5vw, 132px) 0 clamp(40px, 5vw, 64px);
}

/* With stats present the panel IS the hero's bottom edge, so the shell needs
   no padding of its own beneath it. */
.hh-metro-hero--stats {
	padding-bottom: 0;
}

.hh-metro-hero::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background:
		radial-gradient(64% 78% at 80% 6%,  rgb(161 210 185 / 42%) 0%, rgb(161 210 185 / 0%) 70%),
		radial-gradient(52% 62% at 0% 100%, rgb(39 114 83 / 12%)   0%, rgb(39 114 83 / 0%)   72%),
		linear-gradient(180deg, #fbf8f2 0%, #f5f0e8 72%);
	/* The seam rule is Deep Green at low alpha rather than Warm Border, so the
	   line the stats panel sits on belongs to the panel rather than to the
	   generic page furniture. */
	border-bottom: 1px solid rgb(34 68 62 / 20%);
	pointer-events: none;
}

/* With a photograph, the backdrop below replaces the tint entirely —
   including its boundary rule and its share of the seam. */
.hh-metro-hero--media::before {
	display: none;
}

/* Everything real sits above the wash. */
.hh-metro-hero__inner,
.hh-metro-hero__stats {
	position: relative;
	z-index: 1;
}

/* THE SEAM. The stats panel is the hero's last child with no bottom margin,
   so the hero's bottom edge and the panel's bottom edge are the same line.
   Lifting the wash's bottom by --hh-metro-overlap therefore leaves exactly
   that much of the Deep Green panel hanging past the tint and its boundary
   rule, onto the plain Pearl page below.
   Done this way, NOTHING moves: no negative margins, no z-index war with the
   jump nav, and no clearance to maintain on whichever element happens to
   follow the hero (jump nav, first band, or the empty-state block). */
@media (min-width: 769px) {

	.hh-metro-hero--stats::before,
	.hh-metro-hero--stats .hh-metro-hero__backdrop {
		bottom: var(--hh-metro-overlap);
	}
}

.hh-metro-hero__inner {
	max-width: var(--hh-metro-max);
	margin: 0 auto;
	padding: 0 var(--hh-metro-gutter);
}

/* No measure here. The heading and the intro each carry their own, and a ch
   cap on this wrapper resolves against ITS font-size (16px), not the 104px
   heading's — which silently clamped the H1 to ~496px and broke it onto a
   third line. */
.hh-metro-hero__lede {
	max-width: none;
}

/* A dateline, not a badge: a hairline rule running into small tracked caps
   on one baseline. No container, no radius, no fill — the rule IS the
   graphic. Deep Green measures 8.2:1 over the worst photograph the hero can
   be given; Muted Teal was tested here and reaches only 4.05:1 against that
   same backdrop, which is why the type is green rather than teal. */
.hh-metro-hero__eyebrow {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 0 14px;
	margin: 0 0 clamp(20px, 2.4vw, 30px);
	font-family: var(--hh-metro-sans);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.2em;
	line-height: 1.4;
	text-transform: uppercase;
	color: var(--hh-metro-heading);
}

.hh-metro-hero__rule {
	flex: 0 0 auto;
	display: block;
	width: clamp(38px, 4vw, 64px);
	height: 2px;
	background: linear-gradient(90deg,
		var(--hh-metro-action) 0 58%,
		var(--hh-metro-mint)  58% 100%);
}

.hh-metro-hero__eyebrow-sep {
	margin: 0 0.15em;
	color: rgb(39 114 83 / 55%);
	font-weight: 400;
}

/* The heading is the event. The break after "in" is set in the markup as
   two block spans rather than left to a max-width, because a wrap heuristic
   moves it at every viewport — a 16ch cap broke this as "New / Homes in /
   Newnan, GA" at 1440. Longest current metro, "New Homes in Warner Robins,
   GA", still holds two lines at the 104px cap. */
.hh-metro-hero__title {
	margin: 0;
	font-family: var(--hh-metro-serif);
	font-size: clamp(44px, 7.4vw, 104px);
	font-weight: 500;
	line-height: 0.98;
	letter-spacing: -0.018em;
	text-transform: none;
	color: var(--hh-metro-heading);
	text-wrap: balance;
}

.hh-metro-hero__title-line {
	display: block;
}

/* Deliberately narrower than the heading and a step smaller than the band
   copy: the hero introduces, it does not brief. The measure is capped at
   46ch — a presentation-level limit only, no editorial content is dropped.
   Ink rather than Muted Teal because teal measures 4.05:1 against a
   worst-case photograph here and fails AA at this size. */
.hh-metro-hero__intro {
	margin-top: clamp(28px, 3.2vw, 44px);
	max-width: 46ch;
	font-size: 16px;
	line-height: 1.72;
	color: var(--hh-metro-text);
}

.hh-metro-hero__intro p {
	margin: 0 0 1em;
}

.hh-metro-hero__intro p:last-child {
	margin-bottom: 0;
}

/* ── Full-bleed hero photograph ──────────────────────────────────────────
   Optional, and absent on 15 of the 16 metro terms today, so everything here
   is additive: without metro_hero_image the hero keeps the flat wash above
   and none of this applies.

   The photograph is an <img> stretched to fill, not a CSS background. This is
   the LCP element and a background-image cannot carry srcset — a phone would
   pull the full desktop file. object-fit does the framing instead, and the
   scrim rides on top as its own layer so no text ever composites directly
   against photographic detail. */
.hh-metro-hero__backdrop {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
	background: var(--hh-metro-subtle);
	border-bottom: 1px solid rgb(34 68 62 / 20%);
}

/* The hero box is proportionally taller than a 16:9 photograph, so cover
   scales to the height and crops horizontally. Biasing the crop right of
   centre puts the picture's right-hand content into the part of the frame
   the scrim actually reveals, instead of hiding it under the solid end. */
.hh-metro-hero__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 68% center;
}

/* THE SCRIM — asymmetric, left-weighted.
   The copy column is capped well inside the strong end, so text contrast
   never depends on which photograph an editor picked. Measured against the
   worst case a photograph can present (pure black beneath):
     Deep Green H1 over the 93% zone .... 8.1:1
     Ink body over the 93% zone ........ 14.9:1
     Deep Green H1 at the 72% midpoint .. 5.1:1
     Ink body at the 72% midpoint ....... 9.3:1
   All pass AA, so the picture may be anything at all.
   The second (vertical) layer is separate from the horizontal one: alphas
   compose, lifting the bottom-right corner from 40% to roughly 73% so the
   Deep Green stats panel seats on a settled surface rather than on detail. */
.hh-metro-hero__scrim {
	position: absolute;
	inset: 0;
	display: block;
	background:
		linear-gradient(180deg,
			rgb(245 240 232 / 0%)  58%,
			rgb(245 240 232 / 48%) 100%),
		linear-gradient(90deg,
			rgb(245 240 232 / 100%)  0%,
			rgb(245 240 232 / 100%) 35%,
			rgb(245 240 232 / 92%)  50%,
			rgb(245 240 232 / 66%)  64%,
			rgb(245 240 232 / 40%)  76%,
			rgb(245 240 232 / 22%) 100%);
}

@media (min-width: 1025px) {

	/* Enough height for the photograph to read as one, even on a metro with
	   no intro copy — Fort Mitchell has none. The lede centres in whatever
	   space is left while the stats panel stays pinned to the bottom edge,
	   so short heroes gain picture rather than dead Pearl. */
	.hh-metro-hero--media {
		display: flex;
		flex-direction: column;
		min-height: clamp(520px, 46vw, 720px);
	}

	/* Both children carry `margin-inline: auto` for the non-flex case. As
	   flex items in a column container those auto margins would shrink each
	   box to its content width and centre it — which collapsed the stats
	   panel to ~570px. An explicit width resolves the autos to zero. */
	.hh-metro-hero--media .hh-metro-hero__inner,
	.hh-metro-hero--media .hh-metro-hero__stats {
		width: 100%;
	}

	.hh-metro-hero--media .hh-metro-hero__inner {
		flex: 1 1 auto;
		display: flex;
		flex-direction: column;
		justify-content: center;
	}

	/* CONTROLLED ASYMMETRY. The strip's left edge sits on the heading's
	   margin and its right end runs off the viewport — not a centred
	   container, and deliberately not the text measure. Squaring the right
	   corners is what sells it as a bleed rather than a misaligned box.
	   The left edge is kept ON the gutter rather than pulled out to the
	   window: that margin is the only place the hero/stats overlap is
	   visible, since the bar itself is opaque and covers the seam everywhere
	   it runs. A full-bleed bar looked cleaner but hid the overlap entirely. */
	.hh-metro .hh-metro-hero__stats {
		max-width: none;
		width: 100%;
		margin-left: 0;
		margin-right: 0;
		padding-left: max(
			var(--hh-metro-gutter),
			calc((100% - var(--hh-metro-max)) / 2 + var(--hh-metro-gutter))
		);
		padding-right: 0;
	}

	.hh-metro .hh-metro-stats {
		border-radius: 2px 0 0 2px;
	}
}

/* Below 1025px the copy spans the full width, so an asymmetric scrim would
   put the right-hand end of every line over the thin part. Flatten it. */
/* Tablet keeps a reveal, but a much gentler one — the copy measure is a far
   larger share of the viewport here, so the solid end has to run most of the
   way across before it opens. */
@media (max-width: 1024px) {

	.hh-metro-hero__scrim {
		background:
			linear-gradient(180deg,
				rgb(245 240 232 / 0%)  58%,
				rgb(245 240 232 / 44%) 100%),
			linear-gradient(90deg,
				rgb(245 240 232 / 100%)  0%,
				rgb(245 240 232 / 97%)  52%,
				rgb(245 240 232 / 84%)  74%,
				rgb(245 240 232 / 62%) 100%);
	}
}


/* ── Computed stats strip ───────────────────────────────────────────────── */

.hh-metro-hero__stats {
	--hh-stats-pad: clamp(18px, 2.2vw, 34px);
	max-width: var(--hh-metro-max);
	margin: clamp(40px, 5vw, 64px) auto 0;
	padding: 0 var(--hh-metro-gutter);
}

/* ONE block, not three cards. No shadow, a 2px radius rather than 10, and
   hairline rules instead of gaps — everything that made the cells read as
   separate objects is gone, leaving a single Deep Green bar.
   flex: 1 1 0 keeps the columns equal so the rules land on a regular
   rhythm whether the metro shows two figures or three. */
.hh-metro-stats {
	display: flex;
	flex-wrap: nowrap;
	gap: 0;
	margin: 0;
	padding: clamp(28px, 3.2vw, 46px) var(--hh-stats-pad);
	border: 0;
	border-radius: 2px;
	background: var(--hh-metro-panel);
}

/* column-reverse puts the VALUE above its LABEL while leaving the <dl>
   markup valid — <dt> must precede <dd>, and a screen reader still hears
   "Communities, 3", which is a correct reading of the pair either way.
   justify-content:flex-end is the TOP in a reversed column, so the three
   values sit on one line however the labels below them wrap. */
.hh-metro-stats__item {
	display: flex;
	flex-direction: column-reverse;
	justify-content: flex-end;
	flex: 1 1 0;
	min-width: 0;
	padding: 0 clamp(16px, 2.2vw, 44px);
	border-left: 1px solid var(--hh-metro-panel-rule);
}

.hh-metro-stats__item:first-child {
	padding-left: 0;
	border-left: 0;
}

/* Secondary by a wide margin — the label now hangs beneath the figure. */
.hh-metro-stats__label {
	margin: 12px 0 0;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--hh-metro-mint);
}

.hh-metro-stats__value {
	margin: 0;
	/* Salient's style.css has a bare dd{padding-left:20px}, which would
	   step every value 20px right of its label. */
	padding: 0;
	font-family: var(--hh-metro-serif);
	font-size: clamp(34px, 4vw, 54px);
	font-weight: 500;
	line-height: 1;
	letter-spacing: -0.015em;
	color: var(--hh-metro-surface);
	font-variant-numeric: tabular-nums;
}


/* ==========================================================================
   COMMUNITY JUMP NAV

   Deliberately NOT sticky. Salient sets body { overflow: hidden } on both
   axes, which turns body into a scroll container that never scrolls and
   pins every position:sticky descendant. The child theme's rescue is scoped
   to body.single-community and does not match a taxonomy archive, so a
   sticky bar here would silently never move. A calm editorial row avoids
   the problem rather than patching around it.
   ========================================================================== */

/* An index, not a control strip. No fill, no border box, no radius: a rule
   across the top, a set numeral, and the community name in the same serif
   the band headings use. The hit area is the whole row, and the hover and
   focus affordance is a rule that thickens under the name rather than a
   button that lights up. */
.hh-metro-jump {
	max-width: var(--hh-metro-max);
	margin: clamp(48px, 5.5vw, 84px) auto 0;
	padding: 0 var(--hh-metro-gutter);
}

.hh-metro-jump__title {
	margin: 0 0 clamp(14px, 1.6vw, 20px);
	font-family: var(--hh-metro-sans);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--hh-metro-muted);
}

.hh-metro-jump__list {
	display: flex;
	flex-wrap: wrap;
	gap: 0 clamp(30px, 4.4vw, 76px);
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--hh-metro-border);
}

.hh-metro-jump__item {
	margin: 0;
	padding: 0;
	list-style: none;
}

.hh-metro-jump__link {
	display: inline-flex;
	align-items: baseline;
	gap: 12px;
	padding: clamp(16px, 1.8vw, 22px) 0 clamp(14px, 1.6vw, 20px);
	border: 0;
	border-bottom: 2px solid transparent;
	border-radius: 0;
	background: none;
	text-decoration: none;
	transition: border-color 0.2s, color 0.2s;
}

.hh-metro-jump__num {
	flex: 0 0 auto;
	font-family: var(--hh-metro-sans);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.12em;
	color: var(--hh-metro-muted);
	font-variant-numeric: tabular-nums;
	transition: color 0.2s;
}

.hh-metro-jump__name {
	font-family: var(--hh-metro-serif);
	font-size: clamp(19px, 1.7vw, 24px);
	font-weight: 500;
	line-height: 1.2;
	color: var(--hh-metro-heading);
}

/* Salient ships a{color:#3555ff} and a:hover{color:inherit} at a specificity
   that beats a single class, so hover/focus colour is stated explicitly. */
.hh-metro .hh-metro-jump__link:hover,
.hh-metro .hh-metro-jump__link:focus {
	border-bottom-color: var(--hh-metro-action);
	background: none;
	color: var(--hh-metro-heading);
	text-decoration: none;
}

.hh-metro .hh-metro-jump__link:hover .hh-metro-jump__num,
.hh-metro .hh-metro-jump__link:focus .hh-metro-jump__num {
	color: var(--hh-metro-action);
}


/* ==========================================================================
   COMMUNITY BANDS
   ========================================================================== */

.hh-metro-bands {
	margin-top: clamp(40px, 5vw, 72px);
}

.hh-metro-band {
	position: relative;
	isolation: isolate;
	padding: clamp(44px, 5vw, 76px) 0;
	border-top: 1px solid var(--hh-metro-border);
	background: var(--hh-metro-canvas);

	/* Jump targets clear the fixed Salient header. The custom property is
	   measured in JS; the +24px is breathing room. */
	scroll-margin-top: calc(var(--hh-metro-offset) + 24px);
}

.hh-metro-band:last-child {
	border-bottom: 1px solid var(--hh-metro-border);
}

/* Bands with no usable photograph get the neutral treatment: a raised
   surface tone, so an unphotographed community reads as deliberate.
   The modifier is set in PHP rather than with :has(), so the fallback does
   not depend on selector support. */
.hh-metro-band--plain {
	background: var(--hh-metro-surface);
}

/* ── Backdrop: photograph layer + wash layer, both behind the content ───── */

.hh-metro-band__backdrop {
	position: absolute;
	inset: 0;
	z-index: -1;
	overflow: hidden;
	pointer-events: none;
}

.hh-metro-band__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/* The wash is a separate layer over the photograph. The content above is
   never given an opacity of its own, so text stays fully opaque. */
.hh-metro-band__wash {
	position: absolute;
	inset: 0;
	display: block;
	background: linear-gradient(
		to right,
		var(--hh-metro-wash-strong) 0%,
		var(--hh-metro-wash) 58%,
		var(--hh-metro-wash-soft) 100%
	);
}

.hh-metro-band__inner {
	position: relative;
	max-width: var(--hh-metro-max);
	margin: 0 auto;
	padding: 0 var(--hh-metro-gutter);

	display: grid;
	gap: 18px;
	grid-template-areas:
		"ident"
		"facts"
		"cols"
		"actions";
}

.hh-metro-band__ident   { grid-area: ident; }
.hh-metro-band__facts   { grid-area: facts; }
.hh-metro-band__actions { grid-area: actions; }
.hh-metro-band__cols    { grid-area: cols; }

.hh-metro-band__name {
	margin: 0;
	font-family: var(--hh-metro-serif);
	font-size: clamp(28px, 3.4vw, 42px);
	font-weight: 500;
	line-height: 1.12;
	text-transform: none;
	color: var(--hh-metro-heading);
}

/* A site-wide inline WPCode snippet ships a bare
   @media (max-width:1000px){ h2 { font-size:40px !important; line-height:1.2 !important } }.
   !important on an element selector cannot be beaten by specificity, so the
   band headings would render at 40px on every phone and tablet — larger than
   this page's own 38px H1. These two declarations are the only !important in
   the file and exist solely to undo that snippet. */
@media (max-width: 1000px) {

	.hh-metro-band__name {
		font-size: clamp(28px, 3.4vw, 42px) !important;
		line-height: 1.12 !important;
	}
}

/* Deep Green, not Muted Teal: measured against the washed photographs,
   Muted Teal lands at 3.5-4.4:1 and fails AA, while Deep Green holds
   7.0-8.7:1. The same applies to every small label inside a band. */
.hh-metro-band__place {
	margin: 6px 0 0;
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--hh-metro-heading);
}

.hh-metro-band__facts {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 6px 18px;
}

.hh-metro-band__price {
	margin: 0;
	font-size: 16px;
	line-height: 1.5;
	color: var(--hh-metro-text);
}

.hh-metro-band__price-value {
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.hh-metro-band__avail {
	margin: 0;
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--hh-metro-heading);
}

.hh-metro-band__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 4px;
}


/* ── The three-column information row ───────────────────────────────────── */

.hh-metro-band__cols {
	display: grid;
	gap: 28px;
	margin-top: 10px;
	padding-top: 26px;
	border-top: 1px solid var(--hh-metro-border);
}

.hh-metro-col {
	min-width: 0;
}

.hh-metro-col__title {
	margin: 0 0 12px;
	font-family: var(--hh-metro-sans);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.14em;
	line-height: 1.4;
	text-transform: uppercase;
	color: var(--hh-metro-heading);
}

.hh-metro-col__text {
	margin: 0;
	font-size: 15px;
	line-height: 1.7;
	color: var(--hh-metro-text);
	max-width: 46ch;
}

.hh-metro-col__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.hh-metro-col__item {
	margin: 0 0 7px;
	padding: 0 0 0 16px;
	position: relative;
	font-size: 15px;
	line-height: 1.55;
	color: var(--hh-metro-text);
	list-style: none;
}

.hh-metro-col__item::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.62em;
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--hh-metro-action);
}

.hh-metro-col__item:last-child {
	margin-bottom: 0;
}


/* ==========================================================================
   BUTTONS
   Geometry and weight match the community page's .hh-comm-btn so the two
   pages read as one system; colours come from the approved palette.
   ========================================================================== */

.hh-metro-btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 13px 26px;
	border-radius: var(--hh-metro-radius-pill);
	font-family: var(--hh-metro-sans);
	font-size: 12px;
	font-weight: 700;
	letter-spacing: 0.06em;
	line-height: 1.2;
	text-transform: uppercase;
	text-decoration: none;
	transition: background-color 0.2s, color 0.2s, border-color 0.2s;
}

.hh-metro .hh-metro-btn--solid,
.hh-metro .hh-metro-btn--solid:visited {
	background: var(--hh-metro-action);
	border: 2px solid var(--hh-metro-action);
	color: var(--hh-metro-action-fg);
}

.hh-metro .hh-metro-btn--solid:hover,
.hh-metro .hh-metro-btn--solid:focus {
	background: var(--hh-metro-action-active);
	border-color: var(--hh-metro-action-active);
	color: var(--hh-metro-action-fg);
	text-decoration: none;
}

.hh-metro .hh-metro-btn--ghost,
.hh-metro .hh-metro-btn--ghost:visited {
	background: transparent;
	border: 2px solid var(--hh-metro-action-active);
	color: var(--hh-metro-action-active);
}

.hh-metro .hh-metro-btn--ghost:hover,
.hh-metro .hh-metro-btn--ghost:focus {
	background: var(--hh-metro-subtle);
	border-color: var(--hh-metro-action-active);
	color: var(--hh-metro-action-active);
	text-decoration: none;
}

.hh-metro-btn__arrow {
	transition: transform 0.2s;
}

.hh-metro-btn--solid:hover .hh-metro-btn__arrow {
	transform: translateX(3px);
}


/* ==========================================================================
   EMPTY METRO
   ========================================================================== */

.hh-metro-empty {
	max-width: var(--hh-metro-max);
	margin: clamp(40px, 5vw, 72px) auto 0;
	padding: 44px var(--hh-metro-gutter);
	border-top: 1px solid var(--hh-metro-border);
}

.hh-metro-empty__text {
	margin: 0;
	font-size: 16px;
	line-height: 1.7;
	color: var(--hh-metro-muted);
}

.hh-metro .hh-metro-empty__link,
.hh-metro .hh-metro-empty__link:hover,
.hh-metro .hh-metro-empty__link:focus {
	color: var(--hh-metro-action-active);
	text-decoration: underline;
	text-underline-offset: 3px;
}


/* ==========================================================================
   FOCUS
   The community page has essentially no focus styling; this page does not
   copy that. Pattern follows assets/css/hh-debt-buster.css.
   ========================================================================== */

.hh-metro :is(a, button):focus-visible {
	outline: 2px solid var(--hh-metro-focus);
	outline-offset: 3px;
	border-radius: 2px;
}


/* ==========================================================================
   RESPONSIVE

   Mobile DOM order is the rendered order:
     name → city/state → price/availability → About → Highlights → Schools → CTAs
   Desktop reorders the three columns to About | Schools | Highlights.
   ========================================================================== */

@media (min-width: 769px) {

	.hh-metro-band__cols {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 36px;
	}

	.hh-metro-col--about      { order: 1; }
	.hh-metro-col--schools    { order: 2; }
	.hh-metro-col--highlights { order: 3; }
}

@media (min-width: 1025px) {

	.hh-metro-band__inner {
		grid-template-columns: minmax(0, 1fr) auto;
		grid-template-areas:
			"ident   actions"
			"facts   actions"
			"cols    cols";
		column-gap: 40px;
	}

	.hh-metro-band__actions {
		align-self: center;
		justify-self: end;
		margin-top: 0;
	}

	.hh-metro-band__cols {
		margin-top: 22px;
		padding-top: 32px;
	}
}

@media (max-width: 768px) {

	.hh-metro {
		--hh-metro-gutter: 16px;

		/* A stronger wash on small screens: the band content occupies the
		   full width there, so more of it sits over the busiest part of the
		   photograph. */
		--hh-metro-wash-strong: rgb(245 240 232 / 96%);
		--hh-metro-wash:        rgb(245 240 232 / 93%);
		--hh-metro-wash-soft:   rgb(245 240 232 / 92%);
	}

	/* Copy runs the full width on a phone, so the directional reveal has
	   nowhere to go — flatten it to a near-solid wash and let the photograph
	   be texture. Readability wins here, per the brief. */
	.hh-metro-hero__scrim {
		background:
			linear-gradient(180deg,
				rgb(245 240 232 / 0%)  62%,
				rgb(245 240 232 / 38%) 100%),
			linear-gradient(90deg,
				rgb(245 240 232 / 96%)  0%,
				rgb(245 240 232 / 93%) 100%);
	}

	.hh-metro-hero__img {
		object-position: center;
	}

	/* Three cells still, value over label. The values are the first visual
	   item in each reversed column, so they align on one line without needing
	   space-between. */
	.hh-metro-stats {
		padding: 24px 14px;
	}

	.hh-metro-stats__item {
		padding: 0 12px;
	}

	.hh-metro-stats__label {
		margin-top: 8px;
		font-size: 10px;
		letter-spacing: 0.1em;
	}

	.hh-metro-stats__value {
		font-size: clamp(22px, 5.6vw, 30px);
	}

	/* The index becomes a stacked list with a rule per row — the horizontal
	   arrangement would put three serif names on one cramped line. */
	.hh-metro-jump__list {
		flex-direction: column;
		gap: 0;
	}

	.hh-metro-jump__item {
		border-bottom: 1px solid var(--hh-metro-border);
	}

	.hh-metro-jump__link {
		display: flex;
		width: 100%;
		padding: 14px 0 13px;
		border-bottom: 0;
	}

	.hh-metro .hh-metro-jump__link:hover,
	.hh-metro .hh-metro-jump__link:focus {
		border-bottom-color: transparent;
	}

	.hh-metro-band__cols {
		gap: 26px;
	}

	.hh-metro-band__actions {
		flex-direction: column;
		align-items: stretch;
	}

	.hh-metro-btn {
		justify-content: center;
	}
}

@media (max-width: 420px) {

	.hh-metro-stats {
		padding: 20px 10px;
	}

	.hh-metro-stats__item {
		padding: 0 8px;
	}

	.hh-metro-stats__label {
		letter-spacing: 0.06em;
	}
}


/* ==========================================================================
   MOTION

   Two animations, and both of them are gated on the .hh-metro-motion class
   that hh_metro_motion_class() in inc/hh-metro-hub.php writes onto <html>
   from the head. Nothing in this section applies without it, and that state
   — everything visible, nothing moving — is the correct one for a visitor
   with no JavaScript, no IntersectionObserver, or reduced motion set.

   The gate has to be written from the head. A stylesheet cannot ask whether
   scripting is available, and this page's script is deferred and in the
   footer, so a class added by the script itself would land after the first
   paint: the community bands would render normally and then vanish.

   TUNING. Both animations are shaped entirely by the custom properties
   immediately below — distance, duration and easing for each. The only
   knobs left in assets/js/hh-metro-hub.js are the two IntersectionObserver
   triggers, because a threshold is not something a stylesheet can express.
   ========================================================================== */

/* A second .hh-metro block, on purpose: each reveal's shape belongs with the
   rules it drives rather than three hundred lines away in the token list. */
.hh-metro {

	/* ── Stats strip ──────────────────────────────────────────────────
	   How far left the bar starts, and how it settles.

	   DISTANCE has to be read against the width of the thing moving, not
	   in the abstract. 70px looked reasonable written down and was almost
	   invisible in motion: on a 1900px screen the bar is most of the
	   viewport wide, so seventy pixels is under 4% of it and the eye
	   registers the fade instead of the travel. 200px is about an eighth,
	   which is far enough to read unmistakably as a slide while the bar is
	   still plainly associated with where it is going to end up.

	   THE CURVE is the other half of that problem, and was the larger
	   half. cubic-bezier(0.16, 1, 0.3, 1) spends roughly three quarters
	   of its distance in its first quarter: by the time the movement had
	   been noticed it was effectively over, and the remaining 600ms was a
	   settle nobody could see. The curve below is CSS's own `ease` written
	   out — gentle at both ends, unhurried across the middle — so the
	   travel stays visible for most of the duration.

	   Nothing here overshoots, so it never bounces.

	   DURATION has to outrun distance, not merely keep up with it. Speed is
	   the quotient of the two, so lengthening the travel while holding the
	   clock makes the motion faster, not slower — 200px in the old 1150ms
	   would have read as a quicker slide than 160px did. The duration below
	   is up by a larger proportion than the distance, which is what buys an
	   actual slowdown. The curve is unchanged, so speed scales cleanly with
	   the quotient: every equivalent point on the ramp is 10% slower than
	   the 160px/1150ms it replaces, and the fastest instant — mid-curve,
	   where the eye is tracking it — drops from 318px/s to 286px/s while
	   the distance covered goes up by a quarter.

	   THE FADE finishes first on purpose, and by a wide margin: the bar is
	   solid for the last 650ms, so the closing stretch reads as an opaque
	   slab coming to rest rather than as something fading in. */
	--hh-metro-stats-slide: 200px;
	--hh-metro-stats-time:  1600ms;
	--hh-metro-stats-fade:  950ms;
	--hh-metro-stats-ease:  cubic-bezier(0.25, 0.1, 0.25, 1);

	/* ── Community bands ──────────────────────────────────────────── */
	--hh-metro-reveal-rise: 28px;
	--hh-metro-reveal-time: 700ms;
	--hh-metro-reveal-zoom: 1.02;
	--hh-metro-reveal-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
}

/* The distance scales with the bar, because what the eye reads is the
   proportion rather than the pixels: 200px against a full-bleed desktop
   strip, 140px against a contained tablet one, 70px on a phone, where the
   bar has a gutter on both sides and a longer move would start to read as a
   swipe rather than a settle.

   Both are max-width queries and the narrower one is second, so on a phone
   it is the phone value that survives the cascade. */
@media (max-width: 1024px) {

	.hh-metro {
		--hh-metro-stats-slide: 140px;
	}
}

@media (max-width: 768px) {

	.hh-metro {
		--hh-metro-stats-slide: 70px;
	}
}


/* ── Stats strip ─────────────────────────────────────────────────────────
   A ONE-TIME ENTRANCE. The Deep Green bar starts a little left of where the
   layout puts it, and transparent. The first time it enters the viewport it
   fades and slides into place — and stays there. It is never moved again:
   no scroll-linked motion, no exit, no replay on the way back up. The
   finished state is exactly the layout position, so the composition at rest
   is identical with the motion on or off.

   .hh-metro-hero__stats is the clipped viewport and never moves; the bar
   inside it is the only thing that travels. The clip hides the part of the
   bar that sits outside the layout box at the start of the entrance, which
   is why a leftward start cannot turn into visible overflow or a horizontal
   scrollbar. It costs nothing vertically: the strip has no top or bottom
   padding and the bar is its only child, so the padding box and the bar are
   exactly the same height and the hero/stats seam below is untouched.

   No will-change. This runs once, so the browser's own promotion for the
   duration of a transition is exactly the right lifetime — and when it drops
   that layer afterwards the labels get their subpixel anti-aliasing back,
   which a permanent promotion would have cost for the whole session. */
.hh-metro-motion .hh-metro-hero__stats {
	overflow: hidden;
}

.hh-metro-motion .hh-metro-stats {
	opacity: 0;
	transform: translate3d(calc(var(--hh-metro-stats-slide) * -1), 0, 0);
	transition:
		opacity   var(--hh-metro-stats-fade) ease-out,
		transform var(--hh-metro-stats-time) var(--hh-metro-stats-ease);
}

/* Added once, by IntersectionObserver, which unobserves the bar in the same
   breath. Nothing ever takes it off again. */
.hh-metro-motion .hh-metro-stats.is-revealed {
	opacity: 1;
	transform: none;
}


/* ── Community bands ─────────────────────────────────────────────────────
   One composition, not a stagger: the whole band fades and rises as a single
   element, with its photograph settling out of a 2% scale at the same time.
   Nothing inside the band is animated separately, so the heading, the price,
   the three columns and the buttons all arrive together.

   .is-revealed is added once, by IntersectionObserver, and the band is
   unobserved in the same breath — scrolling back up cannot replay it.

   No will-change on these: they are full-width and several viewports tall
   between them, and the browser promotes a transitioning transform on its
   own. Holding three layers that size for the whole session is the more
   expensive mistake. */
.hh-metro-motion .hh-metro-band {
	opacity: 0;
	transform: translate3d(0, var(--hh-metro-reveal-rise), 0);
	transition:
		opacity   var(--hh-metro-reveal-time) var(--hh-metro-reveal-ease),
		transform var(--hh-metro-reveal-time) var(--hh-metro-reveal-ease);
}

.hh-metro-motion .hh-metro-band.is-revealed {
	opacity: 1;
	transform: none;
}

/* .hh-metro-band__backdrop already clips, so the 2% never escapes the band.
   A little longer than the rise so the picture is still settling as the copy
   lands — concurrent, but not lockstep. */
.hh-metro-motion .hh-metro-band__img {
	transform: scale(var(--hh-metro-reveal-zoom));
	transition: transform calc(var(--hh-metro-reveal-time) + 200ms) var(--hh-metro-reveal-ease);
}

.hh-metro-motion .hh-metro-band.is-revealed .hh-metro-band__img {
	transform: none;
}


/* ==========================================================================
   REDUCED MOTION

   The preference is honoured before any of this loads: the head snippet does
   not write .hh-metro-motion when it is set, so the MOTION section above
   never applies and the script never starts. What follows covers the visitor
   who turns the preference on with the page already open, plus the hover
   affordances the hub has always had.

   Both entrances are plain class-driven CSS now — the script writes no
   inline styles at all — so both can simply be flattened here.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

	.hh-metro-btn,
	.hh-metro-btn__arrow,
	.hh-metro-jump__link {
		transition: none;
	}

	.hh-metro-btn--solid:hover .hh-metro-btn__arrow {
		transform: none;
	}

	.hh-metro-motion .hh-metro-stats,
	.hh-metro-motion .hh-metro-stats.is-revealed,
	.hh-metro-motion .hh-metro-band,
	.hh-metro-motion .hh-metro-band.is-revealed,
	.hh-metro-motion .hh-metro-band__img {
		opacity: 1;
		transform: none;
		transition: none;
	}
}
