/*
Theme Name: Mulberry Health
Description: Bespoke GeneratePress child theme for Mulberry Health — in-home medical care, Arizona. Design is client-specific (no shared house style).
Author: Ted Slater
Template: generatepress
Version: 0.1.0
Requires PHP: 8.0
Text Domain: mulberry-health
*/

/* =========================================================================
   DESIGN TOKENS  — client-specific, sourced from the Mulberry Health mockup.
   When cloning this theme for another client, replace this whole block.
   ========================================================================= */
:root {
	/* Color */
	--mh-ink:    #2C312B; /* primary text — warm near-black */
	--mh-paper:  #FCFBF7; /* page background — cream */
	--mh-forest: #2C3E36; /* header bar, hero overlay, primary button */
	--mh-sage:   #637061; /* muted green — secondary text */
	--mh-olive:  #B8B665; /* accent — Register pill, highlights */
	--mh-sand:   #DEDBD3; /* borders, dividers */
	--mh-white:  #FFFFFF;

	/* Type families */
	--mh-font-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;
	--mh-font-body:    "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
	/* The logotype face. Was the client's Brice Expanded; since 2026-08-07 both
	   logotypes are the SVG lockup and the only things still reading this are
	   the fallback text wordmarks, which are hidden (header) and font-size:0
	   (footer). Kept as its own token rather than collapsed into
	   --mh-font-display so restoring a text logotype stays a one-line change. */
	--mh-font-logo:    "Cormorant Garamond", Georgia, serif;

	/* Type scale */
	--mh-fs-base: 1.125rem;                    /* 18px */
	--mh-fs-h1:   clamp(2.75rem, 6vw, 4.5rem); /* ~44–72px */
	--mh-fs-h2:   clamp(2rem, 4vw, 3rem);
	--mh-fs-h3:   1.5rem;

	/* NOTE: --mh-hero-image is NOT declared here.
	   A relative url() in a custom property resolves against the *document*,
	   not this stylesheet, because GenerateBlocks injects its CSS inline into
	   the page — so "assets/img/hero.jpg" 404s as /assets/img/hero.jpg.
	   functions.php emits the variable with a runtime-generated absolute URL,
	   which is both correct and portable across domains. */

	/* Rhythm & shape.
	   Only the pill radius earns a token — cards are 2rem in the GB per-block
	   styles throughout. --mh-radius-card/-maxw/-gutter/-section-y were
	   removed 2026-08-04: never referenced, and radius-card (14px) actively
	   contradicted the real card radius, inviting a wrong "fix". */
	--mh-radius-pill: 9999px;
}

/* =========================================================================
   BASE
   ========================================================================= */

/* scroll-padding-top is the load-bearing half of this rule. The site header is
   position: fixed, so it occupies no space in the flow — without this, every
   anchor jump (GP's "Skip to content" included) lands the target UNDERNEATH
   the header. 7rem clears the ~101px bar with room to spare.

   Smooth scrolling is gated on prefers-reduced-motion: it's motion the user
   didn't ask for, and animated scrolling is a common vestibular trigger. The
   rest of this stylesheet already honours that setting.

   Font smoothing is actively reset to auto below — not merely "not set".
   GeneratePress sets -webkit-font-smoothing:antialiased on html in its own
   stylesheet, which on macOS renders text THINNER. This site's audience is
   seniors, and the type is already light (Cormorant at 300 for headings,
   Inter at 300 in the nav) — thinning it further is the wrong direction.
   (An earlier comment here claimed omission was enough; it wasn't — GP's
   rule applied regardless. Found in the 2026-08-04 review.) */
html {
	scroll-padding-top: 7rem;
	-webkit-font-smoothing: auto;
	-moz-osx-font-smoothing: auto;
}
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

body {
	background-color: var(--mh-paper);
	color: var(--mh-ink);
	font-family: var(--mh-font-body);
	font-size: var(--mh-fs-base);
	line-height: 1.6;
}

h1, h2, h3 {
	font-family: var(--mh-font-display);
	font-weight: 300;
	color: var(--mh-ink);
	line-height: 1.05;
}
h1 { font-size: var(--mh-fs-h1); }
h2 { font-size: var(--mh-fs-h2); }
h3 { font-size: var(--mh-fs-h3); font-weight: 400; }

a { color: var(--mh-forest); }

/* NOTE: component styling (eyebrows, pill buttons, cards, section padding)
   deliberately lives in GenerateBlocks, not here — see CLAUDE.md "Styling
   ownership". This file stays the design-system layer: tokens, base
   typography, and fonts. Add a rule here only when it must apply site-wide
   and can't be expressed per-block. */

/* =========================================================================
   FONTS  — self-hosted (latin subset, variable weight axis), downloaded from
   Google Fonts 2026-08-02. Both are SIL Open Font License 1.1.
   Weight ranges below match each font's real variable axis; declaring a range
   the file doesn't have makes the browser synthesise weights instead.
   ========================================================================= */
@font-face {
	font-family: "Cormorant Garamond";
	font-style: normal;
	font-weight: 300 700;
	font-display: swap;
	src: url("assets/fonts/cormorant-garamond-var.woff2") format("woff2");
}
@font-face {
	font-family: "Cormorant Garamond";
	font-style: italic;
	font-weight: 300 700;
	font-display: swap;
	src: url("assets/fonts/cormorant-garamond-italic-var.woff2") format("woff2");
}
@font-face {
	font-family: "Inter";
	font-style: normal;
	font-weight: 100 900;
	font-display: swap;
	src: url("assets/fonts/inter-var.woff2") format("woff2");
}
/* NO @font-face for Brice — deliberate, retired 2026-08-07 (Ted).
   The brand face was licensed and self-hosted on 2026-08-06 to set the text
   logotype. The client then replaced both logotypes with their own horizontal
   SVG lockup, and that file is served with the wordmark converted to OUTLINES
   (see the --mh-logo-h note in functions.php) — so the face has no remaining
   consumer and loading it was 29KB of preloaded dead weight on every page.

   assets/fonts/brice-expanded.woff2 and the supplied Brice-RegularExpanded.otf
   are still on disk. The .otf is the client's licensed source and is what the
   outlined SVG was generated from, so keep it; the .woff2 is derived and can be
   regenerated from it at any time. Restoring the text logotype means putting
   this @font-face back, re-adding the preload, and re-measuring every width
   figure marked "in Brice" below — the fallback serif sets far narrower. */

/* Pages run edge-to-edge: the PHP side drops GP's max-width container
   (functions.php, 'generate_page_class'); this drops the padding GP's
   one-container mode adds. Posts and archives keep GP's normal spacing. */
body.page .site-content {
	padding: 0;
}

/* =========================================================================
   SITE HEADER
   GeneratePress renders the header and nav (so the menu stays editable in
   Appearance → Menus and GP's sticky-nav module keeps working); this styles
   GP's own markup to the mockup. The footer is NOT here — it's the "Site
   Footer" GP Block Element. See CLAUDE.md.
   ========================================================================= */
/* Fixed, not sticky, on every page: the header floats over the first section
   so its dark translucent state can sit on top of the hero.
   NOTE this means the header takes NO space in the flow — every page's first
   section must carry enough top padding to clear it. The homepage hero does by
   design; inner-page heroes get it from .mh-hero-dark. A new template without a
   full-bleed hero would need its own top padding. */
.site-header {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 100;
	background-color: rgba(253, 251, 247, 0.95);
	-webkit-backdrop-filter: blur(12px);
	backdrop-filter: blur(12px);
	border-bottom: 1px solid rgba(184, 182, 101, 0.2);
}

/* The WP admin bar is fixed for logged-in users — offset the sticky header so
   it doesn't hide behind it. 782px is WP's own admin-bar breakpoint. */
.admin-bar .site-header { top: 32px; }
@media (max-width: 782px) {
	.admin-bar .site-header { top: 46px; }
}

.site-header .inside-header {
	padding-block: 1rem;
	/* Matches the 1600px content measure (.mh-wide). Left at GP's default 1200
	   the nav ran out of room and the CTA wrapped onto its own line. */
	max-width: 1600px;
}

/* Brand lockup: tree mark beside the wordmark, as in the mockup. */
.site-branding,
.site-header .site-logo {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}
/* The client's horizontal lockup (2026-08-07) is 1376 x 372 — a 3.70:1 ratio
   against the old mark's 0.84:1. At the previous 42px height it would have
   been only ~155px wide and the wordmark inside it unreadable, so the logo is
   sized by HEIGHT to keep the type legible and the header's 100px bar intact.
   56px puts the cap-height of "MULBERRY" at roughly the size the old Brice
   wordmark set beside it, so the header reads at the same weight as before. */
.site-header .site-logo img,
.site-header img.header-image {
	width: auto;
	height: 56px;
	max-height: 56px;
}

/* The lockup already contains the wordmark, so GP's separate text title would
   repeat it — visually AND in the accessibility tree, since the logo <img>
   carries alt="Mulberry Health". `display: none` removes both. The markup is
   left in place rather than filtered away so the title is one line from coming
   back if the client ever reverts to a mark-only logo.
   This retired the Brice text wordmark; the face itself was dropped from the
   build on 2026-08-07 once nothing was left rendering in it. */
.site-header .site-branding {
	display: none;
}

/* Reversed logo for the transparent header over the hero.
   The mark's trunk and roots are sage (#637262), almost identical in value to
   the dark header (#2C3E36) — at the real 42px the full-colour logo loses its
   whole trunk and reads as scattered specks. This was a flat white silhouette
   (brightness(0) invert(1)) until 2026-08-03; it is now the proper reversed
   variant, which recolours ONLY the trunk to #e6f1e8 — a colour already in the
   mark's own palette — and keeps every leaf colour.

   Swapped with a background-image on the anchor rather than the `content`
   property: `content` on a replaced element only became reliable in Firefox in
   2023, and its failure mode here would be the unreadable full-colour mark.
   The <img> is faded to opacity 0 rather than hidden so it stays in the
   accessibility tree, and it still sizes the anchor. The two selectors are
   deliberately paired — any logo image NOT inside .site-logo a keeps its normal
   full-colour rendering rather than becoming invisible. */
.site-header.mh-at-top .site-logo a {
	display: inline-block;
	background-image: var(--mh-logo-h-light);
	background-repeat: no-repeat;
	background-position: center;
	background-size: contain;
}
.site-header.mh-at-top .site-logo a img {
	opacity: 0;
}

/* Wordmark — nowrap so "Mulberry Health" stays on one line next to the nav.
   ⚠️ CURRENTLY UNRENDERED: .site-header .site-branding is display:none (the SVG
   lockup carries the wordmark), so nothing here paints. It is kept as the
   revert path for a text logotype. Every size below was measured with Brice
   Expanded, which is no longer loaded and sets much wider than the fallback
   serif — RE-MEASURE, don't trust these numbers, if the text ever comes back. */
.site-branding .main-title,
.site-branding .main-title a {
	font-family: var(--mh-font-logo);
	font-size: 1.25rem;
	/* Close the gap so the wordmark reads as one lockup — the italic already
	   separates "Health". Done with word-spacing rather than by deleting the
	   space in the PHP filter, ON PURPOSE: the space stays in the DOM, so the
	   accessible name and the <title> tag still read "Mulberry Health" rather
	   than "MulberryHealth". -0.304em was the space glyph's exact advance in
	   Brice (304/1000 upem) — with Brice gone this no longer cancels the space
	   precisely, which is harmless while the wordmark is hidden but is one more
	   thing to re-measure if it is ever restored. */
	word-spacing: -0.304em;
	font-weight: 400;
	line-height: 1.1;
	white-space: nowrap;
	color: var(--mh-ink);
	text-decoration: none;
}

/* Give the nav room: the menu has six top-level items plus a CTA. */
.site-header .inside-header {
	gap: 1.5rem;
}
.main-navigation .main-nav > ul > li > a {
	padding-left: 0.5rem;
	padding-right: 0.5rem;
}

/* The brand lockup plus six nav items plus a CTA is a lot of horizontal
   real estate — let the nav wrap to its own row before it overflows rather
   than colliding with the logo. */
@media (max-width: 1100px) {
	.site-header .inside-header {
		flex-wrap: wrap;
		row-gap: 0.5rem;
	}
}

/* GP gives the nav its own background; clear it so the header's cream and
   blur show through as one surface. Submenus still need an opaque panel. */
.main-navigation,
.main-navigation .inside-navigation {
	background-color: transparent;
}
/* Dropdown panel, restyled to the mockup's card: cream, 1rem radius, real
   shadow, breathing room, 280px floor. GP positions these absolutely under
   the item; only the skin changes here. The items get generous padding and a
   faint sage wash on hover; "View All Services" (injected in functions.php)
   draws the hairline divider the mockup puts above it. */
.main-navigation .main-nav ul ul {
	background-color: var(--mh-paper);
	border: 1px solid rgba(222, 219, 211, 0.7);
	border-radius: 16px;
	box-shadow:
		0 20px 25px -5px rgba(0, 0, 0, 0.1),
		0 8px 10px -6px rgba(0, 0, 0, 0.1);
	padding: 0.75rem 0;
	width: 280px;
}
.main-navigation .main-nav ul ul li a {
	padding: 0.65rem 1.5rem;
	font-family: var(--mh-font-body);
	font-size: 0.9375rem;
	color: var(--mh-ink);
	line-height: 1.4;
	transition: background-color 0.2s ease, color 0.2s ease;
}
.main-navigation .main-nav ul ul li a:hover,
.main-navigation .main-nav ul ul li a:focus {
	background-color: rgba(99, 112, 97, 0.05);
	color: var(--mh-forest);
}
.main-navigation .main-nav ul ul li.mh-view-all {
	margin-top: 0.5rem;
	border-top: 1px solid rgba(222, 219, 211, 0.7);
	padding-top: 0.5rem;
}
.main-navigation .main-nav ul ul li.mh-view-all a {
	color: var(--mh-sage);
	font-weight: 600;
}

/* Primary nav links */
.main-navigation .main-nav > ul > li > a {
	font-family: var(--mh-font-body);
	font-size: 0.75rem;
	font-weight: 300;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: rgba(44, 49, 43, 0.7);
}
/* current-menu-ancestor/-parent matter as much as -item: on the service child
   pages WordPress marks the "Services" parent with those classes only, and
   without them GeneratePress's default accent blue (#1e73be) showed through. */
.main-navigation .main-nav > ul > li > a:hover,
.main-navigation .main-nav > ul > li.current-menu-item > a,
.main-navigation .main-nav > ul > li.current-menu-ancestor > a,
.main-navigation .main-nav > ul > li.current-menu-parent > a {
	color: var(--mh-forest);
}

/* --- Scroll-reactive header (all pages) --------------------------------
   The solid cream treatment above is the DEFAULT and the no-JS fallback.
   assets/js/header.js adds .mh-at-top while scrolled to the top, which
   swaps in the mockup's dark translucent bar over the hero.

   This used to be front-page only, because inner pages opened on a cream hero
   where a dark bar failed contrast. Inner heroes are now dark green
   (.mh-hero-dark), so the treatment applies site-wide. If a page is ever given
   a light hero again, the dark bar will be unreadable over it. ------------ */
.site-header,
.site-header .main-title,
.site-header .main-title a,
.main-navigation .main-nav > ul > li > a {
	transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}

@media (prefers-reduced-motion: reduce) {
	.site-header,
	.site-header .main-title,
	.site-header .main-title a,
	.main-navigation .main-nav > ul > li > a {
		transition: none;
	}
}

.site-header.mh-at-top {
	background-color: rgba(44, 62, 54, 0.8);
	border-bottom-color: transparent;
}

/* Cream on the blended dark bar measures ~6:1 against the hero behind it,
   comfortably past WCAG AA for body text. */
.site-header.mh-at-top .site-branding .main-title,
.site-header.mh-at-top .site-branding .main-title a,
.site-header.mh-at-top .main-navigation .main-nav > ul > li > a {
	color: var(--mh-paper);
}
.site-header.mh-at-top .main-navigation .main-nav > ul > li > a:hover,
.site-header.mh-at-top .main-navigation .main-nav > ul > li.current-menu-item > a,
.site-header.mh-at-top .main-navigation .main-nav > ul > li.current-menu-ancestor > a,
.site-header.mh-at-top .main-navigation .main-nav > ul > li.current-menu-parent > a {
	color: var(--mh-white);
}

/* Opt-in nav CTA: add the class "mh-nav-cta" to a menu item
   (Appearance → Menus → Screen Options → CSS Classes) to render it as the
   mockup's pill button. Geometry only — fills, type and the layered ring are
   state-dependent and live in ONE place, the MOCKUP PARITY block. (This used
   to be a second full styling block; the two drifted and most of this one was
   silently dead. Do not re-introduce colour here.) */
.main-navigation .main-nav > ul > li.mh-nav-cta > a {
	/* Roomier left margin than the other items so the 4px ring (see MOCKUP
	   PARITY) doesn't crowd the preceding link. */
	margin-left: 1.25rem;
	padding: 14px 32px;
	border-radius: var(--mh-radius-pill);
}

/* =========================================================================
   MOTION + COMPONENT UTILITIES
   GenerateBlocks owns per-section styling, but these are cross-cutting and
   involve things GB can't express per-block: JS-coordinated reveal states,
   backdrop-filter, hover transitions, and inline-SVG defaults. Applied to
   blocks via GB's `globalClasses` attribute (NOT htmlAttributes.class, which
   emits a second class attribute that browsers discard).
   ========================================================================= */

/* --- Reveal on scroll ---------------------------------------------------
   Hiding is gated on .mh-js, set inline in <head>. If the script never runs,
   nothing is hidden — the mockup blanks whole sections when its animation
   library fails, and that is the failure being designed out. */
.mh-js .mh-reveal {
	opacity: 0;
	transform: translateY(30px);
	transition:
		opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
		transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
	transition-delay: var(--mh-reveal-delay, 0ms);
}
.mh-js .mh-reveal.is-visible {
	opacity: 1;
	transform: none;
}

/* Cards that are BOTH a reveal target and a hover card.
   `.mh-js .mh-reveal` (0,2,0) outranks `.mh-card-hover` (0,1,0), and it lists
   only opacity + transform — so a hover that changes border-colour and
   box-shadow got NO transition and snapped instantly. Both properties have to
   be named here, at the winning specificity.
   The per-property transition-delay is deliberate: the stagger delay must
   apply to the reveal only. Shared, a card with a 360ms reveal delay would
   also sit 360ms before responding to the pointer. */
.mh-js .mh-reveal.mh-card-hover {
	transition:
		opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
		transform 0.5s cubic-bezier(0.4, 0, 0.2, 1),
		border-color 0.5s cubic-bezier(0.4, 0, 0.2, 1),
		box-shadow 0.5s cubic-bezier(0.4, 0, 0.2, 1);
	transition-delay: var(--mh-reveal-delay, 0ms), var(--mh-reveal-delay, 0ms), 0ms, 0ms;
}

@media (prefers-reduced-motion: reduce) {
	.mh-js .mh-reveal,
	.mh-js .mh-reveal.is-visible,
	.mh-js .mh-reveal.mh-card-hover {
		opacity: 1;
		transform: none;
		transition: none;
	}
}

/* --- Small-screen grid guard --------------------------------------------
   GenerateBlocks writes these grids as `repeat(auto-fit, minmax(480px, 1fr))`.
   auto-fit collapses to ONE column on a narrow screen but it cannot shrink
   that column below the 480px minimum — so on a 360px phone the grid forced
   the document to 505px and the whole homepage scrolled sideways. Verified
   2026-08-03 with a 375px iframe harness; nothing else on the site overflowed.

   Forcing a single 0-min column below 640px fixes it for every grid we own,
   whatever minmax value GB happens to have written.

   ⚠️ .mh-feature-grid is NOT in this list, on purpose: its 2-column 1024px
   rule lives LATER in the file and would win the equal-specificity tie, so
   its single-column collapse must also live later — beside its other rules.
   (Removing that "duplicate" broke the benefits grids back to 2-up on phones
   on 2026-08-04; order is load-bearing here.) */
@media (max-width: 640px) {
	.entry-content .mh-stagger {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* --- Frosted stats card, lifted over the hero --------------------------- */
.mh-glass-card {
	background-color: rgba(255, 255, 255, 0.8);
	-webkit-backdrop-filter: blur(24px);
	backdrop-filter: blur(24px);
	border: 1px solid rgba(222, 219, 211, 0.5);
	border-radius: 2rem;
	box-shadow:
		0 20px 25px -5px rgba(0, 0, 0, 0.1),
		0 8px 10px -6px rgba(0, 0, 0, 0.1);
}
.mh-overlap {
	position: relative;
	z-index: 20;
	margin-top: -48px;
}

/* --- Inline icons ------------------------------------------------------- */
.gb-shape svg {
	display: block;
	width: 100%;
	height: 100%;
	fill: none;
	stroke: currentColor;
	stroke-width: 2;
	stroke-linecap: round;
	stroke-linejoin: round;
}
.mh-icon-badge {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 64px;
	height: 64px;
	margin: 0 auto 1.25rem;
	border-radius: 9999px;
	background-color: rgba(184, 182, 101, 0.1);
	color: var(--mh-olive);
}
.mh-icon-badge .gb-shape { width: 28px; height: 28px; }

.mh-icon-box {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin-bottom: 1.25rem;
	border-radius: 16px;
	background-color: rgba(99, 112, 97, 0.05);
	color: var(--mh-sage);
}
.mh-icon-box .gb-shape { width: 24px; height: 24px; }

/* Homepage service-line cards put the icon LEFT of the text in the mockup
   ("flex items-start gap-5"), not stacked above it. Grid, not flex, because
   the icon-box/h3/p/link are four siblings with no text wrapper — the icon
   spans the three text rows. Desktop-and-up only; on phones the stacked
   layout keeps the text column wide (2026-08-04). */
@media (min-width: 641px) {
	.entry-content .mh-card-hover:has(> .mh-icon-box) {
		display: grid;
		grid-template-columns: auto minmax(0, 1fr);
		column-gap: 1.25rem;
		align-items: start;
	}
	.entry-content .mh-card-hover > .mh-icon-box {
		grid-row: 1 / span 3;
		margin-bottom: 0;
	}
}

.mh-stat-icon {
	display: flex;
	justify-content: center;
	margin-bottom: 0.85rem;
	color: var(--mh-olive);
}
.mh-stat-icon .gb-shape { width: 24px; height: 24px; }

/* --- Card lift on hover -------------------------------------------------- */
.mh-card-hover {
	transition:
		border-color 0.5s ease,
		box-shadow 0.5s ease,
		transform 0.5s ease;
}
.mh-card-hover:hover {
	border-color: rgba(184, 182, 101, 0.4);
	box-shadow:
		0 20px 25px -5px rgba(0, 0, 0, 0.08),
		0 8px 10px -6px rgba(0, 0, 0, 0.06);
	transform: translateY(-3px);
}
@media (prefers-reduced-motion: reduce) {
	.mh-card-hover,
	.mh-card-hover:hover {
		transition: none;
		transform: none;
	}
}

/* --- "Learn More" card link ---------------------------------------------
 * The arrow is a pseudo-element rather than markup so it never lands in the
 * accessible name — screen readers announce "Learn More", not "Learn More
 * right arrow". It slides on hover of the whole CARD, not just the link,
 * so the affordance reads while the pointer is anywhere over the card.
 */
/* Scoped .entry-content on purpose: at bare (0,1,0) this tied with GB's
   per-block rules and lost on source order — /services' "Learn More" rendered
   0.9375rem/600 while home's rendered 0.875rem/500 from this rule. (0,2,0)
   makes the utility the single source of truth for the link's type. */
.entry-content .mh-card-link {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	margin-top: 1.25rem;
	font-family: var(--mh-font-body);
	font-size: 0.875rem;
	font-weight: 500;
	letter-spacing: 0.02em;
	/* Sage, not forest — the mockup rests these on text-primary (2026-08-04;
	   5.3:1 on white, still AA). */
	color: var(--mh-sage);
	text-decoration: none;
}
.mh-card-link::after {
	content: "\2192"; /* → */
	transition: transform 0.3s ease;
}
.mh-card-hover:hover .mh-card-link {
	color: var(--mh-olive);
}
.mh-card-hover:hover .mh-card-link::after {
	transform: translateX(4px);
}
.mh-card-link:focus-visible {
	outline: 2px solid var(--mh-olive);
	outline-offset: 3px;
	border-radius: 2px;
}
@media (prefers-reduced-motion: reduce) {
	.mh-card-link::after,
	.mh-card-hover:hover .mh-card-link::after {
		transition: none;
		transform: none;
	}
}

/* --- Whole-card click targets (mockup parity, 2026-08-04) ----------------
   The mockup renders each service card as one big <Link>; ours had only the
   "Learn More" anchor navigable. A stretched pseudo-element on that anchor
   makes the entire card the tap target — markup untouched, and the card's
   pills/title need no links of their own. Scoped to cards that actually
   CONTAIN a card-link so exec/area/insurance cards stay inert. The mockup's
   group-hover follows: title, icon tile and link all warm toward olive when
   any part of the card is hovered. */
.entry-content .mh-card-hover:has(.mh-card-link) {
	position: relative;
}
.entry-content .mh-card-hover .mh-card-link::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}
.entry-content .mh-card-hover:has(.mh-card-link):hover h3 {
	color: var(--mh-olive);
}
.entry-content .mh-card-hover:has(.mh-card-link):hover .mh-icon-box {
	background-color: rgba(184, 182, 101, 0.12);
}
.entry-content .mh-card-hover:has(.mh-card-link) h3,
.entry-content .mh-icon-box {
	transition: color 0.3s ease, background-color 0.3s ease;
}

/* Benefit cards are NOT links — the mockup leaves them static, and a lift on
   a non-clickable card is a false affordance. Neutralise the mh-card-hover
   treatment there (same pattern as .mh-step). */
.entry-content .mh-feature-card.mh-card-hover:hover {
	transform: none;
	box-shadow: none;
	border-color: rgba(222, 219, 211, 0.5);
}

/* Outline buttons were hover-inert; the mockup washes them with faint sage
   (bg-primary/10). Filled buttons never match — the :not guard mirrors the
   mobile rule's. */
.entry-content .mh-btn-secondary:not(.mh-btn-primary):hover,
.entry-content .mh-btn-secondary:not(.mh-btn-primary):focus-visible {
	background-color: rgba(99, 112, 97, 0.1);
	transition: background-color 0.3s ease;
}

/* The hero headline's italic "Healthcare" is SAGE in the mockup, not ink —
   the tinted word is half the wordmark's point. Only the homepage hero h1
   carries an <em>; dark-hero h1s are plain text. */
.entry-content h1 em {
	color: var(--mh-sage);
}

/* =========================================================================
   MOCKUP PARITY
   A second pass against the base44 mockup (2026-08-03). Values here were read
   off the mockup with getComputedStyle rather than eyeballed.

   Icons are CSS masks / background images rather than inline SVG on purpose:
   they need no block markup, they inherit currentColor, and being decorative
   they stay out of the accessible name — "Register Now", not "Register Now
   right arrow". The classes are applied via GB's globalClasses.
   ========================================================================= */

/* --- Wider desktop canvas ------------------------------------------------
   The mockup's outer wrapper caps at 1600px; ours was built to 1200px.
   Two class levels of specificity so this beats GB's own .gb-element-* rule
   without resorting to !important. */
.entry-content .mh-wide,
.site-footer .mh-wide {
	max-width: 1580px;
}

/* Section headers sit in a narrower measure than the section itself, exactly
   as the mockup does — long lines are hard to read centred.
   The auto margins are load-bearing: these wrappers ship with
   margin-left/right: 0, so without them the header block sits flush left in
   the (now 1600px) section and reads as misaligned against the grid below. */
.entry-content .mh-centered {
	text-align: center;
	margin-left: auto;
	margin-right: auto;
}

/* --- Inner-page hero ----------------------------------------------------
   The mockup opens every inner page on a sage band with centred cream text.
   Applied as a class rather than by editing the blocks' own GB styles: this
   keeps GenerateBlocks' compiled CSS untouched (see the "lags one save behind"
   warning in CLAUDE.md) and makes the treatment one line to revert.

   The tall padding-top is load-bearing — the site header is position:fixed and
   occupies no space in the flow, so without it the h1 sits under the header. */
.entry-content .mh-hero-dark {
	background-color: var(--mh-sage);
	text-align: center;
	padding-top: 11rem;
	padding-bottom: 7rem;
}
/* Two classes deep so these beat GenerateBlocks' own .gb-text-* colour rules
   without !important. Every inner hero is span + h1 + p and holds no buttons,
   so plain element selectors are enough here. */
.entry-content .mh-hero-dark h1,
.entry-content .mh-hero-dark h2 {
	color: var(--mh-paper);
}
/* Auto margins matter as much as text-align here: the hero subtitle carries
   its own max-width with margin-left:0, so centring the text alone just
   centres it inside a box that is still sitting on the left. */
.entry-content .mh-hero-dark p {
	color: rgba(252, 251, 247, 0.85);
	margin-left: auto;
	margin-right: auto;
}
/* Eyebrow on the dark heroes.
   NOT --mh-olive (#B8B665): measured against the sage hero (#637061) that is
   only 2.47:1, well under WCAG AA's 4.5:1 for normal text — and at 17.5px
   regular this is normal text, not large. The mockup has the same problem;
   that does not make it right on a site whose audience is seniors.
   #EFF2DA measures 4.57:1 and still reads as a pale olive rather than plain
   cream, so the accent survives. Scoped to the dark heroes only — the full
   olive is fine on cream sections and is untouched there. */
.entry-content .mh-hero-dark > * > span,
.entry-content .mh-hero-dark > span {
	color: #eff2da;
}

/* The LIGHT-section eyebrows have the same disease: olive #B8B665 at regular
   weight is ~2.05:1 on cream — the worst text contrast on the site, on the
   labels that name every section. The mockup's own service pages set these
   in SAGE at semibold (text-primary font-semibold, ~5.0:1); its homepage
   keeps olive and fails its own standard, so sage wins site-wide — the same
   accessibility-over-mockup call as the hero eyebrows above.

   Selector: an eyebrow is exactly "a span immediately followed by a heading"
   inside a light section. Verified 2026-08-04 against all 12 rendered pages:
   28 matches, every one an eyebrow, zero false positives (STEP labels, stats,
   pills and footer headings all unmatched; dark heroes excluded and covered
   by the #EFF2DA rule above, which this must not outrank). */
.entry-content section:not(.mh-hero-dark) span.gb-text:has(+ h1, + h2) {
	color: var(--mh-sage);
	font-weight: 600;
}
/* …except inside the sage CTA card, where sage-on-sage would vanish — same
   pale-olive treatment as the dark heroes. Higher specificity than the rule
   above so order can't flip it. (Added 2026-08-05 for the /services closing
   card, which keeps its "Begin Your Journey" eyebrow.) */
.entry-content section:not(.mh-hero-dark) .mh-cta-card span.gb-text:has(+ h1, + h2) {
	color: #eff2da;
}

/* --- Homepage hero image position (Ted, 2026-08-04) ----------------------
   hero.jpg was replaced with a new photo whose subject sits differently in
   frame. GB's own block CSS (.gb-element-mhheroimg, printed inline) anchors
   the layer at inset 0 with background-position:center; these overrides
   re-crop for the new image: keyed to the right edge, pushed 100px past it
   and 100px down. Safe because the hero section (.gb-element-mhhero01) is
   overflow:hidden — the overhang is clipped, not scrollable; verified at
   360px and desktop. Lives here rather than in the editor so the tweak is
   version-controlled and survives block round-trips; (0,2,0) outranks the
   inline GB rule's (0,1,0) regardless of style order. */
.entry-content .gb-element-mhheroimg {
	/* ⚠️ Read the geometry before touching this — two different bugs came from
	   guessing at it.

	   GB gives the layer `inset: 0`, `background-size: cover` and NO
	   background-repeat (so it defaults to `repeat`). With `cover`, the only
	   room background-position has is the image's OVERFLOW past the box.
	   Measured for hero.jpg (1672x941) at real viewports:
	     1440x800 -> x overflow 0px,   y overflow 10px
	     1050x800 -> x overflow 371px, y overflow 0px
	      390x740 -> x overflow 925px, y overflow 0px
	   Vertical room is essentially ZERO everywhere; horizontal room is large.

	   So a 100px downward push is impossible to honour — it just uncovers the
	   top of the layer, which then TILES (the y-repeat seen between 769 and
	   1335px, where the 81px header stopped hiding the strip). The earlier
	   `top: 100px` form avoided that only by SHORTENING the box, which left
	   sand showing above the photo once the header shrank.

	   `right` is the part that carries real meaning — it pans within the wide
	   horizontal overflow and preserves the 2026-08-04 intent of keying the
	   crop to the right edge. The vertical keyword is honest about having
	   nowhere to go. `no-repeat` is a guard: a cover background should never
	   tile, whatever position it is given. */
	background-repeat: no-repeat;
	background-position: right center;
	/* Overhang the right edge by 100px (Ted, 2026-08-07). Lives here, not in
	   the ≤1024 band block, so it applies at EVERY width — the band inherits
	   it rather than redeclaring it.

	   ⚠️ It does something different above and below 1024, and the difference
	   is not a bug — it falls out of `background-size`:

	     ≤1024 the size is a PERCENTAGE of the box, so widening the box widens
	     the painted image too: the crop pans AND zooms (~20% at 500px).

	     >1024 the size is GB's `cover`, and the behaviour splits on the
	     viewport's ASPECT, not its width — specifically on whether the box is
	     wider than the photo's own 1.777 (1672/941). Measured both ways:

	       aspect < 1.777 (cover is height-driven): pure PAN. Scale does not
	       move; the window slides ~105-118 source px left, trading the sofa
	       back on the right for more room and more of the caregiver.
	         1100x800  srcX [396,1672] -> [278,1554]   scale 0.8502 (unchanged)
	         1280x800  srcX [184,1672] -> [ 66,1554]   scale 0.8502 (unchanged)
	         1440x900  srcX [182,1672] -> [ 78,1567]   scale 0.9564 (unchanged)

	       aspect > 1.777 (width-driven): the window has already panned to
	       source x=0 and has no image left to give, so covering a 100px-wider
	       box ZOOMS instead — the crop loses source px off the RIGHT and the
	       pair sit slightly larger.
	         1440x800  srcX [ 0,1672] -> [0,1562]  scale 0.8523 -> 0.9121 (+7.0%)
	         1600x900  srcX [15,1672] -> [0,1573]  scale 0.9564 -> 1.0078 (+5.4%)
	         1920x1080 srcX [12,1672] -> [0,1589]  scale 1.1477 -> 1.1992 (+4.5%)

	     So: it pans left until it runs out of photograph, then it zooms.

	   Safe at both because the hero section is overflow:hidden, so the
	   overhang is clipped rather than scrolled — verified 2026-08-07 at all
	   seven widths above plus the ≤1024 band: documentElement.scrollWidth
	   minus clientWidth is 0 everywhere. Re-check that if the section ever
	   loses overflow:hidden; a 100px overhang is exactly the kind of thing
	   that turns into a site-wide horizontal scrollbar. */
	right: -100px;
}

/* Hero icon, centred above the eyebrow — the mockup uses a 40px olive glyph. */
.entry-content .mh-hero-icon::before {
	content: "";
	display: block;
	width: 40px;
	height: 40px;
	margin: 0 auto 1.5rem;
	background-color: var(--mh-olive);
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
}
.mh-icon-shield {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3C/svg%3E");
}
.mh-icon-activity {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2'/%3E%3C/svg%3E");
}
/* (mh-icon-heart / -clipboard / -monitor were removed 2026-08-04: no page
   uses them. The service-hero icon variants that ARE used — heartpulse,
   handheart, stethoscope — live with the feature-card styles further down.) */

/* --- Services page: full-width panels ------------------------------------
   The mockup lists the four service lines as full-width cards with the icon
   in a rounded square on the left and a row of "example" pills under the
   description. */
.entry-content .mh-stack {
	/* minmax(0,...) not bare 1fr: a bare 1fr's min is auto, which refuses to
	   shrink below content — the exact overflow the grid guard exists to
	   prevent. Fixed at the source here because this rule sits after the
	   guard and would win the tie. */
	grid-template-columns: minmax(0, 1fr);
}

/* The badge is absolutely positioned rather than a grid cell so it does not
   depend on how many children the card has — the pill row was added later,
   and a `grid-row: 1 / span N` would have had to be recounted. */
.entry-content .mh-service-panel {
	position: relative;
	padding-left: calc(2.5rem + 64px + 1.75rem);
	text-align: left;
}
.entry-content .mh-service-panel::before {
	content: "";
	position: absolute;
	left: 2.5rem;
	top: 2.5rem;
	width: 64px;
	height: 64px;
	border-radius: 20px;
	background-color: rgba(99, 112, 97, 0.06);
	background-image: var(--mh-svc-icon);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 28px 28px;
}
/* Narrow screens: drop the badge above the text instead of beside it.
   640px, NOT 600 — the MOBILE block replaces the panel's left padding-reserve
   with plain 1.5rem side padding at ≤640, so a 600px boundary here left a
   601–640 band where the absolutely-positioned badge sat on top of the text
   (found in the 2026-08-04 review). The two rules must share a breakpoint. */
@media (max-width: 640px) {
	.entry-content .mh-service-panel {
		padding-left: 2rem;
		padding-top: calc(2rem + 64px + 1rem);
	}
	.entry-content .mh-service-panel::before {
		top: 2rem;
		left: 2rem;
	}
}

.mh-pill-row {
	display: flex;
	flex-wrap: wrap;
	gap: 0.6rem;
	margin-top: 1.5rem;
}
.mh-pill {
	display: inline-flex;
	align-items: center;
	padding: 0.4rem 1.05rem;
	border-radius: var(--mh-radius-pill);
	background-color: rgba(99, 112, 97, 0.06);
	color: var(--mh-sage);
	font-family: var(--mh-font-body);
	font-size: 0.875rem;
	line-height: 1.35;
}

.mh-svc-heartpulse {
	--mh-svc-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3Cpath d='M3.22 13H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27'/%3E%3C/svg%3E");
}
.mh-svc-handheart {
	--mh-svc-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 14h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 16'/%3E%3Cpath d='m7 20 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9'/%3E%3Cpath d='m2 15 6 6'/%3E%3Cpath d='M19.5 8.5c.7-.7 1.5-1.6 1.5-2.7A2.73 2.73 0 0 0 16 4a2.78 2.78 0 0 0-5 1.8c0 1.2.8 2 1.5 2.8L16 12Z'/%3E%3C/svg%3E");
}
.mh-svc-stethoscope {
	--mh-svc-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 2v2'/%3E%3Cpath d='M5 2v2'/%3E%3Cpath d='M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1'/%3E%3Cpath d='M8 15a6 6 0 0 0 12 0v-3'/%3E%3Ccircle cx='20' cy='10' r='2'/%3E%3C/svg%3E");
}
.mh-svc-activity {
	--mh-svc-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2'/%3E%3C/svg%3E");
}

/* --- Section eyebrow -----------------------------------------------------
   Mirrors the values GenerateBlocks already carries on the hand-built
   eyebrows (olive, 0.875rem, 0.175em tracking, uppercase). Exists so a new
   eyebrow can be added without cloning another block's styles object and
   minting a fresh uniqueId for GB to compile. */
.entry-content .mh-eyebrow {
	display: block;
	margin-bottom: 1rem;
	color: var(--mh-olive);
	font-family: var(--mh-font-body);
	font-size: 0.875rem;
	font-weight: 400;
	letter-spacing: 0.175em;
	text-transform: uppercase;
}

/* Rows that sit under a centred header — the plan chips and the trailing
   "View all…" buttons. One class covers both cases: justify-content centres
   the flex rows, text-align centres the block wrappers holding an inline
   button, and each property is simply inert on the other display type. */
.entry-content .mh-row-center {
	justify-content: center;
	text-align: center;
}

/* --- Italics the mockup sets --------------------------------------------
   The wordmark reads "Mulberry <em>Health</em>"; functions.php injects that
   <em> via the generate_site_title_output filter. */
.main-title em,
.entry-content .mh-italic,
.site-footer .mh-italic {
	font-style: italic;
}
.main-title em {
	font-weight: inherit;
}

/* The brand tagline ("Where Home & Healthcare Meet.") is set in the DISPLAY
   face, not the body face — the mockup renders it Cormorant Garamond italic at
   25px/20px root, i.e. 1.25rem. Kept separate from .mh-italic on purpose:
   that one is a plain font-style utility, and the other copy it marks up (the
   homepage's "More communities coming soon…") is Inter italic in the mockup.
   Our own footer already set this tagline in Cormorant, so the hero was the
   odd one out. */
.entry-content .mh-tagline {
	font-family: var(--mh-font-display);
	font-style: italic;
	font-size: 1.25rem;
}

/* --- Icons inside buttons ----------------------------------------------- */
.mh-btn-arrow,
.mh-btn-phone {
	gap: 0.55rem;
}
.mh-btn-arrow::after,
.mh-btn-phone::before {
	content: "";
	flex: 0 0 auto;
	width: 1em;
	height: 1em;
	background-color: currentColor;
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
}
.mh-btn-arrow::after {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E");
	transition: transform 0.3s ease;
}
.mh-btn-arrow:hover::after {
	transform: translateX(4px);
}
.mh-btn-phone::before {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce) {
	.mh-btn-arrow::after,
	.mh-btn-arrow:hover::after {
		transition: none;
		transform: none;
	}
}

/* The service-page hero's "Get Started" button needs breathing room under the
   intro paragraph; the hero is centred, so the button centres with it. */
.entry-content .mh-hero-dark .mh-hero-cta {
	margin-top: 2.25rem;
}

/* --- Primary (filled) pill button ---------------------------------------
   The mockup fills these with SAGE (#637061), not forest, and gives them a
   real hover: bg-primary/90, a larger shadow, and a 2px lift. Ours were
   forest with no hover state at all.

   Buttons inside .mh-cta-card keep their olive-on-sage treatment — that rule
   is more specific (0,3,0 vs 0,2,0), so it wins without needing !important. */
.entry-content .mh-btn-primary {
	background-color: var(--mh-sage);
	color: var(--mh-white);
	box-shadow:
		0 10px 15px -3px rgba(0, 0, 0, 0.1),
		0 4px 6px -4px rgba(0, 0, 0, 0.1);
	transition:
		background-color 0.3s ease,
		box-shadow 0.3s ease,
		transform 0.3s ease;
}
.entry-content .mh-btn-primary:hover,
.entry-content .mh-btn-primary:focus-visible {
	/* Literally bg-primary/90: the sage at 90% alpha, which composites
	   slightly lighter over the cream page — what the mockup does. */
	background-color: rgba(99, 112, 97, 0.9);
	color: var(--mh-white);
	box-shadow:
		0 20px 25px -5px rgba(0, 0, 0, 0.12),
		0 8px 10px -6px rgba(0, 0, 0, 0.1);
	transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
	.entry-content .mh-btn-primary,
	.entry-content .mh-btn-primary:hover {
		transition: none;
		transform: none;
	}
}

/* On the DARK GREEN heroes the sage fill above is invisible — the band is the
   identical #637061, so "Get Started" on all four service pages rendered as a
   floating white label with only its drop shadow for an edge (found in the
   2026-08-04 review; a regression from making .mh-btn-primary sage globally,
   which post-dated the hero buttons). Forest on sage restores the pill; the
   hover composites forest at 90% over the band, the same direction as the
   cream-page hover. */
.entry-content .mh-hero-dark .mh-btn-primary {
	background-color: var(--mh-forest);
}
.entry-content .mh-hero-dark .mh-btn-primary:hover,
.entry-content .mh-hero-dark .mh-btn-primary:focus-visible {
	background-color: rgba(44, 62, 54, 0.9);
}

/* --- Header CTA — OLIVE in both header states ----------------------------
   ⚠️ DELIBERATE DIVERGENCE FROM THE MOCKUP (client request, 2026-08-06).
   The mockup's pill changes with the header — olive with ink text over the
   dark hero, sage with cream text once the bar scrolls to cream. The client
   asked for the olive accent to persist after scrolling, so the CTA now reads
   as one constant brand-accent button on every page and at every scroll
   position. Do not "restore" the sage state as a parity fix.

   Contrast holds in the new state: olive #B8B665 with ink #2C312B measures
   6.3:1, comfortably past AA for this size. The RING still tracks the header
   (see below) — only the fill is now constant.
   Sentence case on purpose: the rest of the nav is uppercase, the CTA is not. */
.main-navigation .main-nav > ul > li.mh-nav-cta > a {
	/* Scrolled / cream-bar state (the default) — olive, per the client. */
	background-color: var(--mh-olive);
	color: var(--mh-ink);
	/* The mockup sets this at 20px against a 20px root — i.e. 1rem, against
	   0.75rem nav links. Ours was 0.85rem, which read noticeably smaller. */
	font-size: 1rem;
	font-weight: 700;
	text-transform: none;
	letter-spacing: 0.01em;
	/* GeneratePress gives nav links a 60px line-height to set the header's
	   height. Left inherited, the padding below stacks on top of that and the
	   pill renders ~88px tall. Reset it so padding alone controls the size. */
	line-height: 1.5;
	/* The mockup's layered ring: a 2px band in the header's OWN colour (so it
	   reads as a gap), then a 2px translucent olive halo, then the lift.
	   The inner band therefore has to change with the header — forest over the
	   hero, cream once scrolled — or it draws a dark outline on the pale bar. */
	box-shadow:
		0 0 0 2px var(--mh-paper),
		0 0 0 4px rgba(184, 182, 101, 0.4),
		0 10px 15px -3px rgba(0, 0, 0, 0.1),
		0 4px 6px -4px rgba(0, 0, 0, 0.1);
	/* The header's own colours animate over 0.3s; without this the pill's
	   fill and ring snapped between states while everything else eased. */
	transition: background-color 0.3s ease, color 0.3s ease, box-shadow 0.3s ease;
}
.site-header.mh-at-top .main-navigation .main-nav > ul > li.mh-nav-cta > a {
	/* At-top / dark-hero state. The fill is now identical to the default —
	   kept here explicitly rather than deleted so this rule still states the
	   complete at-top appearance in one place. What genuinely differs is the
	   box-shadow's inner band: forest over the hero, cream once scrolled, so
	   the ring always reads as a gap in the bar rather than an outline. */
	background-color: var(--mh-olive);
	color: var(--mh-ink);
	box-shadow:
		0 0 0 2px var(--mh-forest),
		0 0 0 4px rgba(184, 182, 101, 0.4),
		0 10px 15px -3px rgba(0, 0, 0, 0.1),
		0 4px 6px -4px rgba(0, 0, 0, 0.1);
}
/* One fill now means one hover. The olive pill DARKENS rather than lightens —
   the old #c9c775 lightening read as a glare. Both states share it so the
   button behaves identically wherever you are on the page. #a6a45b with ink
   measures 5.1:1, so the hover state passes AA too. */
.main-navigation .main-nav > ul > li.mh-nav-cta > a:hover,
.site-header.mh-at-top .main-navigation .main-nav > ul > li.mh-nav-cta > a:hover {
	background-color: #a6a45b;
	color: var(--mh-ink);
}

/* --- Service Areas: map-pin badge beside the county name ----------------
   Grid rather than flex because the h3 and p are siblings with no wrapper —
   the badge spans both rows in column 1. */
.entry-content .mh-area-card {
	display: grid;
	grid-template-columns: auto 1fr;
	column-gap: 1.25rem;
	align-items: start;
	text-align: left;
}
.entry-content .mh-area-card::before {
	content: "";
	grid-row: 1 / span 2;
	/* 40px rounded SQUARE per the mockup (w-10 rounded-xl) — was a 44px
	   circle, the one badge on the site that didn't follow the squircle
	   family (aligned 2026-08-04). */
	width: 40px;
	height: 40px;
	border-radius: 12px;
	background-color: rgba(184, 182, 101, 0.12);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23B8B665' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
	background-size: 20px 20px;
}

/* --- Accepted Insurances: shield on each plan chip ---------------------- */
.entry-content .mh-plan-chip::before {
	content: "";
	flex: 0 0 auto;
	width: 0.95em;
	height: 0.95em;
	margin-right: 0.45rem;
	background-color: var(--mh-olive);
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3C/svg%3E");
}

/* The trailing "+ N more plans" chip is deliberately the odd one out in the
   mockup: pale olive fill, olive text, no visible border, and no shield.
   border-color rather than border-width so it keeps the same box size as the
   chips beside it. */
.entry-content .mh-plan-more {
	background-color: rgba(184, 182, 101, 0.1);
	color: var(--mh-olive);
	border-color: transparent;
}

/* --- /insurances: plan grid --------------------------------------------
   The dedicated insurances page lists plans as a 3-column grid of cards, not
   the wrapped row of chips used on the homepage summary. */
.entry-content .mh-plan-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 1rem;
}
@media (max-width: 900px) {
	.entry-content .mh-plan-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
@media (max-width: 600px) {
	.entry-content .mh-plan-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}
.entry-content .mh-plan-card {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	padding: 1.15rem 1.25rem;
	border-radius: 20px;
	background-color: var(--mh-white);
	border-width: 1px;
	border-style: solid;
	border-color: rgba(222, 219, 211, 0.5);
	color: var(--mh-ink);
	font-family: var(--mh-font-body);
	font-size: 1rem;
	line-height: 1.35;
	text-align: left;
}
.entry-content .mh-plan-card::before {
	content: "";
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	background-color: var(--mh-olive);
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3C/svg%3E");
}
/* Mockup hover: olive border tint + a soft shadow (the chips are static
   info, so no lift). plan-chips.js supplies the native title tooltips and
   wraps the launching-soon asterisk in .mh-ast for the olive marker. */
.entry-content .mh-plan-card {
	transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.entry-content .mh-plan-card:hover {
	border-color: rgba(184, 182, 101, 0.3);
	box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 4px 6px -4px rgba(0, 0, 0, 0.06);
}
.entry-content .mh-plan-card .mh-ast {
	color: var(--mh-olive);
	font-weight: 700;
	margin-left: 0.15rem;
}

/* --- "Important Insurance Information" panel ---------------------------- */
.entry-content .mh-info-panel {
	max-width: 62rem;
	margin-inline: auto;
	padding: clamp(2rem, 4vw, 3.125rem);
	border-radius: 40px;
	background-color: rgba(184, 182, 101, 0.1);
	border: 1px solid rgba(184, 182, 101, 0.2);
	/* Left-aligned, as the mockup has it — not centred. */
	text-align: left;
}
/* The heading carries an inline info glyph rather than a badge. */
.entry-content .mh-info-panel h3 {
	display: flex;
	align-items: center;
	gap: 0.65rem;
	text-align: left;
}
.entry-content .mh-info-panel h3::before {
	content: "";
	flex: 0 0 auto;
	width: 22px;
	height: 22px;
	background-color: var(--mh-olive);
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E");
}
.entry-content .mh-info-panel p {
	text-align: left;
}
.entry-content .mh-info-actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-start;
	gap: 1rem;
	margin-top: 2rem;
}

/* Leading mail glyph, matching .mh-btn-phone. */
.mh-btn-mail {
	gap: 0.55rem;
}
.mh-btn-mail::before {
	content: "";
	flex: 0 0 auto;
	width: 1em;
	height: 1em;
	background-color: currentColor;
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7'/%3E%3Crect x='2' y='4' width='20' height='16' rx='2'/%3E%3C/svg%3E");
}

/* --- /contact: two-column layout ----------------------------------------
   The mockup pairs the contact details (left) with the message form in a
   white card (right). Ours had them as two stacked sections. */
.entry-content .mh-contact-split {
	display: grid;
	grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
	gap: 4rem;
	align-items: start;
}
@media (max-width: 900px) {
	.entry-content .mh-contact-split {
		grid-template-columns: minmax(0, 1fr);
		gap: 2.5rem;
	}
}

/* Left column: icon-led rows, not cards. The badge spans both rows so the
   label and value stack beside it. */
.entry-content .mh-contact-list {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}
.entry-content .mh-contact-row {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: 1rem;
	align-items: start;
	padding: 0;
	border: 0;
	background-color: transparent;
	text-align: left;
}
.entry-content .mh-contact-row::before {
	content: "";
	grid-row: 1 / span 2;
	width: 44px;
	height: 44px;
	border-radius: 14px;
	background-color: rgba(184, 182, 101, 0.12);
	background-image: var(--mh-glyph);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 20px 20px;
}
.entry-content .mh-contact-row h3 {
	/* Sentence case per the mockup — the GB per-block rule uppercases these
	   at 0.175em tracking; reset both here (2026-08-04). */
	text-transform: none;
	letter-spacing: 0.02em;
	margin: 0;
	font-family: var(--mh-font-body);
	font-size: 0.85rem;
	font-weight: 400;
	color: var(--mh-sage);
}
.entry-content .mh-contact-row p {
	margin: 0.1rem 0 0;
	font-family: var(--mh-font-body);
	font-size: 1rem;
	font-weight: 600;
	color: var(--mh-ink);
}
/* The phone / fax / email values are tel:/mailto: links (added 2026-08-04 —
   they were plain text, on the page whose whole job is getting a senior to
   tap one of them). At rest they look exactly like the text they replaced;
   hover/focus turns them sage. The mockup hovers these to olive, which is
   2.1:1 on white — same accessibility call as the eyebrows. */
.entry-content .mh-contact-row a {
	color: inherit;
	text-decoration: none;
	transition: color 0.3s ease;
}
.entry-content .mh-contact-row a:hover,
.entry-content .mh-contact-row a:focus-visible {
	color: var(--mh-sage);
}
.mh-ci-phone {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23B8B665' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384'/%3E%3C/svg%3E");
}
.mh-ci-fax {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23B8B665' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6'/%3E%3Crect x='6' y='14' width='12' height='8' rx='1'/%3E%3C/svg%3E");
}
.mh-ci-mail {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23B8B665' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7'/%3E%3Crect x='2' y='4' width='20' height='16' rx='2'/%3E%3C/svg%3E");
}
.mh-ci-pin {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23B8B665' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
}
.mh-ci-clock {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23B8B665' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 6v6l4 2'/%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3C/svg%3E");
}

/* Right column: the form sits in a white card, as in the mockup. */
.entry-content .mh-form-card {
	padding: clamp(1.75rem, 3vw, 3rem);
	border-radius: 2rem;
	background-color: var(--mh-white);
	border: 1px solid rgba(222, 219, 211, 0.5);
	box-shadow:
		0 10px 15px -3px rgba(0, 0, 0, 0.04),
		0 4px 6px -4px rgba(0, 0, 0, 0.04);
	text-align: left;
}
/* The heading and intro carry their own text-align from GB, so inheriting
   left from the card is not enough — they have to be targeted directly. */
.entry-content .mh-form-card h2,
.entry-content .mh-form-card > p {
	text-align: left;
}

/* --- Embedded FormDr intake form ----------------------------------------
   Resolving the "form is 1200px but the panels are 1600px" mismatch.

   The instinct is to widen the iframe to match — but FormDr's document has its
   own FIXED internal width (~760px) and centres itself, so the iframe width
   only controls how much of FormDr's own green chrome shows around it.
   Measured at 1480px it just produced fat green bars down both sides; the form
   itself did not grow at all.

   Constraining to a reading measure instead makes the form fill its frame,
   reduces the green edging to a hairline, and lets its field rows reflow
   sensibly (date-of-birth drops to its own line rather than crowding the name
   row). The narrower zone then reads as deliberate rather than misaligned. */
.entry-content .responsive-iframe-wrapper {
	max-width: 860px;
	margin-inline: auto;
}

/* The /services embed's plain wrapper gets the same white card the /register
   embed sits in (values copied from register's .gb-element-e05c) — the mockup
   gives both pages one treatment; ours had a card on /register and a bare
   iframe on /services. Matched structurally on the wrapper's child because
   the wrapper div carries no class at all. Zeroed back out in the ≤640 block
   with the other embed wrappers. */
/* Both FormDr embeds share the mockup's frame: a ~896px card with a chunky
   4px sage-tinted border, large radius, soft shadow, and the iframe FLUSH
   against it (no inner padding, overflow clipped). Replaces the earlier
   plain white cards (2026-08-04). On /register this outranks the block's own
   .gb-element-e05c styling at (0,1,0). */
.entry-content div:has(> .responsive-iframe-wrapper),
.entry-content div:has(> .code-block .formdr-embed) {
	max-width: 896px;
	margin-inline: auto;
	background-color: var(--mh-white);
	border: 4px solid rgba(99, 112, 97, 0.1);
	border-radius: 2rem;
	box-shadow:
		0 10px 15px -3px rgba(0, 0, 0, 0.1),
		0 4px 6px -4px rgba(0, 0, 0, 0.1);
	padding: 0;
	overflow: hidden;
}
.entry-content div:has(> .responsive-iframe-wrapper) .responsive-iframe-wrapper,
.entry-content div:has(> .code-block .formdr-embed) .formdr-embed {
	max-width: none;
}
/* The sub-480 handoff button renders INSIDE this frame (the filter inserts
   it beside the iframe wrapper) — give it room, since the frame itself now
   has none. */
.entry-content .mh-form-handoff {
	padding-block: 2rem;
}

/* The /contact form was the site's only DOUBLE card — a white .mh-form-card
   holding a second sage-tinted bordered card around the Forminator form. The
   mockup (and /register) use a single card, so the inner one is flattened to
   a plain wrapper. Its padding is already zeroed at ≤640 by the MOBILE block. */
.entry-content .mh-form-card > div:has(.forminator-ui) {
	background-color: transparent;
	border: 0;
	border-radius: 0;
	padding: 0;
}

/* --- Floating "Begin Enrollment" CTA ------------------------------------
   Printed by functions.php on every page except /register itself (offering a
   shortcut to the page you are already on is just clutter). */
.mh-float-cta {
	position: fixed;
	right: 1.5rem;
	bottom: 1.5rem;
	z-index: 90;
	display: inline-flex;
	align-items: center;
	padding: 0.85rem 1.6rem;
	border-radius: var(--mh-radius-pill);
	background-color: var(--mh-sage);
	color: var(--mh-white);
	font-family: var(--mh-font-body);
	font-size: 0.75rem;
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	text-decoration: none;
	box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.25);
	transition:
		background-color 0.3s ease,
		transform 0.3s ease;
}
.mh-float-cta:hover,
.mh-float-cta:focus {
	background-color: var(--mh-forest);
	color: var(--mh-white);
	transform: translateY(-2px);
}
.mh-float-cta:focus-visible {
	outline: 2px solid var(--mh-olive);
	outline-offset: 3px;
}
/* Hidden on mobile (Ted's call, 2026-08-03). A fixed overlay costs far more
   on a 375px screen than on desktop — it sat over the hero's own buttons and
   over the foot of every section. Nothing is lost: the enrolment path is still
   one tap away in the menu's olive "Register Now", plus the in-page CTAs.
   768px matches the breakpoint the rest of the mobile block uses, i.e. the
   point where the nav collapses to the hamburger. The old 640px rule only
   shrank the button and is now unreachable, so it is gone rather than left
   behind as dead code. */
@media (max-width: 768px) {
	.mh-float-cta {
		display: none;
	}
}
@media (prefers-reduced-motion: reduce) {
	.mh-float-cta,
	.mh-float-cta:hover {
		transition: none;
		transform: none;
	}
}

/* =========================================================================
   SERVICE DETAIL PAGES
   How It Works timeline, Benefits / Care Coordination grids.

   TWO icon mechanisms exist here, and the distinction is load-bearing:
     * --mh-icon  + .mh-icon-*  → CSS **mask**. Use where the pseudo-element
       IS the icon (hero glyph, button arrows, footer lines). Inherits
       currentColor.
     * --mh-glyph + .mh-gl-*    → **background-image**. Use where the
       pseudo-element is a circle/rounded badge WITH an icon inside — a mask
       would clip the badge away along with everything else. Stroke colour is
       baked in (sage).
   A few glyphs exist in both sets because they're needed in both contexts.
   ========================================================================= */

/* --- Badge glyphs (background-image, sage stroke) ------------------------ */
.mh-gl-house {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8'/%3E%3Cpath d='M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/%3E%3C/svg%3E");
}
.mh-gl-clipboardlist {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='M12 11h4'/%3E%3Cpath d='M12 16h4'/%3E%3Cpath d='M8 11h.01'/%3E%3Cpath d='M8 16h.01'/%3E%3C/svg%3E");
}
.mh-gl-heart {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E");
}
.mh-gl-users {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cpath d='M22 21v-2a4 4 0 0 0-3-3.87'/%3E%3Cpath d='M16 3.13a4 4 0 0 1 0 7.75'/%3E%3C/svg%3E");
}
.mh-gl-heartpulse {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3Cpath d='M3.22 13H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27'/%3E%3C/svg%3E");
}
.mh-gl-pill {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m10.5 20.5 10-10a4.95 4.95 0 1 0-7-7l-10 10a4.95 4.95 0 1 0 7 7Z'/%3E%3Cpath d='m8.5 8.5 7 7'/%3E%3C/svg%3E");
}
.mh-gl-stethoscope {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 2v2'/%3E%3Cpath d='M5 2v2'/%3E%3Cpath d='M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1'/%3E%3Cpath d='M8 15a6 6 0 0 0 12 0v-3'/%3E%3Ccircle cx='20' cy='10' r='2'/%3E%3C/svg%3E");
}
.mh-gl-shieldcheck {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E");
}
.mh-gl-activity {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2'/%3E%3C/svg%3E");
}
.mh-gl-droplets {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 16.3c2.2 0 4-1.83 4-4.05 0-1.16-.57-2.26-1.71-3.19S7.29 6.75 7 5.3c-.29 1.45-1.14 2.84-2.29 3.76S3 11.1 3 12.25c0 2.22 1.8 4.05 4 4.05z'/%3E%3Cpath d='M12.56 6.6A10.97 10.97 0 0 0 14 3.02c.5 2.5 2 4.9 4 6.5s3 3.5 3 5.5a6.98 6.98 0 0 1-11.91 4.97'/%3E%3C/svg%3E");
}
.mh-gl-scanline {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 7V5a2 2 0 0 1 2-2h2'/%3E%3Cpath d='M17 3h2a2 2 0 0 1 2 2v2'/%3E%3Cpath d='M21 17v2a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M7 21H5a2 2 0 0 1-2-2v-2'/%3E%3Cpath d='M7 12h10'/%3E%3C/svg%3E");
}
.mh-gl-package {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7.5 4.27 9 5.15'/%3E%3Cpath d='M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z'/%3E%3Cpath d='m3.3 7 8.7 5 8.7-5'/%3E%3Cpath d='M12 22V12'/%3E%3C/svg%3E");
}
.mh-gl-userplus {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2'/%3E%3Ccircle cx='9' cy='7' r='4'/%3E%3Cpath d='M19 8v6'/%3E%3Cpath d='M22 11h-6'/%3E%3C/svg%3E");
}

/* Added for the palliative / primary care / remote-monitoring pages. The
   "Services Our Team Coordinates" six are identical on all four service pages,
   so only the Benefits row needed new glyphs. */
.mh-gl-handheart {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 14h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 16'/%3E%3Cpath d='m7 20 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9'/%3E%3Cpath d='m2 15 6 6'/%3E%3Cpath d='M19.5 8.5c.7-.7 1.5-1.6 1.5-2.7A2.73 2.73 0 0 0 16 4a2.78 2.78 0 0 0-5 1.8c0 1.2.8 2 1.5 2.8L16 12Z'/%3E%3C/svg%3E");
}
.mh-gl-messagecircle {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7.9 20A9 9 0 1 0 4 16.1L2 22Z'/%3E%3C/svg%3E");
}
.mh-gl-shield {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67 0C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3C/svg%3E");
}
.mh-gl-brain {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z'/%3E%3Cpath d='M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z'/%3E%3Cpath d='M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4'/%3E%3Cpath d='M6 18a4 4 0 0 1-1.967-.516'/%3E%3Cpath d='M19.967 17.484A4 4 0 0 1 18 18'/%3E%3C/svg%3E");
}
.mh-gl-bell {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.268 21a2 2 0 0 0 3.464 0'/%3E%3Cpath d='M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326'/%3E%3C/svg%3E");
}
.mh-gl-signal {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 20h.01'/%3E%3Cpath d='M7 20v-4'/%3E%3Cpath d='M12 20v-8'/%3E%3Cpath d='M17 20V8'/%3E%3Cpath d='M22 4v16'/%3E%3C/svg%3E");
}
.mh-gl-smartphone {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='14' height='20' x='5' y='2' rx='2' ry='2'/%3E%3Cpath d='M12 18h.01'/%3E%3C/svg%3E");
}

/* Added for the remote-monitoring "Devices We Provide" row. */
.mh-gl-gauge {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m12 14 4-4'/%3E%3Cpath d='M3.34 19a10 10 0 1 1 17.32 0'/%3E%3C/svg%3E");
}
.mh-gl-wind {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12.8 19.6A2 2 0 1 0 14 16H2'/%3E%3Cpath d='M17.5 8a2.5 2.5 0 1 1 2 4H2'/%3E%3Cpath d='M9.8 4.4A2 2 0 1 1 11 8H2'/%3E%3C/svg%3E");
}
.mh-gl-weight {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='5' r='3'/%3E%3Cpath d='M6.5 8a2 2 0 0 0-1.905 1.46L2.1 18.5A2 2 0 0 0 4 21h16a2 2 0 0 0 1.925-2.54L19.4 9.5A2 2 0 0 0 17.48 8Z'/%3E%3C/svg%3E");
}
.mh-gl-thermometer {
	--mh-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23637061' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 4v10.54a4 4 0 1 1-4 0V4a2 2 0 0 1 4 0Z'/%3E%3C/svg%3E");
}

/* --- "Devices We Provide" row (remote monitoring) ------------------------
   Six compact cards, icon badge over a centred label. The mockup runs all six
   across on desktop; that is too tight below ~1100px, so it steps to 3 then 2
   rather than shrinking the cards further. */
.entry-content .mh-device-grid {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: 1.25rem;
}
@media (max-width: 1100px) {
	.entry-content .mh-device-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}
@media (max-width: 600px) {
	.entry-content .mh-device-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
.entry-content .mh-device-card {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	padding: 1.75rem 1rem;
	border-radius: 1.5rem;
	background-color: var(--mh-white);
	border: 1px solid rgba(222, 219, 211, 0.5);
}
.entry-content .mh-device-card::before {
	content: "";
	flex: 0 0 auto;
	width: 48px;
	height: 48px;
	margin-bottom: 1rem;
	border-radius: 14px;
	background-color: rgba(99, 112, 97, 0.07);
	background-image: var(--mh-glyph);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 22px 22px;
}
.entry-content .mh-device-card p {
	margin: 0;
	font-family: var(--mh-font-display);
	font-size: 1rem;
	line-height: 1.3;
	color: var(--mh-ink);
}

/* --- Extra hero glyphs (mask, olive) ------------------------------------ */
.mh-icon-heartpulse {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3Cpath d='M3.22 13H9.5l.5-1 2 4.5 2-7 1.5 3.5h5.27'/%3E%3C/svg%3E");
}
.mh-icon-handheart {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 14h2a2 2 0 1 0 0-4h-3c-.6 0-1.1.2-1.4.6L3 16'/%3E%3Cpath d='m7 20 1.6-1.4c.3-.4.8-.6 1.4-.6h4c1.1 0 2.1-.4 2.8-1.2l4.6-4.4a2 2 0 0 0-2.75-2.91l-4.2 3.9'/%3E%3Cpath d='m2 15 6 6'/%3E%3Cpath d='M19.5 8.5c.7-.7 1.5-1.6 1.5-2.7A2.73 2.73 0 0 0 16 4a2.78 2.78 0 0 0-5 1.8c0 1.2.8 2 1.5 2.8L16 12Z'/%3E%3C/svg%3E");
}
.mh-icon-stethoscope {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M11 2v2'/%3E%3Cpath d='M5 2v2'/%3E%3Cpath d='M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1'/%3E%3Cpath d='M8 15a6 6 0 0 0 12 0v-3'/%3E%3Ccircle cx='20' cy='10' r='2'/%3E%3C/svg%3E");
}

/* --- How It Works: vertical timeline ------------------------------------ */
.entry-content .mh-steps {
	grid-template-columns: minmax(0, 1fr);
	gap: 0;
	max-width: 56rem;
	margin-inline: auto;
}
.entry-content .mh-step {
	position: relative;
	padding: 0 0 2.75rem calc(48px + 1.5rem);
	text-align: left;
	background-color: transparent;
	border: 0;
	border-radius: 0;
}
.entry-content .mh-step:last-child {
	padding-bottom: 0;
}
.entry-content .mh-step::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	width: 48px;
	height: 48px;
	/* rounded-2xl per the mockup — was the page's only circular badge while
	   every neighbouring card used squircles (aligned 2026-08-04). */
	border-radius: 16px;
	background-color: rgba(99, 112, 97, 0.07);
	background-image: var(--mh-glyph);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 21px 21px;
}
/* The connector: a hairline from under one badge to the next. */
.entry-content .mh-step::after {
	content: "";
	position: absolute;
	left: 23px;
	top: 56px;
	bottom: 0;
	width: 1px;
	background-color: rgba(99, 112, 97, 0.22);
}
.entry-content .mh-step:last-child::after {
	display: none;
}
/* Step titles are the one place the mockup uses the BODY face for a heading
   (Inter 600) rather than Cormorant — verified against the mockup. The
   Benefits cards next to them stay serif, which ours already matched. */
.entry-content .mh-step h3 {
	font-family: var(--mh-font-body);
	font-weight: 600;
	font-size: 1.25rem;
	line-height: 1.3;
}
/* These cards were built with the hover-lift; it makes no sense on a
   borderless timeline row. */
.entry-content .mh-step.mh-card-hover:hover {
	transform: none;
	box-shadow: none;
	border-color: transparent;
}

/* --- Benefits: 3 / 2 / 1 feature cards ----------------------------------
   The ≤640 single-column rule MUST come after the ≤1024 two-column rule:
   both match on a phone at equal specificity, so source order decides. It
   cannot move to the grid guard at the top of the file for the same reason
   (learned the hard way 2026-08-04). */
.entry-content .mh-feature-grid {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 1024px) {
	.entry-content .mh-feature-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
@media (max-width: 640px) {
	.entry-content .mh-feature-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}
.entry-content .mh-feature-card {
	text-align: left;
}
/* 16px radius / 5% tint to match .mh-icon-box on the homepage cards — the
   badge family had drifted (this one was 14px / 7%); the mockup uses
   rounded-2xl (16px) for both sizes. */
.entry-content .mh-feature-card::before {
	content: "";
	display: block;
	width: 48px;
	height: 48px;
	margin-bottom: 1.25rem;
	border-radius: 16px;
	background-color: rgba(99, 112, 97, 0.05);
	background-image: var(--mh-glyph);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 22px 22px;
}

/* --- Care Coordination: compact icon-left rows -------------------------- */
.entry-content .mh-coord-card {
	position: relative;
	display: flex;
	align-items: center;
	min-height: calc(44px + 2.5rem);
	padding: 1.25rem 1.5rem 1.25rem calc(1.5rem + 44px + 1rem);
	text-align: left;
}
.entry-content .mh-coord-card::before {
	content: "";
	position: absolute;
	left: 1.5rem;
	top: 50%;
	transform: translateY(-50%);
	width: 44px;
	height: 44px;
	border-radius: 12px;
	background-color: rgba(99, 112, 97, 0.07);
	background-image: var(--mh-glyph);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 20px 20px;
}
/* Row titles are serif semibold in the mockup (font-heading font-semibold
   text-foreground); ours had drifted to Inter 500. The size steps up to
   1.0625rem because Cormorant's small x-height reads a step smaller than
   Inter at equal size. The Mobile Imaging row's "X-ray, EKG, Ultrasound"
   sub-line (a <small> inside the row text) gets the mockup's muted second
   line. */
.entry-content .mh-coord-card p {
	font-family: var(--mh-font-display);
	font-size: 1.0625rem;
	font-weight: 600;
	color: var(--mh-ink);
}
.entry-content .mh-coord-card small {
	display: block;
	font-family: var(--mh-font-body);
	font-size: 0.8125rem;
	font-weight: 400;
	color: var(--mh-sage);
	margin-top: 2px;
}

/* =========================================================================
   ABOUT PAGE
   Executive team (real headshots), care team roster, and the closing CTA card.

   The headshot URLs are relative and that is fine HERE — style.css is a real
   stylesheet, so url() resolves against it. The hero image needed an absolute
   URL from PHP only because it was set in a GenerateBlocks block style, which
   GB injects inline into the document. See the warning in CLAUDE.md.
   ========================================================================= */

/* --- Executive team ------------------------------------------------------ */
.entry-content .mh-exec-card {
	text-align: left;
}
/* The avatar disc: a headshot where one exists, otherwise the person's
   initials on sage (Ted, 2026-08-07 — Christy, Kelly and Erin showed an empty
   grey disc until then).

   ⚠️ The two are ALTERNATIVES, and they have to be. The first attempt set
   --mh-initials on all seven on the theory that the photo would paint over the
   monogram and give every card a free fallback if its file ever went missing.
   It does not work and the screenshot showed why: `background-image` paints
   BEHIND an element's content, and generated content is content — so JF, KH,
   PA and MH rendered on top of four real faces. A per-element photo-over-text
   layer would need a second positioned pseudo-element, which is not worth it.
   Set --mh-initials only where there is no --mh-headshot.

   ⚠️ font-size is px, not rem, ON PURPOSE. The disc is a fixed 96px; sizing the
   monogram in rem lets it grow against a fixed box, and at the 20px root some
   browsers are set to it overflows the circle. Same coupling that bit the
   header logo. */
.entry-content .mh-exec-card::before {
	content: var(--mh-initials, "");
	display: grid;
	place-items: center;
	width: 96px;
	height: 96px;
	margin-bottom: 1.35rem;
	border-radius: 9999px;
	background-color: var(--mh-sage);
	background-image: var(--mh-headshot, none);
	background-repeat: no-repeat;
	background-position: center top;
	background-size: cover;
	font-family: var(--mh-font-display);
	font-size: 34px;
	font-weight: 400;
	line-height: 1;
	letter-spacing: 0.04em;
	color: var(--mh-paper);
}
/* Marks the monogram as decorative so screen readers skip it — the card's
   heading names the person on the very next line. Behind @supports because the
   `content: <string> / <alt>` syntax is all-or-nothing: on a browser that
   can't parse it the WHOLE declaration is dropped and the initials vanish.
   Safari only shipped it in 17.4, and this audience skews toward older,
   less-updated devices, so visible-everywhere wins and the a11y polish is
   applied only where it is free. */
@supports (content: "a" / "b") {
	.entry-content .mh-exec-card::before {
		content: var(--mh-initials, "") / "";
	}
}
/* Exactly one of --mh-headshot / --mh-initials per person — never both, see
   the layering note above. To swap a monogram for a real photo later: drop the
   file into assets/img/team/, then replace that card's --mh-initials line with
   a --mh-headshot line. */
.mh-exec-joseph {
	--mh-headshot: url("assets/img/team/joseph-furtado.jpg");
}
.mh-exec-katina {
	--mh-headshot: url("assets/img/team/katina-hughes.jpg");
}
.mh-exec-preston {
	--mh-headshot: url("assets/img/team/preston-ashby.jpg");
}
.mh-exec-hoertz {
	--mh-headshot: url("assets/img/team/maria-hoertz.jpg");
}
/* Ted, 2026-08-07 — monograms until the client supplies headshots. The
   --mh-headshot lines are REMOVED rather than commented out or pointed at a
   placeholder: they referenced christy-furtado.jpg, kelly-ranahan.jpg and
   erin-bond.jpg, none of which exist, so every visit fired three 404s to fill
   three empty discs. */
/* ⚠️ `--mh-headshot: none` is a GUARD, not redundancy. Custom properties
   inherit and these classes coexist with whatever else is on the element, so a
   card cloned in the editor keeps the source card's person class and quietly
   inherits its photo. That is exactly what happened: Christy's card carried
   `mh-exec-joseph` in globalClasses with `mh-exec-christy` only in className,
   and the moment the dead christy-furtado.jpg URL was removed she rendered
   with Joseph's face. Maria had the same stray `mh-exec-preston` and was
   saved only by source order. The strays were cleaned out of the markup on
   2026-08-07; this line means the next clone fails safe instead of silently
   putting the wrong person's face on the wrong name. */
.mh-exec-christy {
	--mh-initials: "CF";
	--mh-headshot: none;
}
.mh-exec-kelly {
	--mh-initials: "KR";
	--mh-headshot: none;
}
.mh-exec-erin {
	--mh-initials: "EB";
	--mh-headshot: none;
}
.entry-content .mh-exec-bio {
	margin-top: 1rem;
	color: var(--mh-sage);
	font-family: var(--mh-font-body);
	font-size: 0.9375rem;
	line-height: 1.7;
}
/* .is-clamped is added by assets/js/bio-toggle.js, never in the markup — the
   bio ships expanded so it stays readable if the script never runs. */
.entry-content .mh-exec-bio.is-clamped {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.entry-content .mh-bio-toggle {
	display: inline-flex;
	align-items: center;
	gap: 0.4rem;
	margin-top: 0.85rem;
	padding: 0;
	border: 0;
	background: none;
	color: var(--mh-olive);
	font-family: var(--mh-font-body);
	font-size: 0.875rem;
	font-weight: 600;
	cursor: pointer;
}
.entry-content .mh-bio-toggle:hover {
	color: var(--mh-forest);
}
.entry-content .mh-bio-toggle:focus-visible {
	outline: 2px solid var(--mh-olive);
	outline-offset: 3px;
	border-radius: 2px;
}
.entry-content .mh-bio-toggle::after {
	content: "";
	width: 0.85em;
	height: 0.85em;
	background-color: currentColor;
	transition: transform 0.25s ease;
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.25' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
.entry-content .mh-bio-toggle[aria-expanded="true"]::after {
	transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
	.entry-content .mh-bio-toggle::after {
		transition: none;
	}
}

/* --- Care team roster ---------------------------------------------------- */
/* Explicit 3 / 2 / 1 rather than auto-fit: the cards hold four lines of text
   of wildly different lengths, and auto-fit was picking column counts off the
   widest card. */
.entry-content .mh-care-grid {
	grid-template-columns: repeat(3, minmax(0, 1fr));
}
@media (max-width: 1024px) {
	.entry-content .mh-care-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
@media (max-width: 640px) {
	.entry-content .mh-care-grid {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Avatar is absolutely positioned for the same reason as the service panels:
   it must not depend on how many text rows the card happens to have. */
.entry-content .mh-care-card {
	position: relative;
	padding: 1.75rem 1.75rem 1.75rem calc(1.75rem + 52px + 1rem);
	text-align: left;
}
.entry-content .mh-care-avatar {
	position: absolute;
	left: 1.75rem;
	top: 1.75rem;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	border-radius: 9999px;
	background-color: rgba(99, 112, 97, 0.07);
	color: var(--mh-sage);
	font-family: var(--mh-font-display);
	font-size: 1rem;
	letter-spacing: 0.03em;
}
.entry-content .mh-care-creds {
	margin: 0.15rem 0 0.6rem;
	color: var(--mh-sage);
	font-family: var(--mh-font-body);
	font-size: 0.8125rem;
	line-height: 1.4;
}
.entry-content .mh-care-area {
	display: flex;
	align-items: center;
	gap: 0.35rem;
	margin-top: 0.5rem;
	color: var(--mh-olive);
	font-family: var(--mh-font-body);
	font-size: 0.8125rem;
	line-height: 1.4;
}
.entry-content .mh-care-area::before {
	content: "";
	flex: 0 0 auto;
	width: 13px;
	height: 13px;
	background-color: currentColor;
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
}

/* --- Closing CTA card ---------------------------------------------------- */
.entry-content .mh-cta-card {
	max-width: 62rem;
	margin-inline: auto;
	padding: 4.5rem 3rem;
	border-radius: 30px;
	background-color: var(--mh-sage);
	text-align: center;
}
.entry-content .mh-cta-card h2 {
	color: var(--mh-paper);
}
.entry-content .mh-cta-card p {
	color: rgba(252, 251, 247, 0.85);
	margin-inline: auto;
}
/* Buttons have to be re-tuned for the dark card: the forest fill vanishes on
   sage, and the sand-coloured outline is too low-contrast to see. */
.entry-content .mh-cta-card .mh-btn-arrow {
	background-color: var(--mh-olive);
	color: var(--mh-ink);
}
.entry-content .mh-cta-card .mh-btn-phone {
	box-shadow: inset 0 0 0 1px rgba(252, 251, 247, 0.45);
	color: var(--mh-paper);
}
/* Hover states live HERE, not on .mh-btn-primary, because the card's (0,3,0)
   fills outrank the utility's (0,2,1) hover — which is why the four service
   pages' closing buttons (which carry no mh-btn-primary at all) sat inert
   while /about's animated. One rule set, every page, same behaviour. The
   olive pill darkens (same direction as the header pill); the outline pill
   brightens its ring. */
.entry-content .mh-cta-card .mh-btn-arrow,
.entry-content .mh-cta-card .mh-btn-phone {
	transition: background-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.entry-content .mh-cta-card .mh-btn-arrow:hover,
.entry-content .mh-cta-card .mh-btn-arrow:focus-visible {
	background-color: #a6a45b;
	color: var(--mh-ink);
	transform: translateY(-2px);
}
.entry-content .mh-cta-card .mh-btn-phone:hover,
.entry-content .mh-cta-card .mh-btn-phone:focus-visible {
	box-shadow: inset 0 0 0 1.5px rgba(252, 251, 247, 0.85);
	color: var(--mh-paper);
	transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
	.entry-content .mh-cta-card .mh-btn-arrow,
	.entry-content .mh-cta-card .mh-btn-phone,
	.entry-content .mh-cta-card .mh-btn-arrow:hover,
	.entry-content .mh-cta-card .mh-btn-phone:hover {
		transition: none;
		transform: none;
	}
}
@media (max-width: 640px) {
	.entry-content .mh-cta-card {
		padding: 3rem 1.5rem;
	}
}

/* --- "Golden thread" section divider (mockup parity, 2026-08-04) ---------
   The mockup opens key sections with a 1px olive gradient hairline. Applied
   as a globalClass (mh-thread) on the section blocks the mockup divides:
   home Mission/Exec/Insurances/final CTA, about Exec/Care Team, and the
   /services + /insurances closing sections. */
.entry-content .mh-thread {
	position: relative;
}
.entry-content .mh-thread::before {
	content: "";
	position: absolute;
	top: 0;
	left: 50%;
	transform: translateX(-50%);
	width: min(92%, 1600px);
	height: 1px;
	background: linear-gradient(90deg, transparent, rgba(184, 182, 101, 0.5), transparent);
}

/* Olive accent bar closing the homepage mission paragraph (mockup's
   h-1 w-16 bg-secondary rounded-full; 80×5 as rendered). globalClass
   mh-accent-bar on the paragraph block. */
.entry-content .mh-accent-bar::after {
	content: "";
	display: block;
	width: 80px;
	height: 5px;
	margin: 2.5rem auto 0;
	border-radius: 9999px;
	background-color: var(--mh-olive);
}

/* Hero scroll cue: the mockup's mouse-outline with a bobbing olive dot,
   centred at the hero's bottom edge. globalClass mh-scroll-cue on an empty
   element block inside the hero. Decorative only (aria-hidden set in the
   block); hidden on phones where the hero is compact, and the dot holds
   still under prefers-reduced-motion. */
.entry-content .mh-scroll-cue {
	position: absolute;
	bottom: 2rem;
	left: 50%;
	transform: translateX(-50%);
	width: 24px;
	height: 40px;
	border: 2px solid rgba(99, 112, 97, 0.3);
	border-radius: 9999px;
}
.entry-content .mh-scroll-cue::before {
	content: "";
	position: absolute;
	top: 6px;
	left: 50%;
	transform: translateX(-50%);
	width: 4px;
	height: 8px;
	border-radius: 9999px;
	background-color: var(--mh-olive);
	animation: mh-cue-bob 2s ease-in-out infinite;
}
@keyframes mh-cue-bob {
	0%, 100% { transform: translate(-50%, 0); }
	50% { transform: translate(-50%, 8px); }
}
@media (prefers-reduced-motion: reduce) {
	.entry-content .mh-scroll-cue::before {
		animation: none;
	}
}
@media (max-width: 768px) {
	.entry-content .mh-scroll-cue {
		display: none;
	}
}

/* --- /register: persistent help bar (mockup parity, 2026-08-04) ----------
   The mockup pins "Need help? Our team is standing by." + the call button to
   the viewport bottom while the long intake form scrolls. globalClass
   mh-help-bar on the register page's closing section converts it from an
   in-flow band to the fixed bar. The :has() gives the footer breathing room
   so the bar never permanently covers its last line. */
.entry-content .mh-help-bar {
	position: fixed;
	bottom: 0;
	left: 0;
	right: 0;
	z-index: 90;
	background-color: rgba(255, 255, 255, 0.95);
	-webkit-backdrop-filter: blur(12px);
	backdrop-filter: blur(12px);
	border-top: 1px solid var(--mh-sand);
	box-shadow: 0 -10px 15px -3px rgba(0, 0, 0, 0.05);
	/* (0,2,0) outranks the block's own 6rem band padding — no !important. */
	padding: 0.85rem 1.5rem;
}
.entry-content .mh-help-bar > div {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1.5rem;
	padding: 0;
}
.entry-content .mh-help-bar p {
	margin: 0;
}
body:has(.mh-help-bar) .site-footer {
	padding-bottom: 6rem;
}
@media (max-width: 640px) {
	.entry-content .mh-help-bar p {
		display: none;
	}
}

/* =========================================================================
   SITE FOOTER
   The footer is a GP Block Element (Appearance → Elements → "Site Footer"),
   so GenerateBlocks owns its layout and spacing. What lives here is the
   cross-cutting decoration the mockup adds and GB can't express per block:
   masked icons, the knocked-out logo, and the social buttons.
   ========================================================================= */

/* Column headings — gold, and set in the display serif rather than the body
   face, which is what the mockup does. */
.site-footer .mh-foot-heading {
	color: var(--mh-olive);
	font-family: var(--mh-font-display);
	font-size: 1.05rem;
	font-weight: 600;
	letter-spacing: 0.15em;
	text-transform: uppercase;
}

/* Brand lockup: knocked-out tree beside the wordmark.
   The mark is a pseudo-element on the wordmark itself rather than its own
   block — it is purely decorative (the wordmark text already names the
   practice), so this keeps it out of the accessible name and avoids
   restructuring the footer's blocks to introduce a wrapper. */
/* Deliberately NOT display:flex. The wordmark is "Mulberry <em>Health</em>",
   and under flex the bare text node and the <em> become separate flex items,
   so the container's gap opens up between the two words as well as before the
   mark. Inline-block on the pseudo-element keeps the words as normal text. */
/* The wordmark's own type. The GenerateBlocks block sets the display serif via
   its per-block class (.gb-text-mhf001, specificity 0,1,0); this rule is
   (0,2,0) so it wins regardless of source order, and it keeps the brand face
   in the THEME where both logotypes are defined together — rather than in
   block styles, where an editor recompile is free to rewrite it. Size trimmed
   from 1.75rem for the same width reason as the header. */
/* The client's horizontal lockup replaces the tree + Brice wordmark here too
   (2026-08-07). The block's text ("Mulberry Health") is kept in the DOM and
   collapsed with font-size:0 rather than removed: it stays the accessible
   name of the element, so the footer still announces the practice even though
   the visible brand is now an image. The old ::before tree is switched off.

   Sized by width with an aspect-ratio box so the SVG never needs intrinsic
   dimensions, and the LIGHT variant is used because the stock wordmark
   measures 1.02:1 against this sage panel — i.e. invisible. */
.site-footer .mh-foot-brand {
	display: block;
	width: 100%;
	max-width: 260px;
	aspect-ratio: 1376.19 / 371.9;
	background-image: var(--mh-logo-h-light);
	background-repeat: no-repeat;
	background-position: left center;
	background-size: contain;
	font-size: 0;
	margin-bottom: 1.25rem;
	/* ⚠️ NO `filter` here — deliberate. A `filter: brightness(0) invert(1)`
	   silhouette lived here for a few hours on 2026-08-07 to make the mark
	   white, and it had to go the moment "HEALTH" needed to stay green: a
	   filter cannot recolour one part of an image. The on-dark treatment now
	   lives in the FILE (--mh-logo-h-light), which both dark contexts share —
	   see the lockup section in CLAUDE.md for the recolour map. */
}
/* ⚠️ Keep this the ONLY ::before rule for .mh-foot-brand. Until 2026-08-07 a
   second one sat ~20 lines below with the identical selector, and since they
   tie on specificity the later one silently won — see the deletion note there
   before adding another. */
.site-footer .mh-foot-brand::before {
	content: none;
}

/* Retained for reference — the wordmark styling the lockup replaced. Harmless
   now that font-size is 0, and one deletion away if the logo is ever reverted. */
.site-footer .mh-foot-brand--text {
	font-family: var(--mh-font-logo);
	/* MEASURED, do not raise without re-measuring. The footer's first grid
	   column is 325px inner; the mark plus its gap reserve 57px, leaving 268px
	   of text space. "Mulberry Health" in Brice Expanded ran 347px at the
	   old 1.5rem, so it wrapped to two lines with the mark stranded beside the
	   first — 1.1rem landed at ~254px and kept the wordmark on one line with
	   headroom. ⚠️ Those widths were measured in Brice, which the site stopped
	   loading on 2026-08-07; the fallback serif sets narrower, so re-measure
	   rather than reuse them if the text wordmark is ever restored. */
	font-size: 1.1rem;
	white-space: nowrap;
	/* Same closed lockup as the header — see the note there for why this is
	   word-spacing and not a markup change. */
	word-spacing: -0.304em;
}
/* DELETED 2026-08-07 (found by Ted): a SECOND `.site-footer .mh-foot-brand
   ::before` rule lived here, painting the old tree-only mark
   (--mh-logo-reversed) at 42x50. It was the twin of the `content: none` rule
   ~20 lines above, identical selector and identical (0,2,0) specificity — so
   source order decided, and being later it won. `content: none` never took
   effect; the standalone tree was still drawn, and because it is smaller than
   the lockup's own tree it landed almost exactly on top of it, so its full
   colour leaves showed around the white ones. That is the "coloured leaves
   peeking through" — two trees stacked, not one tree failing to recolour.
   The lockup carries its own tree now, so nothing replaces this. */
/* "Follow us" sits on the same row as the buttons and keeps the muted cream
   of the original column labels — in the mockup only the three column
   headings are gold. */
.site-footer .mh-foot-follow {
	margin-right: 0.4rem;
	color: rgba(252, 251, 247, 0.65);
	font-family: var(--mh-font-body);
	font-size: 0.8125rem;
	font-weight: 500;
	letter-spacing: 0.175em;
	text-transform: uppercase;
	white-space: nowrap;
}

/* Icon-led lines: the counties line and the contact details. */
.site-footer .mh-foot-icon {
	display: flex;
	align-items: flex-start;
	gap: 0.6rem;
	/* referrals@mulberrymedical.net has no break opportunity, and the text is
	   an anonymous flex item whose default min-width:auto makes it demand its
	   full 303px. In the footer's 245px grid column that pushed the DOCUMENT
	   to 633px against a 600px viewport — a horizontal scrollbar on every page
	   at tablet widths, found 2026-08-03 while verifying the register page.

	   `anywhere` rather than `break-word` on purpose: only `anywhere` reduces
	   intrinsic min-content size, which is what lets the flex item shrink.
	   `break-word` looks equivalent and does not fix this. It still breaks
	   only when the line genuinely cannot fit, so wide viewports are
	   unchanged and the address stays on one line. */
	overflow-wrap: anywhere;
}
.site-footer .mh-foot-icon::before {
	content: "";
	flex: 0 0 auto;
	width: 16px;
	height: 16px;
	margin-top: 0.2em;
	opacity: 0.8;
	background-color: currentColor;
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
}
.site-footer .mh-foot-pin::before {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E");
}
.site-footer .mh-foot-phone::before {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384'/%3E%3C/svg%3E");
}
.site-footer .mh-foot-fax::before {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6'/%3E%3Crect x='6' y='14' width='12' height='8' rx='1'/%3E%3C/svg%3E");
}
.site-footer .mh-foot-mail::before {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7'/%3E%3Crect x='2' y='4' width='20' height='16' rx='2'/%3E%3C/svg%3E");
}

/* Legal fine print. Ted asked for 0.6rem, which reads fine in a browser whose
   root is 20px — but at the standard 16px root that is 9.6px, and this block
   carries the HIPAA and A.R.S. § 32-1401 notices on a site whose audience is
   seniors. 0.7rem keeps the deliberately-small fine-print look (11.2px at a
   16px root) without dropping under the ~11px mark where body text starts
   getting genuinely hard to read. Revert to 0.6rem if you prefer the smaller
   setting — it is one value. */
.site-footer .mh-foot-legal {
	font-size: 0.7rem;
	line-height: 1.85;
}

/* Social buttons. The label text stays in the markup (and so in the
   accessible name) and is collapsed visually with font-size: 0 — the icon is
   sized in px, so it is unaffected. */
.site-footer .mh-social-row {
	display: flex;
	align-items: center;
	gap: 0.6rem;
	margin-top: 2rem;
}
.site-footer .mh-social {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 9999px;
	background-color: rgba(252, 251, 247, 0.12);
	color: rgba(252, 251, 247, 0.75);
	font-size: 0;
	text-decoration: none;
	transition:
		background-color 0.3s ease,
		color 0.3s ease;
}
.site-footer .mh-social:hover,
.site-footer .mh-social:focus {
	background-color: rgba(252, 251, 247, 0.2);
	color: var(--mh-olive);
}
.site-footer .mh-social::before {
	content: "";
	width: 16px;
	height: 16px;
	background-color: currentColor;
	-webkit-mask: var(--mh-icon) center / contain no-repeat;
	mask: var(--mh-icon) center / contain no-repeat;
}
.site-footer .mh-social-fb::before {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z'/%3E%3C/svg%3E");
}
.site-footer .mh-social-li::before {
	--mh-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce) {
	.site-footer .mh-social {
		transition: none;
	}
}

/* --- Footer link hover -----------------------------------------------------
   GeneratePress prints a global `a:hover{color:var(--contrast)}` (#222222)
   inline, which outranked the GB per-block colours — every footer link turned
   near-black ON THE DARK GREEN footer on hover (~1.9:1, effectively
   vanishing). The mockup hovers footer links to the olive accent. :not()
   guards keep this off the two footer links with their own treatments — the
   social circles (own hover above) and the olive Register pill, whose ink
   text must never turn olive-on-olive; it instead darkens like the header's
   at-top pill. */
.site-footer a:not(.mh-social):not(.mh-foot-cta):hover,
.site-footer a:not(.mh-social):not(.mh-foot-cta):focus-visible {
	color: var(--mh-olive);
}
.site-footer a.mh-foot-cta:hover,
.site-footer a.mh-foot-cta:focus-visible {
	background-color: #a6a45b;
	color: var(--mh-ink);
}

/* =========================================================================
   FORMS (Forminator)
   Forminator renders its own markup, so it can't be styled per-block in
   GenerateBlocks — this maps its fields onto the design tokens so the forms
   read as part of the site rather than a plugin default.

   Every declaration in this block is !important, and has to be: Forminator
   ships its own design-system stylesheet keyed on ids and inline styles that
   outrank any sane theme selector. This block and the mobile menu fill are
   the theme's TWO !important sites; both are deliberate. Selectors trimmed
   2026-08-04 to the field types form 108 actually uses (text, email, phone,
   textarea, submit) — re-add checkbox/select/radio mappings only when a form
   gains those fields.
   ========================================================================= */
.forminator-ui .forminator-label {
	font-family: var(--mh-font-body) !important;
	color: var(--mh-ink) !important;
}
.forminator-ui .forminator-description {
	font-family: var(--mh-font-body) !important;
	color: var(--mh-sage) !important;
}
.forminator-ui input.forminator-input,
.forminator-ui textarea.forminator-textarea {
	font-family: var(--mh-font-body) !important;
	font-size: 1rem !important;
	color: var(--mh-ink) !important;
	background-color: var(--mh-white) !important;
	border: 1px solid var(--mh-sand) !important;
	border-radius: 12px !important;
}
.forminator-ui input.forminator-input:focus,
.forminator-ui textarea.forminator-textarea:focus {
	border-color: var(--mh-sage) !important;
	box-shadow: 0 0 0 3px rgba(99, 112, 97, 0.12) !important;
}
/* Submit: the mockup's full-width sage pill with a leading Send glyph and a
   bg-primary/90 hover — ours was an auto-width forest pill with a darkening
   hover, contradicting the primary-button parity rule (fixed 2026-08-04). */
.forminator-ui button.forminator-button-submit {
	display: inline-flex !important;
	align-items: center !important;
	justify-content: center !important;
	gap: 0.55rem !important;
	width: 100% !important;
	padding: 16px 32px !important;
	border-radius: var(--mh-radius-pill) !important;
	background: var(--mh-sage) !important;
	color: var(--mh-white) !important;
	font-family: var(--mh-font-body) !important;
	font-weight: 700 !important;
	font-size: 1rem !important;
	line-height: 1 !important;
	transition: background-color 0.3s ease !important;
}
.forminator-ui button.forminator-button-submit::before {
	content: "";
	flex: 0 0 auto;
	width: 1em;
	height: 1em;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z'/%3E%3Cpath d='m21.854 2.147-10.94 10.939'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z'/%3E%3Cpath d='m21.854 2.147-10.94 10.939'/%3E%3C/svg%3E") center / contain no-repeat;
}
.forminator-ui button.forminator-button-submit:hover,
.forminator-ui button.forminator-button-submit:focus-visible {
	background: rgba(99, 112, 97, 0.9) !important;
}

/* =========================================================================
   MOBILE
   Everything below is measured, not guessed — see the 375px iframe harness
   recipe in CLAUDE.md. Deliberately last in the file and entirely inside
   max-width media queries, so no desktop rule is touched.
   ========================================================================= */

/* --- "Why Families Choose Us": 4 columns, then straight to 2 -------------
   The block ships `repeat(auto-fit, minmax(220px, 1fr))`, which steps down
   4 → 3 → 2 → 1 as the viewport narrows. A 3-up row leaves one card orphaned
   on a second line, so the client asked for it to jump 4 → 2 (two tidy rows
   of two) at the point it currently breaks to 3, ~1135px.

   Matched with `:has(.mh-icon-badge)` rather than the block's uniqueId:
   verified in the DOM that all four badges live in this grid and no other
   `.mh-stagger` contains one, so this survives the block being rebuilt with
   fresh uniqueIds — which a GenerateBlocks round-trip will do.

   ≤640px is already handled by the MOBILE block's grid guard
   (`.mh-stagger` → `minmax(0, 1fr)`), so this only needs the middle step. */
@media (max-width: 1135px) {
	.entry-content .mh-stagger:has(.mh-icon-badge) {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* --- Header CTA while the menu is collapsed ------------------------------
   Printed into .inside-header by functions.php. Hidden everywhere by default;
   the band rule below is the only place it appears, so above 1335px the nav's
   own li.mh-nav-cta is the single Register Now and there is never a duplicate
   link in the accessibility tree.

   Deliberately NOT sharing a selector with the nav pill: that one is reached
   through `.main-navigation .main-nav > ul > li.mh-nav-cta > a` (0,4,1), which
   only exists inside the menu. Same tokens, same measurements, own rule. */
.mh-header-cta {
	display: none;
	align-items: center;
	flex: 0 0 auto;
	padding: 12px 26px;
	border-radius: 9999px;
	background-color: var(--mh-olive);
	color: var(--mh-ink);
	font-family: var(--mh-font-body);
	font-size: 0.95rem;
	font-weight: 700;
	line-height: 1.5;
	text-decoration: none;
	white-space: nowrap;
	/* Same layered ring as the nav pill: a band in the header's OWN colour so
	   it reads as a gap, then the translucent olive halo, then the lift. The
	   inner band has to track the header state or it draws a dark outline on
	   the pale bar. */
	box-shadow:
		0 0 0 2px var(--mh-paper),
		0 0 0 4px rgba(184, 182, 101, 0.4),
		0 8px 12px -4px rgba(0, 0, 0, 0.1);
	transition: background-color 0.3s ease, box-shadow 0.3s ease;
}
.site-header.mh-at-top .mh-header-cta {
	box-shadow:
		0 0 0 2px var(--mh-forest),
		0 0 0 4px rgba(184, 182, 101, 0.4),
		0 8px 12px -4px rgba(0, 0, 0, 0.1);
}
.mh-header-cta:hover,
.mh-header-cta:focus-visible {
	background-color: #a6a45b;
	color: var(--mh-ink);
}

/* The band where the menu is collapsed but the bar still has room for a pill.
   Lower bound 769px = just above the phone block, where the wordmark already
   uses the full row; upper bound 1335px = GP's mobile-menu breakpoint, above
   which the real nav (and its own CTA) is back. */
@media (min-width: 769px) and (max-width: 1335px) {
	.mh-header-cta {
		display: inline-flex;
		/* Sit beside the hamburger rather than against it. The toggle carries
		   margin-left:auto, so this pill is pushed right along with it. */
		margin-left: auto;
	}
	/* With the pill taking the auto margin, the toggle needs only a small fixed
	   gap. ⚠️ This MUST out-specify `.site-header .mobile-menu-control-wrapper`
	   in the 1335 block below, which sets `margin-left: auto` (correct at
	   ≤768px, where there is no pill to push). Written at (0,2,0) it lost on
	   source order — the 1335 block comes later — so BOTH elements claimed the
	   free space, split it evenly, and stranded the pill mid-header. The extra
	   `.inside-header` makes this (0,3,0) and order-independent. */
	.site-header .inside-header .mobile-menu-control-wrapper {
		margin-left: 0.75rem;
	}
}

/* =========================================================================
   COLLAPSED HEADER — must track GP's mobile-menu breakpoint
   GP Premium's Menu Plus swaps the nav for the hamburger at
   `mobile_menu_breakpoint`, raised from 768 to **1335** on 2026-08-06 (the
   measured width where the 862px nav stops fitting beside the wordmark: at
   1335 there is still a 31px gap, at 1300 the header wraps to 158px).

   Everything in this block is what makes the COLLAPSED header work, so it has
   to span the same range GP does. Keeping it at 768 left the toggle rendering
   in GP's default #222 — invisible on the dark bar — and the open panel
   transparent, for every width from 769 to 1335. Phone-only COMPRESSIONS
   (logo size, wordmark size, type scale, section padding) stay in the 768px
   block below; they would be wrong on a 1200px screen.
   ⚠️ If the Customizer breakpoint is ever changed, change this query with it.
   ========================================================================= */
@media (max-width: 1335px) {
	.site-header .inside-header {
		/* Stays WRAP on purpose. GP's collapsible nav is a flex child with
		   flex-basis: 100% — it is meant to take a row of its own below the
		   bar. Forcing nowrap squeezes it onto line 1 and crushes the logo to
		   13px. Instead: let the branding grow, pin the toggle right with an
		   auto margin, and the 100%-basis nav wraps to line 2 as designed. */
		flex-wrap: wrap;
		align-items: center;
		gap: 0.5rem;
		/* Top padding only. The 100%-basis nav below is a zero-height row when
		   the menu is closed, so bottom padding just banked dead space under
		   the bar — the gap above it already separates the rows. (Two values
		   on padding-block = top, bottom.) */
		padding-block: 0.55rem 0;
	}
	.site-header .site-logo {
		flex: 0 0 auto;
	}
	.site-header .site-branding {
		flex: 1 1 auto;
		min-width: 0;
	}
	.site-header .mobile-menu-control-wrapper {
		flex: 0 0 auto;
		margin-left: auto;
	}
	.site-header .main-navigation:not(.mobile-menu-control-wrapper) {
		flex: 0 0 100%;
	}

	/* The hamburger inherits #222 from GP, which is invisible against the
	   dark green bar — that is most of why the menu read as "broken". */
	.site-header .menu-toggle {
		color: var(--mh-ink);
	}
	.site-header.mh-at-top .menu-toggle {
		color: var(--mh-paper);
	}
	.site-header .menu-toggle .gp-icon svg {
		fill: currentColor;
	}

	/* The open menu panel must be OPAQUE. The bar is rgba(44,62,54,0.8) so it
	   can blend with the hero, but that let the hero's headline and body copy
	   read straight through the dropdown. GP marks the open state with
	   .toggled on the nav, so the panel can be filled without touching the
	   translucent bar above it.
	   GP puts .toggled on BOTH .main-navigation elements — the menu panel AND
	   the little toggle wrapper — so the :not() is required or the fill lands
	   on the 55px button instead of the panel.
	   !important is deliberate and narrow. GeneratePress paints this panel
	   rgba(0,0,0,.02) from its own stylesheet and wins the cascade even at
	   (0,4,0) — the rule below is in the CSSOM and its selector matches, but
	   the computed value stays GP's. Rather than escalate the selector into
	   something unreadable, the two background declarations are forced. */
	.site-header .main-navigation.toggled:not(.mobile-menu-control-wrapper) {
		background-color: var(--mh-paper) !important;
	}
	.site-header.mh-at-top .main-navigation.toggled:not(.mobile-menu-control-wrapper) {
		background-color: var(--mh-forest) !important;
	}

	/* Inside the dropdown the CTA is just another menu row, so strip the pill.
	   A full-width olive button stacked under five text links read as a
	   different kind of thing and fought the panel — and the bar already
	   carries a real Register Now pill in this range (.mh-header-cta), so the
	   emphasis is not lost, only de-duplicated.

	   This resets every property the pill rule sets, in the same order, so
	   nothing is left half-applied: fill, text colour, ring, the sentence-case
	   overrides, and the 1.5 line-height that existed only to tame GP's 60px
	   nav line-height on a padded pill. Colours then fall through to the
	   normal nav-link rules for each header state. */
	/* ⚠️ The at-top pill rule is
	   `.site-header.mh-at-top .main-navigation .main-nav > ul > li.mh-nav-cta > a`;
	   a reset written only against the default rule loses to it over the hero
	   and the fill and ring survive in the dropdown. So both states are reset
	   explicitly — and each is given the SAME colour the plain links get in
	   that state rather than `inherit`. `inherit` was the first attempt and it
	   was worse than useless: being more specific than the state colour rules,
	   it out-ranked them and resolved to body ink, which on the forest panel
	   over the hero is all but invisible. */
	.main-navigation .main-nav > ul > li.mh-nav-cta > a {
		background-color: transparent;
		box-shadow: none;
		font-size: 0.75rem;
		font-weight: 300;
		text-transform: uppercase;
		letter-spacing: 0.05em;
		line-height: inherit;
		/* Cream panel (scrolled) — matches the plain links. */
		color: rgba(44, 49, 43, 0.7);
		/* Box metrics, not just paint. The pill is set up by TWO rules — the
		   opt-in block near SITE HEADER adds `margin-left: 1.25rem` and
		   `padding: 14px 32px` on top of the colour rule further down — and
		   leaving them indented the row 47px past its siblings. Measured: the
		   plain links sit at `padding: 0 10px` with no margin, so match that
		   exactly rather than eyeballing a value. */
		margin-left: 0;
		padding: 0 0.5rem;
		border-radius: 0;
        line-height: 60px;
	}
	.site-header.mh-at-top .main-navigation .main-nav > ul > li.mh-nav-cta > a {
		background-color: transparent;
		box-shadow: none;
		/* Forest panel (over the hero) — matches the plain links. */
		color: var(--mh-paper);
        line-height: 60px;
	}
	.main-navigation .main-nav > ul > li.mh-nav-cta > a:hover {
		background-color: transparent;
		color: var(--mh-forest);
	}
	.site-header.mh-at-top .main-navigation .main-nav > ul > li.mh-nav-cta > a:hover {
		background-color: transparent;
		color: var(--mh-white);
	}
}

/* =====================================================================
   HOMEPAGE HERO — the photo-band treatment, up to 1024px (Ted, 2026-08-07)

   Its own media query, NOT the 768px MOBILE block, and the breakpoint is
   deliberately different. 768 is where the PHONE compressions live (180px
   logo, 2.3rem h1, 3.5rem section rhythm, FormDr handoff); none of those
   belong on a tablet. The hero band is a separate concern with a separate
   reason to move: the full-bleed `cover` hero fails on any tall-and-narrow
   box, and portrait tablets are the worst case on the site. Measured source
   px shown / resample at 2x, BEFORE this change: 810x1080 -> 706px, 2.30x;
   820x1180 -> 654px, 2.51x; 1024x1366 -> 705px, 2.90x. After: a constant
   934px at 2.19x or better.

   ⚠️ Keep this block ABOVE the 768px block. Nothing here depends on source
   order (the section rule carries :not(.mh-hero-dark) to out-specify the
   vertical-rhythm rule down there) but the reading order matters: band
   first, then the phone-only compressions layered on top.

   ⚠️ 1024 is also the ceiling for `--mh-hero-band-top: 78px`. The header
   measures exactly 78px at every width from 375 to 1024 — the ≤768 rule
   sizes the logo by width (180px) and the desktop rule by height (56px),
   and the two happen to land on the same bar height. Above 1024 that is no
   longer checked. Re-measure before widening this query again.
   ===================================================================== */
@media (max-width: 1024px) {
	/* --- Hero: photo BAND, not a full-bleed background (2026-08-07) -------
	   The desktop overlay is a 100deg gradient shielding the LEFT third, where
	   the desktop text column sits. On mobile the text runs full width, so the
	   photo showed straight through it and needed a vertical scrim — and two
	   rounds of tuning that scrim never fixed the real problem, which is
	   geometric, not a question of opacity:

	   The hero box on a phone is 375x812 — aspect 0.46 — and the photograph is
	   1672x941, aspect 1.78. Filling that box with `cover` scales the image to
	   1443x812 and shows a 375px-wide slice of it: **434 of 1672 source pixels,
	   26% of the frame.** That slice contains one shoulder and the side of the
	   elderly woman's head — no second person, no scene, no story. It is also
	   *upscaled 1.73x* on a 2x phone (434 source px painted into 750 device
	   px), so the one thing it does show is soft. No gradient can rescue that;
	   any scrim tuned to keep the copy readable lands squarely on her face,
	   which is exactly what Ted reported seeing.

	   Panning is not a lever either: at this aspect `cover` leaves 0px of
	   vertical overflow, so background-position-y does nothing, and horizontal
	   panning only trades one 434px slice for another.

	   So the photograph stops trying to fill the box. It becomes a BAND across
	   the top, sized to the phone's width, with the copy on solid cream below
	   it. Measured at 375px with the band geometry set below: the visible crop
	   is 934 source px — both women, the doors, the room — and it *downscales*
	   0.80x instead of upscaling, so it is sharp. Nothing is veiled at all: the
	   scrim is fully transparent over the photo and only fades its bottom edge
	   into the cream bed.

	   ⚠️ THE THREE VALUES BELOW ARE COUPLED. The image layer's box, the scrim's
	   fade stops and the copy's top offset all derive from these two custom
	   properties — change one number, not four. */
	/* ⚠️ The `:not(.mh-hero-dark)` is LOAD-BEARING, not decoration. Without it
	   this reads (0,2,1) — exactly the same as the vertical-rhythm rule further
	   down this same media query, `.entry-content > section:not(.mh-hero-dark)`,
	   which sets 3.5rem top and bottom. Equal specificity, and that rule comes
	   later, so it won on source order and the padding-top:0 below silently did
	   nothing (caught by measuring: the section still reported 3.5rem top). The
	   extra class takes this to (0,3,1) and makes it order-independent. */
	.entry-content > section:has(.mh-hero-scrim):not(.mh-hero-dark) {
		/* The FIXED header's height at this width — measured, 78px at 375px and
		   768px alike (the ≤768 rule sizes the logo to 180px wide, so the bar
		   is the same height across the whole phone range). The band starts
		   below it because the photograph has only ~40 source px of headroom
		   above the caregiver's hair: at any scale that fits the band, heads
		   land in the top 20px, and anchoring the band at 0 would slide them
		   behind the header. */
		--mh-hero-band-top: 78px;
		/* The hero's target height. `100svh` alone is right for a phone and
		   wrong for a narrow, very tall window: the photo band is capped by
		   coverage (see below) and the copy is a fixed block, so everything
		   past ~1100px becomes dead cream under the buttons — measured 657px of
		   it at 500x1600. Beyond that height a full-viewport hero stops reading
		   as a hero and starts reading as a mistake, so it caps out and the
		   next section peeks instead, which is a better scroll cue anyway.
		   Real phones (≤932px tall) never reach the cap and are unaffected. */
		--mh-hero-h: min(100svh, 1100px);
		min-height: var(--mh-hero-h);
		/* VISIBLE photo height, below the header. Three terms, each load-bearing:

		   `72vw` is the baseline. It tracks width rather than sitting at a flat
		   270px so the band keeps roughly one aspect ratio across the range:
		   the background-size below fixes the HORIZONTAL crop, so the band's
		   height is what decides how far down the photo is cut. A flat 270px at
		   768px wide cut through the elderly woman's chin.

		   `var(--mh-hero-h) - 640px` is what makes the band EAT THE SLACK on a
		   tall viewport. 640 ≈ everything below the band at its worst (78
		   header + 16 gap + ~435 copy + 20 + 50), deliberately over-estimated
		   so the band lands slightly short and the leftover falls harmlessly
		   past the copy rather than pushing it off-screen. It reads the CAPPED
		   height, not raw `100svh`, so the band and the hero agree about how
		   tall the hero is.

		   The ceiling is the SMALLER of two limits, and both are needed:

		     `98vw` is a COVERAGE limit — at `background-size: 179%` the painted
		     height comes out at 1.0074x the band's width, so a band taller than
		     that stops covering and exposes a strip along its bottom edge. 98vw
		     keeps ~2% of margin against subpixel rounding.

		     `--mh-hero-h - 480px` is a BUDGET limit, and it is what makes 72vw
		     safe on a wide, SHORT viewport. 72vw is a sane shape on a phone,
		     where width and height are correlated — but at 1024x768 (a landscape
		     iPad) it asks for a 737px band inside a 768px viewport, which would
		     have pushed the entire headline below the fold. 480 ≈ the smallest
		     "everything below the band" gets at these widths (78 header + 16 gap
		     + ~300 copy + 20 + 40 ≈ 454), so the cap bites only when it must:
		     measured, it changes nothing at 375, 390, 430, 500 or 768 and takes
		     1024x768 from 737 down to 288.

		   ⚠️ At 375px the whole budget is 812 - 78 - 16 - 387 - 20 - 40 = 271,
		   so the phone case is still exactly as tight as it was; the svh term
		   is negative there and never fires. Re-measure at 375 AND at a tall
		   narrow window before touching any of the three. */
		/* ⚠️ The FLOOR is `max(240px, 28vw)`, not a flat 240px, and the 28vw is
		   the second half of the face guard. Once the guard has zoomed all the
		   way out to full-frame width there is nothing left to give, and the
		   only thing still deciding the vertical crop is the band's own height:
		   srcH = band x 1672 / width, so both faces (source y 40-450) need
		   band ≥ 0.275 x width. 28vw is that with a hair of margin. Without it,
		   1024x600 squeezed the band to 240px and cut at source y=392 — through
		   the elderly woman's mouth.
		   Consequence, accepted: on a very short landscape window the floor
		   wins over the budget and the hero runs past the fold. That is the
		   right trade — the hero already overflows on short viewports (320x568,
		   360x640), and a scroll beats a strip of cropped faces.
		   ⚠️ The `+ 28px` pays for the layer's `right: -100px` overhang. The
		   crop is computed against the layer's BOX, which is `100vw + 100px`,
		   not the viewport — so the ratio is band/(W+100), and 0.275 x 100 = 27.5
		   has to be added back. Without it the overhang silently re-broke the
		   guard at 900x700, 1024x600 and 1024x768 (srcH 421-428 against the 460
		   the faces need). If the overhang changes, this changes with it. */
		--mh-hero-band-h: clamp(
			max(240px, calc(28vw + 28px)),
			max(72vw, var(--mh-hero-h) - 640px),
			min(98vw, var(--mh-hero-h) - 480px)
		);
		/* ⚠️ flex-start, NOT center — this was the 2026-08-07 regression Ted
		   caught at 500x1290. The section is `display:flex` with
		   `min-height:100svh`, so with `align-items:center` any leftover space
		   is split ABOVE and BELOW the wrapper — and "above the wrapper" is
		   between the photograph and the copy. Measured before the fix: a
		   **182px** hole at 500x1290 and 101px at 768x1024, against 17px at
		   375x812. Every viewport I had tested was phone-shaped, where the
		   content exactly fills 100svh and there is no leftover to split, so
		   the bug was invisible in the harness and obvious in a narrowed
		   desktop window.
		   flex-start pins the copy a fixed 16px under the band at every size;
		   whatever slack the band could not absorb falls past the buttons,
		   where the scroll cue lives. padding-top is 0 so the copy's offset is
		   exactly the wrapper's padding-top, with nothing re-derived through
		   flex alignment. */
		align-items: flex-start;
		padding-top: 0;
		padding-bottom: 2.5rem;
	}
	/* ⚠️ (0,2,0), same as the global crop rule at the top of the file, so this
	   wins on source order alone — keep it below that rule.

	   The size is WIDTH-relative and that is the whole trick. 179% means the
	   image is painted 1.79x the band's width, so the band always shows
	   1672/1.79 = **934 source px** of the photograph — the same framing at
	   every viewport — and the painted height comes out at 1.007x the band's
	   width, which is always taller than the band, so it always covers. An
	   earlier `auto 140%` did the same job at 375px but pinned the image to a
	   flat 672px wide: past a ~672px viewport it stopped covering and left a
	   bare vertical strip down the left of the band. Caught at 768px.

	   934px is measured, not chosen: it frames from source x=737, and the
	   caregiver's back sits at ~850, so she is whole with 110px to spare.
	   Anchored `right top` because `center` and `bottom` both cut her hair —
	   the photograph has only ~40 source px of headroom above it. */
	.entry-content .gb-element-mhheroimg {
		top: var(--mh-hero-band-top);
		bottom: auto;
		height: var(--mh-hero-band-h);
		/* NOTE: `right: -100px` is NOT redeclared here — it moved to the global
		   .gb-element-mhheroimg rule on 2026-08-07 when Ted extended it to the
		   desktop hero, and this block inherits it.
		   ⚠️ It still does TWO things here, not one, because the background-size
		   below is a percentage of the BOX: widening the box by 100px also
		   enlarges the painted image by the same 179%, so the crop both pans
		   AND zooms ~20% at a 500px viewport. Net effect measured there: the
		   left edge of the crop stays put at source x=738 while the right edge
		   pulls in from 1672 to 1516, so the pair sit larger and closer.
		   Re-measure the face guard after changing it — the guard's
		   `calc(band * 3.55)` term is box-width-independent, so the two terms
		   move relative to each other. */
		/* ⚠️ Three terms; a flat `179%` was wrong once the range reached 1024.
		   Read them inside-out:

		   `calc(band * 3.55)` is a FACE GUARD. The band is anchored `top`, so
		   the vertical crop is `band x 1672 / paintedWidth` — the shorter the
		   band relative to the width, the higher up the photo gets cut. On a
		   short landscape viewport (1024x768, 900x700) the budget squeezes the
		   band to ~240-288px and a fixed 179% cut at source y=249 — straight
		   through both faces, chins are at ~450. 3.55 = 1672/471, i.e. "never
		   zoom past what still shows 471 source px of height".

		   `min(179%, …)` keeps the designed framing wherever the guard is not
		   binding — which is every phone and every portrait tablet.

		   `max(100%, …)` is the coverage floor: below 100% the image stops
		   spanning the band's width. It also makes the short-landscape case
		   land on exactly full-frame width, which is the sharpest the source
		   can do (2.19x -> 1.25x resample at 1024x768).

		   The 934px framing that the rest of this block's numbers assume is the
		   179% case. Where the guard bites, the crop widens instead — a wider,
		   sharper, less intimate frame, which is the right trade when the
		   alternative is cropping through somebody's eyes. */
		background-size: max(100%, min(179%, calc(var(--mh-hero-band-h) * 3.55))) auto;
		background-position: right top;
	}
	/* Clear over the whole photograph, a 40px fade at its bottom edge so the
	   band does not end on a hard rule, then a solid cream bed the copy sits
	   on. Solid, not 0.93: the bed has to hide the section's sand background
	   rather than tint it. */
	.entry-content .mh-hero-scrim {
		background: linear-gradient(
			180deg,
			rgba(252, 251, 247, 0) 0,
			rgba(252, 251, 247, 0) calc(var(--mh-hero-band-top) + var(--mh-hero-band-h) - 40px),
			rgba(252, 251, 247, 1) calc(var(--mh-hero-band-top) + var(--mh-hero-band-h)),
			rgba(252, 251, 247, 1) 100%
		);
	}
	/* Matched via :has(.mh-hero-scrim) rather than the block's uniqueId — that
	   survives a GenerateBlocks round-trip, and it picks out the HOMEPAGE hero
	   only. A `section:first-of-type` selector would also hit the inner pages'
	   .mh-hero-dark heroes and wreck their 11rem top padding. */
	.entry-content > section:has(.mh-hero-scrim) > .mh-wide {
		padding-top: calc(var(--mh-hero-band-top) + var(--mh-hero-band-h) + 16px);
		padding-bottom: 20px;
	}
	/* 40px below the lead paragraph is desktop rhythm; on a phone it is 12px
	   of the photo band's budget. Nothing else in the hero has slack. */
	.entry-content > section:has(.mh-hero-scrim) p {
		margin-bottom: 1.75rem;
	}
}

@media (max-width: 768px) {
	/* --- Header: phone-only compressions -------------------------------
	   Structure lives in the 1335px block above; only the size reductions
	   that would look wrong on a tablet belong here. */
	/* Sized by WIDTH here, unlike the desktop rule, because width is the
	   dimension the phone header is actually budgeted on — the logo, the
	   toggle and the gaps share one flex row. 180px (client's call,
	   2026-08-07) works out to ~49px tall at the lockup's 3.70:1; the earlier
	   40px height gave only 148px and read too small.
	   `max-height` has to be cleared as well — the desktop rule sets one, and
	   left in place it would cap the height and quietly break the aspect. */
	.site-header .site-logo img,
	.site-header img.header-image {
		width: 180px;
		height: auto;
		max-height: none;
	}
	/* ⚠️ MEASURED CEILING — do not raise without re-measuring at 360px.
	   ⚠️ ALSO CURRENTLY UNRENDERED (.site-branding is display:none) and measured
	   in a face the site no longer loads: Brice Expanded set "Mulberry Health"
	   at 254px where the old Cormorant set it at 139px, so the ceiling below is
	   conservative by roughly that factor now. The mark, the wordmark and GP's menu toggle share one
	   flex row, and that row's budget at a 360px viewport is ~197px of
	   wordmark: 0.87rem still fits, 0.88rem wraps the header from 92px to
	   139px. 0.85rem (191px) is used instead of the 0.87rem ceiling so a
	   slightly wider render on another platform can't tip it over.

	   The tree mark stays at its full 34px (client's call, 2026-08-06).
	   Shrinking it to 28px was measured and moves the ceiling not at all —
	   the constraint is the toggle and the gaps, not the mark's width — so
	   there is nothing to gain by making it smaller.

	   Known and accepted: below ~340px (a 320px device) NO readable size fits
	   one row with the mark — even 0.7rem wraps — so those rare viewports get
	   the taller two-row header. That degrades gracefully; the header still
	   works, it is simply 139px. */
	.site-branding .main-title,
	.site-branding .main-title a {
		font-size: 1rem;
	}

	/* --- Type scale ---------------------------------------------------
	   The desktop h1 lands at 55px here, which wrapped to four lines. */
	.entry-content h1 {
		font-size: 2.3rem;
		line-height: 1.1;
	}
	.entry-content h2 {
		font-size: 1.9rem;
		line-height: 1.15;
	}
	.entry-content h3 {
		font-size: 1.2rem;
	}


	/* --- Vertical rhythm ----------------------------------------------
	   6rem section padding is a lot of dead scroll on a phone. The hero is
	   excluded: it must keep enough top padding to clear the FIXED header. */
	.entry-content > section:not(.mh-hero-dark) {
		padding-top: 3.5rem;
		padding-bottom: 3.5rem;
	}
	.entry-content .mh-hero-dark {
		padding-top: 7rem;
		padding-bottom: 3.5rem;
	}
}

@media (max-width: 640px) {
	/* --- Stats card: two up, not stacked -------------------------------
	   The generic small-screen grid guard collapses .mh-stagger to one
	   column, which left four stats in a 666px-tall column. Four short
	   number/label pairs read better two-up. */
	.entry-content .mh-glass-card .mh-stagger {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 1.75rem 1rem;
	}
	.entry-content .mh-glass-card {
		padding: 2rem 1.25rem;
	}
	.entry-content .mh-overlap {
		margin-top: -28px;
	}

	/* --- Buttons: full-width tap targets --------------------------------
	   Scoped to .entry-content so the fixed floating CTA is unaffected;
	   .mh-card-link carries none of these classes and stays inline. */
	.entry-content .mh-btn-primary,
	.entry-content .mh-btn-arrow,
	.entry-content .mh-btn-phone,
	.entry-content .mh-btn-secondary {
		width: 100%;
		max-width: 22rem;
		justify-content: center;
	}

	/* Outline buttons ring themselves in 1px --mh-sand, which all but
	   disappears against the hero's cream scrim — the button read as a stray
	   line of bold text. A sage ring at 1.5px reads as a button. Mobile only:
	   on desktop the subtle sand ring sits on white cards and is fine.
	   :not(.mh-btn-primary) is a guard — a filled button must never pick up
	   the outline treatment and lose its white-on-sage contrast. */
	.entry-content .mh-btn-secondary:not(.mh-btn-primary) {
		box-shadow: inset 0 0 0 1.5px var(--mh-sage);
		color: var(--mh-forest);
	}

	/* Roomier padding is desktop luxury; on a phone it eats the content.
	   (.mh-cta-card is NOT here — its own 640px rule beside the card styles
	   already sets 3rem 1.5rem; it was duplicated in both places until
	   2026-08-04.) */
	.entry-content .mh-service-panel {
		padding-left: 1.5rem;
		padding-right: 1.5rem;
	}

	/* The contact rows lose ~44px to the icon badge, leaving about 260px of
	   text column — narrower than "referrals@mulberrymedical.net" set at 1rem
	   bold, so the address broke mid-domain ("...mulberrymedi / cal.net").
	   Dropping a step fits it on one line; break-word is a backstop for any
	   longer value added later. */
	.entry-content .mh-contact-row p {
		font-size: 0.8rem;
		overflow-wrap: break-word;
	}

	/* Same "roomy on desktop, ruinous on a phone" problem, measured rather
	   than guessed: at a 360px viewport these cards were left with a 230px
	   content column. */
	.entry-content .mh-exec-card,
	.entry-content .mh-info-panel {
		padding-left: 1.5rem;
		padding-right: 1.5rem;
	}

	/* The care cards reserve 107px on the left (1.75rem + 52px avatar + 1rem)
	   for the absolutely-positioned avatar. Once the grid is 1-up that left
	   half of the card is wasted and the text column collapsed to 168px — the
	   worst measure on the site. Drop the avatar above the text, exactly as
	   .mh-service-panel already does at 600px. */
	.entry-content .mh-care-card {
		padding: calc(1.5rem + 52px + 0.85rem) 1.5rem 1.5rem;
	}
	.entry-content .mh-care-avatar {
		top: 1.5rem;
		left: 1.5rem;
	}

	/* The FormDr intake form is a CROSS-ORIGIN iframe — its internal layout
	   cannot be restyled from here, so the only lever is how much width we
	   hand it. The block editor gives this card 50px of side padding and its
	   .mh-wide parent another 25px, which left the form 208px at a 360px
	   viewport; FormDr's own responsive layout gives up well before that and
	   was breaking "Patient Registration" into four-character lines.
	   Nearly full-bleed here buys back ~120px and lets FormDr's mobile
	   layout do its job.

	   Matched with :has() rather than a class added in the editor on purpose:
	   the embed is a pasted third-party snippet, so this keeps working if the
	   client ever re-pastes it and loses an editor-assigned class. Covers BOTH
	   wrapper variants — .formdr-embed (/register) and
	   .responsive-iframe-wrapper (/services, incl. the white card this theme
	   draws around it at desktop) — keying on a single class silently missed
	   /services once already.

	   Only applies down to 481px — below that the embed is swapped out for the
	   handoff button (see the 480px block), and a button pinned to the screen
	   edges would look broken. */
	.entry-content .mh-wide:has(.formdr-embed),
	.entry-content .mh-wide:has(.responsive-iframe-wrapper),
	.entry-content div:has(> .code-block .formdr-embed),
	.entry-content div:has(> .responsive-iframe-wrapper) {
		padding-left: 0;
		padding-right: 0;
	}

	/* The Forminator contact form sits two padded wrappers deep — .mh-wide
	   (25px) + .mh-form-card (35px) + the block's own 50px — so its inputs
	   were left 138px wide. Nested padding is the recurring mobile failure on
	   this site: each layer looks reasonable alone and they only bite when
	   summed, which is why the audit measures the innermost content box
	   rather than any single element's padding. */
	.entry-content .mh-form-card {
		padding-left: 1.25rem;
		padding-right: 1.25rem;
	}
	.entry-content .mh-form-card > div {
		padding-left: 0;
		padding-right: 0;
	}

	/* Service Areas cards carry 50px of editor padding AND spend a 44px grid
	   column on the map pin, so the county list was reading in a 139px
	   column. Keep the pin-left layout (it is the design) and buy the width
	   back from the padding and the gutter instead. */
	.entry-content .mh-area-card {
		padding-left: 1.25rem;
		padding-right: 1.25rem;
		column-gap: 1rem;
	}

	/* Care Coordination rows reserve 94px on the left for the glyph. Same
	   trade as above: the icon-left row is worth keeping, the desktop-sized
	   gutters are not. */
	.entry-content .mh-coord-card {
		padding: 1.25rem 1rem 1.25rem calc(1rem + 44px + 0.75rem);
	}
	.entry-content .mh-coord-card::before {
		left: 1rem;
	}
}

/* --- Phone handoff to the FormDr form ------------------------------------
   Printed into the content by functions.php, immediately before the embed.
   Hidden by default: the embed is the primary path, and it stays the primary
   path everywhere it renders acceptably.

   Measured 2026-08-03 at frame widths 320/375/480/600 (inner viewports
   ~305/360/465/585 after the scrollbar). At ~465px and up the FormDr document
   is fine end to end — fields, Yes/No pairs, signature pad, "Save and Continue
   Later". At ~305px and ~360px the long checkbox labels in "Services
   Requested" collapse to two or three words a line.

   The real boundary is somewhere between 360 and 465; 480px is drawn at the
   top of the phone-portrait range (the widest common phone is 430px) so every
   portrait phone gets the handoff and tablets keep the embed. Deliberately
   NOT the 640px used elsewhere in the MOBILE block — at 640px the embed is
   still perfectly usable and swapping it out would cost a context switch for
   nothing.

   The form is cross-origin, so this is the only remaining lever: FormDr's own
   page gets the whole viewport instead of a nested iframe. */
.entry-content .mh-form-handoff {
	display: none;
}

@media (max-width: 480px) {
	.entry-content .mh-form-handoff {
		display: block;
		/* Its own gutter: the wrapper's padding is zeroed above so the EMBED
		   can run edge to edge, and a button must not inherit that. */
		padding-inline: 1.25rem;
		text-align: center;
	}
	.entry-content .mh-form-handoff p {
		margin: 0 0 1.5rem;
		color: var(--mh-sage);
		font-size: 0.95rem;
	}

	/* Pill geometry has to live here: every other button on the site gets it
	   from its GenerateBlocks per-block class, which injected markup has no
	   way to reuse. Colour, hover and the arrow still come from
	   .mh-btn-primary / .mh-btn-arrow, and the full-width tap-target rule in
	   the 640px block applies because this carries both classes. */
	.entry-content .mh-form-handoff-btn {
		display: inline-flex;
		align-items: center;
		padding: 16px 32px;
		border-radius: 9999px;
		font-family: var(--mh-font-body);
		font-size: 1rem;
		font-weight: 700;
		text-decoration: none;
		/* The label cannot fit on one line at phone widths — 26 characters of
		   1rem bold needs ~270px and only ~216px is available inside a 345px
		   viewport. Rather than shorten the label (it should say plainly what
		   the button does), let it set as a comfortable two lines: the site's
		   line-height:1 is for single-line pills and made these touch, and
		   `balance` avoids the lopsided "Open the Registration / Form" break. */
		line-height: 1.3;
		text-wrap: balance;
	}

	/* Hide whichever div directly wraps the FormDr iframe. Matched on the
	   iframe rather than a wrapper class because the embeds on this site are
	   wrapped differently (.formdr-embed on /register and /test,
	   .responsive-iframe-wrapper on /services) — and it must be the WRAPPER,
	   not the iframe: the wrappers carry a fixed pixel height (up to 5202px at
	   narrow widths) that would leave a huge empty gap behind.

	   The `.mh-form-handoff +` prefix is load-bearing, not decoration. The PHP
	   filter deliberately fails OPEN (any regex miss returns the content
	   untouched, because the embed is the load-bearing part), but this rule
	   would otherwise fail CLOSED — hiding the form whether or not a button
	   was inserted. On a medical intake page the two must not disagree: the
	   worst outcome is a phone with no form AND no button. The filter always
	   inserts the handoff as the wrapper's immediately-preceding sibling, so
	   this selector is exactly the condition "a replacement exists". If the
	   filter ever bails, the embed simply stays — cramped, but usable. */
	.entry-content .mh-form-handoff + div:has(> iframe[src*="formdr.com"]) {
		display: none;
	}
}

/* =========================================================================
   SECTIONS
   Page sections (hero, stats, mission, service lines, why-us, leadership,
   service areas, insurances, CTA) are built with GenerateBlocks on the Home
   page — not here. This block is intentionally empty; see CLAUDE.md.
   ========================================================================= */
