/*
Theme Name: Lotus Wellness
Theme URI: https://www.lotuswellnessclinic.ca/
Author: Lotus Wellness Psychology Clinic
Author URI: https://www.lotuswellnessclinic.ca/
Description: Custom block theme (FSE) for Dr. Nancy Bahl's virtual psychology practice serving adults across Ontario. Calming lotus brand: self-hosted Literata + Manrope, accessible sage/rose palette, locked owner-safe patterns — see docs/design-bible.md.
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.0
Version: 0.17.6
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: lotuswellness
Tags: full-site-editing, block-patterns, accessibility-ready, one-column, wide-blocks
*/

/*
 * Component CSS for things theme.json can't express (block-style variations, the eyebrow,
 * the credential pill, the FAQ caret + search, the contrast-aware focus ring). Every value
 * still comes from theme.json tokens via the --wp--preset--* custom properties. Locked specs
 * live in docs/design-bible.md §5; class names are the contract the patterns reference.
 */

/* ---------------------------------------------------------------------------
   BREAKPOINTS — the three view modes (H, 2026-07-06 — the "781 doctrine"):
     desktop  ≥1000px    nav row + Book button      @media (min-width: 1000px)
     tablet   782–999px  hamburger + Book button    @media (min-width: 782px) and (max-width: 999px)
     mobile   ≤781px     hamburger only, stacked    @media (max-width: 781px)
   This block is the single source of truth. CSS cannot read custom properties
   inside @media conditions, so every view-mode query copies its literal from
   here and tags itself with the mode name (e.g. "mobile (≤781)").
   Why 781: WP core stacks wp:columns below 782 with !important rules that
   cannot move — so the mobile line IS core's line, adopted rather than fought.
   EVERY layout switch must sit on one of the two lines (999/1000, 781/782):
   no auto-fit grids (they re-column at content-driven widths), no container
   queries, no bespoke breakpoints. Continuous INLINE wrapping (chips, the
   hero trust line, fluid clamp() values) is exempt — text flow, not layout.
   Decision log: docs/retros/2026-07-06-phase-8-responsive-menu.md.
   --------------------------------------------------------------------------- */

/* One home for the component corner radius (WordPress has no radius preset). */
:root {
	--lw-radius: 10px;
	--lw-radius-lg: 12px; /* the master's chip/box radius (footer logo chip, crisis box) */
	/* the shared statement column — one width for every capped text block inside
	   full/wide bands: the empathy + areas-of-focus contentSize (via var() in the
	   pattern attrs) and .lw-measure (CTA band). */
	--lw-column: 760px;
	/* ink hairlines — the master's rgba(55,50,45,.1/.08) rules, palette-derived */
	--lw-hairline: color-mix(in srgb, var(--wp--preset--color--contrast) 10%, transparent);
	--lw-hairline-soft: color-mix(in srgb, var(--wp--preset--color--contrast) 8%, transparent);
	/* soft body ink ≈ the master's #544a42 (crisis box, empathy lead) */
	--lw-ink-soft: color-mix(in srgb, var(--wp--preset--color--contrast) 50%, var(--wp--preset--color--contrast-2));
	/* warm off-white panel behind the header lotus mark + the hero photo/card —
	   palette-derived (a blend of surface + base) so it tracks theme.json. */
	--lw-logo-bg: color-mix(in srgb, var(--wp--preset--color--surface) 45%, var(--wp--preset--color--base));
	/* hero decoratives — derived from palette so editing theme.json restyles them */
	--lw-halo: color-mix(in srgb, var(--wp--preset--color--primary) 45%, transparent);
	--lw-dot: color-mix(in srgb, var(--wp--preset--color--accent) 65%, var(--wp--preset--color--base));
}

/* Match the master's crisper text rendering — lighter grayscale AA in place of
   the browser default's heavier subpixel AA (most visible on non-retina screens).
   Inherited by all text; pairs with the tighter heading tracking in theme.json. */
body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
}

/* ---------------------------------------------------------------------------
   Focus — visible on every interactive element; flip to cream on the one dark
   ground (the sage CTA band) so the ring always clears 3:1.
   --------------------------------------------------------------------------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible,
.wp-block-button__link:focus-visible {
	outline: 3px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
	border-radius: 4px;
}
.lw-cta :focus-visible,
.lw-cta .wp-block-button__link:focus-visible {
	outline-color: var(--wp--preset--color--base);
}

/* ---------------------------------------------------------------------------
   Eyebrow / kicker — small uppercase label above section headings.
   Colour is set per-instance via the block's textColor (primary / accent / surface).
   --------------------------------------------------------------------------- */
.lw-eyebrow {
	font-size: 0.8rem; /* the master's eyebrow size — sits between our small/medium tokens */
	font-weight: 700;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	line-height: 1.3;
}

/* ---------------------------------------------------------------------------
   Secondary button — core's "Outline" style as a brand-rose (accent) outline that
   matches the primary button geometry and fills (accent-hover) on hover. Padding is
   reduced by the 2px border so the box equals the borderless primary; radius/padding/
   weight mirror theme.json elements.button (no preset var exists for those).
   --------------------------------------------------------------------------- */
.wp-block-button.is-style-outline > .wp-block-button__link.wp-element-button {
	background-color: transparent;
	color: var(--wp--preset--color--accent);
	border: 2px solid var(--wp--preset--color--accent);
	border-radius: var(--lw-radius);
	padding: calc(0.7rem - 2px) calc(1.4rem - 2px);
	font-weight: 700;
}
.wp-block-button.is-style-outline > .wp-block-button__link.wp-element-button:hover,
.wp-block-button.is-style-outline > .wp-block-button__link.wp-element-button:focus {
	background-color: var(--wp--preset--color--accent-hover);
	border-color: var(--wp--preset--color--accent-hover);
	color: var(--wp--preset--color--base);
}

/* mobile (≤781, stacked layouts): CTA button rows sit on their own line
   site-wide, so centre them and stretch each button to the full container
   width (H). body- prefixed to outrank the block-support flex rules
   regardless of print order. */
@media (max-width: 781px) {
	body .wp-block-buttons {
		justify-content: center;
		width: 100%; /* also when the buttons block is a flex item (e.g. the empathy CTA row) */
	}
	body .wp-block-buttons .wp-block-button,
	body .wp-block-buttons .wp-block-button__link {
		width: 100%;
	}
	/* About page (H, 2026-07-06): the spotlight's "Read a note…" link and the
	   note band's CTA row ("Questions? Read the FAQ →") centre when stacked.
	   Scoped to the bands H named — #note is the note band's fixed anchor. */
	.lw-about .lw-arrow-link {
		text-align: center;
	}
	#note .is-content-justification-left {
		justify-content: center;
	}
}

/* ---------------------------------------------------------------------------
   Header — a cream bar matching the master design (res/claude_design_v001):
   lotus mark in a rounded square + two-line wordmark on the left, dynamic
   wp:navigation on the right with the booking CTA as its last item. The link +
   button *interactions* are the theme's own (the animated sage underline below,
   and theme.json's primary-hover button fill) — only the layout/chrome tracks
   the mockup.

   Mobile bends two hardcoded WP-core nav behaviours (see the media queries):
   core collapses to a hamburger at a fixed 600px — we re-scope that to ~1000px;
   and core opens the menu as a position:fixed full-screen overlay — we turn it
   into a dropdown panel under the bar.

   NOTE: the mockup's sticky header + scroll-shrink are deferred (a pair — the
   shrink is only visible while the bar is pinned). Locked spec: design-bible §5.
   --------------------------------------------------------------------------- */
.site-header {
	position: relative; /* containing block for the mobile dropdown panel */
	padding-block: 0.7rem;
	background: var(--wp--preset--color--base);
	border-bottom: 1px solid var(--lw-hairline);
}
/* nowrap: the toggle/CTA must never drop below the brand (H) — the brand
   shrinks and its wordmark text wraps first. */
.site-header .lw-header {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: space-between;
	gap: 0.6rem 1.5rem;
}

/* Brand — lotus mark in a rounded square + two-line wordmark. The chrome is
   shared with the footer lockup (Phase 7); each context sets only its sizes. */
.site-header .lw-header__brand {
	gap: 0.7rem;
	min-width: 0; /* lets the wordmark shrink/wrap instead of pushing the toggle down */
	flex: 1 1 auto;
}
.site-header .lw-header__nav {
	flex: none; /* the toggle keeps its size; the brand gives way */
}
.site-header .wp-block-site-logo,
.site-footer .wp-block-site-logo {
	line-height: 0;
}
.site-header .wp-block-site-logo img,
.site-footer .wp-block-site-logo img {
	background: var(--lw-logo-bg);
	object-fit: cover;
}
.site-header .wp-block-site-logo img {
	width: 120px;
	height: 120px;
	border-radius: 24px;
}
.site-header .lw-header__wordmark {
	gap: 0;
	min-width: 0;
	position: relative; /* containing block for the stretched home link below */
}
.lw-header__name,
.lw-footer__name {
	font-family: var(--wp--preset--font-family--literata);
	font-weight: 600;
}
.lw-header__name {
	font-size: 1.7rem;
	line-height: 1.08;
	letter-spacing: 0.01em;
	transition: font-size 0.28s ease;
}
.lw-header__name a {
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
}
/* The whole two-line wordmark is one home link (H, 2026-07-06): stretch the
   name's anchor over the group so "Psychology Clinic" is clickable too —
   one link in the a11y tree, no second anchor (stretched-anchor idiom). */
.site-header .lw-header__name a::after {
	content: "";
	position: absolute;
	inset: 0;
}
.lw-header__subtitle,
.lw-footer__subtitle {
	line-height: 1.1;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast-2);
}
.lw-header__subtitle {
	font-size: 0.78rem;
	transition: font-size 0.28s ease;
}

/* Nav text links: ink, no underline; the theme's sage bar grows on hover /
   for the current page (this is the interaction H asked to keep). */
.site-header .wp-block-navigation a:where(:not(.wp-element-button)) {
	text-decoration: none;
	color: var(--wp--preset--color--contrast);
	font-weight: 600;
	font-size: 0.95rem;
}
.site-header .wp-block-navigation-item__content {
	position: relative;
}
.site-header .wp-block-navigation-item__content::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: -3px;
	height: 2px;
	background: var(--wp--preset--color--primary);
	transform: scaleX(0);
	transition: transform 0.18s ease;
}
.site-header .wp-block-navigation-item__content:hover::after,
.site-header .current-menu-item > .wp-block-navigation-item__content::after {
	transform: scaleX(1);
}
.site-header .wp-block-navigation-item__content:hover,
.site-header .current-menu-item > .wp-block-navigation-item__content {
	color: var(--wp--preset--color--primary);
}

/* The booking CTA lives as the nav's last item — a solid primary button
   (reusing theme.json's primary-hover fill), not an underlined text link. */
.site-header .lw-nav-cta .wp-block-navigation-item__content {
	background: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base);
	font-weight: 700;
	padding: 0.62rem 1.15rem;
	border-radius: var(--lw-radius);
	transition: background 0.16s;
}
.site-header .lw-nav-cta .wp-block-navigation-item__content:hover,
.site-header .lw-nav-cta .wp-block-navigation-item__content:focus {
	background: var(--wp--preset--color--primary-hover);
	color: var(--wp--preset--color--base);
}
.site-header .lw-nav-cta .wp-block-navigation-item__content::after {
	display: none; /* the button doesn't get the sliding underline */
}

/* the standalone tablet booking button — shown only in the tablet band (below) */
.site-header .lw-header__cta {
	display: none;
}

/* ---- tablet + mobile (≤999): WP-core nav override A — collapse to the hamburger
   (core is fixed at 600px) ---- */
@media (max-width: 999px) {
	/* show the toggle (core hides it ≥600px) and style it like the mockup's 46px button */
	.site-header .lw-header__nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
		position: relative; /* anchors the ✕ pseudo-elements when open */
		align-items: center;
		justify-content: center;
		width: 46px;
		height: 46px;
		border: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 16%, transparent);
		border-radius: 11px;
		background: var(--wp--preset--color--base);
		color: var(--wp--preset--color--contrast);
	}
	/* hide the inline row (core shows it ≥600px) */
	.site-header .lw-header__nav .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	/* ---- override B: the OPEN menu — core makes it position:fixed full-screen;
	   turn it into a dropdown panel under the bar. Nav goes static so the panel
	   anchors to .site-header (position:relative = its containing block); left+right:0
	   size it to the exact bar width (width:100% overflowed on some setups). */
	.site-header .lw-header__nav {
		position: static;
	}
	.site-header .lw-header__nav .wp-block-navigation__responsive-container.is-menu-open {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		bottom: auto;
		height: auto;
		max-height: calc(100dvh - 100%);
		padding: 0.4rem clamp(1.25rem, 5vw, 3rem) 1.1rem;
		background: var(--wp--preset--color--base);
		border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 8%, transparent);
		overflow: auto;
	}
	/* core pads the content to clear its overlay close button — not needed here */
	.site-header .lw-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
		padding-top: 0;
	}
	/* the stacked list spans the panel (core shrink-wraps + left-aligns it); no
	   gap between rows — padding carries the rhythm */
	.site-header .lw-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container,
	.site-header .lw-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-page-list {
		width: 100%;
		gap: 0;
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-navigation-item {
		width: 100%;
	}
	/* ---- the panel design is H's menu master (res/claude_design_menu_mobile_v001,
	   #lw-mobile-nav) — dividers with beads, muted children cluster, centred
	   scale-in hover bars. Decision log: retros/2026-07-06-phase-8-responsive-menu.md ---- */
	/* Dividers between top-level items only: a 12% hairline with a 26×3px rose
	   bead centred on the line. The last page item and the CTA (outside the
	   page-list) get none; Services' divider sits below its children cluster
	   (the li wraps the submenu). */
	.site-header .lw-header__nav .is-menu-open .wp-block-page-list > .wp-block-navigation-item:not(:last-child) {
		position: relative;
		border-bottom: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 12%, transparent);
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-page-list > .wp-block-navigation-item:not(:last-child)::after {
		content: "";
		position: absolute;
		left: 50%;
		bottom: -2px; /* 3px bead centred on the 1px border line */
		transform: translateX(-50%);
		width: 26px;
		height: 3px;
		border-radius: 3px;
		background: color-mix(in srgb, var(--wp--preset--color--accent) 28%, var(--wp--preset--color--base)); /* master #E8C9C0 */
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-navigation-item__content {
		display: block;
		box-sizing: border-box; /* keep padding inside the 100% so the Book stays centred */
		width: 100%; /* fill the row so text-align can actually centre the label */
		padding: 0.8rem 0;
		font-size: 1.05rem;
		text-align: center; /* centre the stacked links + Book in the panel */
		border-radius: 10px;
		transition: color 0.18s ease;
	}
	/* hover/pressed feedback for the text links only — scoped to the page-list
	   so it can't bleed onto the Book button (whose own hover fills the pill
	   with this same green: unscoped, the label went green-on-green) */
	.site-header .lw-header__nav .is-menu-open .wp-block-page-list .wp-block-navigation-item__content:hover {
		color: var(--wp--preset--color--primary-hover);
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-page-list .wp-block-navigation-item__content:active {
		background: var(--wp--preset--color--surface); /* pressed: blush flash (master) */
	}
	/* Hover/focus cue: a centred rose bar scales in under the label — replaces
	   the nav row's full-width sliding bar, so its geometry is reset (left +
	   width pin the box; the row's right:0 is moot once width is set).
	   Page-list links only; the Book button gets none. The current page keeps
	   a resting bar (composes translateX — the row's plain scaleX(1) rule
	   would misplace it). */
	.site-header .lw-header__nav .is-menu-open .wp-block-page-list .wp-block-navigation-item__content::after {
		content: "";
		position: absolute;
		left: 50%;
		bottom: 0.45rem;
		width: 44px;
		height: 2.5px;
		border-radius: 2px;
		background: color-mix(in srgb, var(--wp--preset--color--accent) 62%, var(--wp--preset--color--base)); /* master #C28C86 */
		transform: translateX(-50%) scaleX(0);
		transition: transform 0.24s cubic-bezier(0.2, 0.9, 0.3, 1);
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-page-list .wp-block-navigation-item__content:hover::after,
	.site-header .lw-header__nav .is-menu-open .wp-block-page-list .wp-block-navigation-item__content:focus-visible::after,
	.site-header .lw-header__nav .is-menu-open .wp-block-page-list .current-menu-item > .wp-block-navigation-item__content::after {
		transform: translateX(-50%) scaleX(1);
	}
	/* Services parent: children tuck in close (master: .8rem top, .3rem bottom);
	   its bar drops into the shortened padding */
	.site-header .lw-header__nav .is-menu-open .has-child > .wp-block-navigation-item__content {
		padding-bottom: 0.3rem;
	}
	.site-header .lw-header__nav .is-menu-open .has-child > .wp-block-navigation-item__content::after {
		bottom: 0.06rem;
	}
	/* Services children: a tight centred cluster in smaller muted ink — kill
	   core's overlay indent (2rem sides) and dead gap (2em top) */
	.site-header .lw-header__nav .is-menu-open .has-child .wp-block-navigation__submenu-container {
		width: 100%; /* .has-child rides along to out-tie core's overlay width:auto (0,5,0) */
		padding: 0;
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
		display: block; /* core's 0,5,0 submenu rule flexes anchors left — block restores the centred text */
		padding: 0.42rem 0;
		font-size: 0.92rem;
		color: color-mix(in srgb, var(--wp--preset--color--contrast-2) 85%, var(--wp--preset--color--base)); /* master #82756B */
		border-radius: 8px;
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
		color: var(--wp--preset--color--accent);
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
		bottom: 0.1rem;
		width: 34px;
		height: 2px;
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item:last-child .wp-block-navigation-item__content {
		padding-bottom: 0.75rem; /* breathing room before the divider (master "sublast") */
	}
	.site-header .lw-header__nav .is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item:last-child .wp-block-navigation-item__content::after {
		bottom: 0.42rem;
	}
	/* the Book button at the foot of the panel: shrink-wrapped + centred (the
	   master's inline-flex pill, not a full-width bar). Overlay items are flex
	   COLUMNS — horizontal centring is align-items here. */
	.site-header .lw-header__nav .is-menu-open .lw-nav-cta {
		margin-top: 0.9rem;
		align-items: center;
	}
	/* motion off: the colour/bar cues still appear — instantly */
	@media (prefers-reduced-motion: reduce) {
		.site-header .lw-header__nav .is-menu-open .wp-block-navigation-item__content,
		.site-header .lw-header__nav .is-menu-open .wp-block-page-list .wp-block-navigation-item__content::after {
			transition: none;
		}
	}
	.site-header .lw-header__nav .is-menu-open .lw-nav-cta .wp-block-navigation-item__content {
		width: auto; /* the master's shrink-wrapped pill (outranks the panel-wide 100%) */
		padding: 0.8rem 1.15rem;
	}
	/* When open, the toggle stays put and becomes an ✕ in place (header.js wires
	   the click-to-close). Core keeps its own separate ✕ inside the panel — hide
	   it so the toggle is the single control. */
	.site-header .wp-block-navigation__responsive-container-close {
		display: none;
	}
	html.has-modal-open .site-header .lw-header__nav .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex; /* keep the toggle visible while open (core would hide it) */
	}
	html.has-modal-open .site-header .wp-block-navigation__responsive-container-open svg {
		display: none; /* swap the hamburger glyph… */
	}
	html.has-modal-open .site-header .wp-block-navigation__responsive-container-open::before,
	html.has-modal-open .site-header .wp-block-navigation__responsive-container-open::after {
		content: "";
		position: absolute;
		top: 50%;
		left: 50%;
		width: 20px;
		height: 2px;
		border-radius: 2px;
		background: currentColor; /* …into an ✕ */
	}
	html.has-modal-open .site-header .wp-block-navigation__responsive-container-open::before {
		transform: translate(-50%, -50%) rotate(45deg);
	}
	html.has-modal-open .site-header .wp-block-navigation__responsive-container-open::after {
		transform: translate(-50%, -50%) rotate(-45deg);
	}
}

/* tablet (782–999): standalone Book + toggle grouped at the right, the
   toggle rightmost (mockup). The brand grows to eat the free space so the two
   pack together on the right instead of being spread by space-between. */
@media (min-width: 782px) and (max-width: 999px) {
	.site-header .lw-header__brand {
		flex: 1 1 auto;
	}
	.site-header .lw-header__cta {
		display: block;
		order: 2;
	}
	.site-header .lw-header__nav {
		order: 3;
	}
	/* the standalone Book in the bar already covers tablet — don't repeat it in the
	   open panel (it stays in the panel on mobile, where there's no bar button).
	   Specificity must clear core's is-menu-open display:flex on nav items (0,4,0). */
	.site-header .lw-header__nav .wp-block-navigation__responsive-container.is-menu-open .lw-nav-cta {
		display: none;
	}
}

/* desktop (≥1000): the Services hover dropdown gets theme chrome in place of
   core's raw white box (cream, hairline, radius, soft shadow, no label wrap);
   hover = ink shift — the row's sliding bar doesn't belong inside a panel.
   The .wp-block-navigation class rides along to outrank core's
   :not(.has-background) default (0,3,0). */
@media (min-width: 1000px) {
	.site-header .wp-block-navigation.lw-header__nav .wp-block-navigation__submenu-container {
		background: var(--wp--preset--color--base);
		border: 1px solid var(--lw-hairline);
		border-radius: var(--lw-radius);
		box-shadow: 0 18px 42px -24px color-mix(in srgb, var(--wp--preset--color--contrast) 35%, transparent);
		padding: 0.4rem 0;
	}
	.site-header .wp-block-navigation.lw-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
		white-space: nowrap; /* "Psychological assessments" stays one line */
	}
	.site-header .wp-block-navigation.lw-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
		display: none;
	}
	.site-header .wp-block-navigation.lw-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
		color: var(--wp--preset--color--primary-hover);
	}
}

/* ---------------------------------------------------------------------------
   Interior pages — page.html template-level rules. Freeze exceptions approved
   by H 2026-07-05 (docs/retros/2026-07-05-phase-8-page-blueprints.md); the
   theme is otherwise frozen (docs/retros/2026-07-05-theme-freeze.md).
   --------------------------------------------------------------------------- */
/* 1. Full-width pattern bands butt flush inside page content, matching
   front-page.html's blockGap:0 main. Beats WP's generated per-container gap
   rule ((0,2,0) vs (0,1,0)); only page.html renders post-content, so the
   homepage is untouched. */
.wp-block-post-content > .alignfull {
	margin-block-start: 0;
}
/* 2. (companion: templates/page.html gives post-content align:"full" — core's
   own escape from main's 640px cap; a CSS emulation loses to core. See retro.) */
/* 3. The template's post-title stays the page's <h1> (one-h1 canon, SEO,
   screen readers) but is visually clipped — pages open on their first band,
   whose xxx-large h2 carries the visible hierarchy. Level-1 titles only:
   index.html's loop titles are h2/h3. The :not() guard keeps the title
   visible in the editor canvas (add_editor_style loads this sheet there,
   and the canvas title is h1.wp-block-post-title.editor-post-title). */
h1.wp-block-post-title:not(.editor-post-title) {
	position: absolute;
	width: 1px;
	height: 1px;
	clip-path: inset(50%);
}

/* ---------------------------------------------------------------------------
   Hero — matches the master design (res/claude_design_v001) LAYOUT while reusing
   the theme's components: the primary + is-style-outline buttons keep their own
   hovers, and .lw-eyebrow / .lw-photo--portrait / .lw-split stay the shared bases
   (only hero-scoped extras are added here). New: a lotus-halo ring, a floating
   credential card, a soft gradient wash. Every colour derives from the theme.json
   palette (var + color-mix) so editing the palette restyles the hero. All
   decoratives are aria-hidden + pointer-events:none. Verify against the real render.
   --------------------------------------------------------------------------- */
/* clip (not hidden): contains the 118% halo + card's negative offsets so they
   never cause horizontal page scroll, without creating a scroll container. */
.lw-hero {
	position: relative;
	overflow-x: clip;
}
/* the hero band sits flush under the header — cancel the site block-gap that
   otherwise leaves a cream strip above the gradient (main gets margin-top on the
   home template; content pages keep their breathing room). */
.home main {
	margin-top: 0;
}
.lw-hero__wash {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
	max-width: none; /* escape the constrained-layout 640px cap so the wash is full-bleed */
	background:
		radial-gradient(120% 95% at 90% 4%, color-mix(in srgb, var(--wp--preset--color--surface) 75%, transparent) 0%, transparent 50%),
		radial-gradient(95% 80% at 2% 102%, color-mix(in srgb, var(--wp--preset--color--primary) 16%, transparent) 0%, transparent 46%);
}
.lw-hero > .alignwide {
	position: relative;
	z-index: 1; /* keep the real content above the wash */
	margin-top: 0; /* the absolute wash counts as a "previous sibling", so WP adds a
	                  phantom block-gap here; cancel it so content sits at the hero's
	                  top padding (not 24px lower) — matches the master's content-top gap */
}

/* Lead — the master's soft warm brown, mixed from the ink token so it stays palette-driven */
.lw-hero__lead {
	color: color-mix(in srgb, var(--wp--preset--color--contrast) 85%, var(--wp--preset--color--base));
	line-height: 1.55;
}
/* measure only alongside the media column — the stacked layout runs full width (H).
   tablet + desktop (≥782; columns are side-by-side there) */
@media (min-width: 782px) {
	.lw-hero__lead {
		max-width: 46ch;
	}
}

/* Trust line — small muted row; CSS rose dots separate the items (not editable text) */
.lw-hero__trust {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 0.9rem;
	margin-top: 1.4rem;
}
.lw-hero__trust > span {
	display: inline-flex;
	align-items: center;
}
.lw-hero__trust > span + span::before {
	content: "";
	width: 4px;
	height: 4px;
	margin-right: 0.9rem;
	border-radius: 50%;
	background: var(--lw-dot);
	flex: none;
}

/* Media column — positioning context for the halo (behind) + the floating card (front).
   overflow visible so both can bleed; the .lw-hero ancestor clips x → no page scroll. */
.lw-hero__media {
	position: relative;
	max-width: 440px;
	margin-inline: auto;
	margin-bottom: 28px; /* room for the card's -20px bottom offset */
	overflow: visible;
}
/* the absolute halo is the frame's "previous sibling", so WP's block-gap adds a
   phantom margin-top on the frame; cancel it so the frame sits at the media
   column's top — this is what keeps the eyebrow ↔ image-top alignment. */
.lw-hero__media > * {
	margin-block-start: 0;
}
.lw-hero__halo {
	position: absolute;
	top: -7%;
	left: 50%;
	transform: translateX(-50%);
	width: 118%;
	aspect-ratio: 1;
	border: 1.5px solid var(--lw-halo);
	border-radius: 50%;
	z-index: 0;
	pointer-events: none;
}
/* Portrait frame — reuse .lw-photo--portrait (4/5); restyle its chrome for the hero
   only (rounded, warm panel, hairline border). Founder/profile keep their look. */
.lw-hero__media .lw-photo {
	position: relative;
	z-index: 1;
	aspect-ratio: 1 / 1; /* square — matches the logo lockup; shorter than the 4:5 placeholder, so the trust strip rides higher */
	padding: 0; /* the image fills the frame (override the placeholder's padding) */
	border-radius: 20px;
	overflow: hidden;
	background: var(--lw-logo-bg);
	border: 1px solid var(--lw-hairline-soft);
}
.lw-hero__media .lw-photo picture,
.lw-hero__media .lw-photo img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Floating credential card — overlaps the frame's bottom-left, above everything */
.lw-hero__cred {
	position: absolute;
	left: 50%;
	transform: translateX(-50%); /* centred on the frame */
	top: calc(100% - 25px); /* top overlaps the image bottom by 25px; the card hangs below (anchoring by top keeps the overlap fixed regardless of card height) */
	width: 80%; /* ~80% of the image/frame width, at every breakpoint */
	z-index: 2;
	gap: 0.7rem;
	align-items: center;
	background: var(--wp--preset--color--base);
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 10%, transparent);
	border-radius: 14px;
	padding: 0.75rem 0.95rem;
	box-shadow: 0 18px 42px -24px color-mix(in srgb, var(--wp--preset--color--contrast) 55%, transparent);
}
/* 42px rounded-square panel around a real, owner-replaceable image (H,
   2026-07-06 — same architecture as the card icons: chrome on the FIGURE,
   never on the img, so a swapped file is clipped at the panel's own radius;
   default = assets/icons/services.svg, which letterboxes under `contain`). */
.lw-hero__cred-mark {
	width: 42px;
	flex: none;
	margin: 0;
	box-sizing: border-box;
	padding: 0.3rem; /* breathing ring inside the square, whatever the owner uploads */
	border-radius: 11px;
	background-color: var(--lw-logo-bg);
	overflow: hidden; /* clips at the padding box — the full rounded square */
}
.lw-hero__cred-mark img {
	display: block;
	width: 100%;
	aspect-ratio: 1;
	object-fit: contain;
}
.lw-hero__cred-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--literata);
	font-weight: 600;
	font-size: 1rem;
	line-height: 1.25;
	color: var(--wp--preset--color--contrast);
}
.lw-hero__cred-line {
	margin: 0;
	line-height: 1.25;
}
/* The card is a link to /about/ (H, 2026-07-06 — freeze amendment #12): a small
   arrow cue line under the registration text, with the card's one real anchor
   stretched over the whole card (same idiom + tradeoffs as .lw-card--service). */
.lw-hero__cred-link {
	margin: 0.2rem 0 0;
	line-height: 1.25;
}
/* Core's layout support makes every constrained group position:relative (a
   zero-specificity :where() rule), which would trap the stretched overlay
   inside the text column — flatten it so the overlay's containing block is
   the card. Nothing anchors inside cred-text. */
.lw-hero__cred-text {
	position: static;
}
.lw-hero__cred .lw-arrow-link a::after {
	content: "";
	position: absolute;
	inset: 0; /* resolves against .lw-hero__cred — the nearest positioned ancestor */
}
/* Hover: lift + deeper shadow/border, ungated (the Chrome input-detection
   lesson); translateY composes with the card's centring translateX. */
.lw-hero__cred {
	transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.lw-hero__cred:hover {
	transform: translateX(-50%) translateY(-3px);
	border-color: color-mix(in srgb, var(--wp--preset--color--contrast) 22%, transparent);
	box-shadow: 0 22px 48px -24px color-mix(in srgb, var(--wp--preset--color--contrast) 65%, transparent);
}
/* Keyboard: promote the stretched anchor's focus ring to the card (cf. the
   service-card rule; non-:has() browsers fall back to the anchor's own ring). */
.lw-hero__cred:has(a:focus-visible) {
	outline: 3px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
}
.lw-hero__cred:has(a:focus-visible) a:focus-visible {
	outline: none;
}
@media (prefers-reduced-motion: reduce) {
	.lw-hero__cred {
		transition: none;
	}
	/* motion gone, feedback kept: the border still deepens (cf. service cards) */
	.lw-hero__cred:hover {
		transform: translateX(-50%);
	}
}

/* Mobile (stacked): the image is last, and the card hangs ~56–94px below it (taller
   at ~320px where the registration line wraps). margin-top clears the halo's -7%
   overhang above the frame (~25px) so the ring stops crowding the trust line (H,
   2026-07-06); margin-bottom reserves just enough room for the hanging card.
   (2-class selector beats WP's last-child margin reset; desktop is unaffected —
   the taller text column already leaves room there.) */
@media (max-width: 781px) {
	.lw-hero .lw-hero__media {
		margin-top: 1.75rem;
		margin-bottom: 4.75rem; /* sized for the card + its Meet Dr. Bahl cue line — ≥30px strip clearance at the 320px worst case */
	}
	/* once the media stacks under the text, centre the trust line too (H) */
	.lw-hero__trust {
		justify-content: center;
	}
}

/* ---------------------------------------------------------------------------
   Two-column section blocks (hero / founder / profile). Stack text-first on
   mobile (source order); on desktop, --media-left moves the media column left.
   --------------------------------------------------------------------------- */
@media (min-width: 782px) {
	.lw-split.lw-split--media-left > .wp-block-column:last-child {
		order: -1;
	}
}

/* framed photo placeholder — replaced by an editable core/image (with alt) in Phase 7 */
.lw-photo {
	aspect-ratio: 4 / 3;
	border-radius: var(--lw-radius);
	display: flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	padding: 1rem;
	color: var(--wp--preset--color--contrast);
	background: linear-gradient(135deg, var(--wp--preset--color--surface), color-mix(in srgb, var(--wp--preset--color--primary) 22%, var(--wp--preset--color--base)));
}
.lw-photo.lw-photo--portrait {
	aspect-ratio: 4 / 5;
}
.lw-photo.lw-photo--wide {
	aspect-ratio: 16 / 10;
	border-radius: 0;
}
.lw-photo p {
	max-width: 24ch;
	font-size: var(--wp--preset--font-size--small);
}

/* keep intro/lead paragraphs at a comfortable reading width inside wide sections */
.lw-measure {
	max-width: var(--lw-column);
}
/* the CTA band is centred, so its capped heading/lead centre within the wide band */
.lw-cta .lw-measure {
	margin-inline: auto;
}

/* ---------------------------------------------------------------------------
   Cards (service + post) — bottom-align the card link so a row of cards lines
   up regardless of copy length. Chrome lives here in CSS (base + per-modifier);
   rhythm (blockGap/margins) stays in the patterns' block attrs.
   --------------------------------------------------------------------------- */
.lw-card {
	display: flex;
	flex-direction: column;
	height: 100%;
	overflow: hidden; /* clips a full-bleed post-card thumbnail to the card radius */
	background-color: var(--wp--preset--color--surface);
	border-radius: var(--lw-radius);
	padding: var(--wp--preset--spacing--40);
}
/* post cards: cream ground + full-bleed thumbnail (the inner group carries the text padding) */
.lw-card--post {
	background-color: var(--wp--preset--color--base);
	padding: 0;
}
.lw-card .lw-card__link {
	margin-top: auto;
}
/* Card icon — a real, per-card replaceable image block (H, 2026-07-06; was an
   empty group + CSS mask, which also rendered as placeholder chrome in the
   editor). Default assets in assets/icons/ (tight canvases, theme-primary
   fills — baked hex: img assets can't read palette tokens, cf. the logo).
   The cream disc lives on the img, and the disc's PADDING is the single
   guaranteed breathing ring (H): every icon — vendored or owner-uploaded —
   sits inset from the circle edge; no per-file viewBox padding. Disc sized so
   the glyph area stays at the approved 41.6px. */
/* The FIGURE is the disc; the img is pure content. border-radius must never
   sit on the img: per spec a replaced element's content is trimmed at the
   content edge with the radius REDUCED BY THE PADDING — an inner clip circle
   (radius − padding) that ate corner-reaching art (the starter card's bubble
   tail, H 2026-07-06) and that no amount of padding can outrun. On the
   figure, the radius only shapes the disc itself. */
.lw-card__icon {
	width: 3.5rem;
	margin: 0 0 0.3rem;
	box-sizing: border-box;
	/* the guaranteed icon margin — MUST be >= 14.65% of the disc width
	   ((1 - 1/sqrt2)/2): past that the square icon canvas is fully inside
	   the visible circle. At 3.5rem: >= 0.5127rem. */
	padding: 0.55rem;
	border-radius: 50%;
	background-color: var(--wp--preset--color--base);
	overflow: hidden; /* clips at the full disc radius (padding box), NOT the inner circle */
}
/* --wide: for wide, letterboxed glyphs (the lotus) whose corners sit far
   inside the circle — less padding renders them ~7% larger (H, 2026-07-06).
   Safe: at 0.42rem the lotus's art corners sit 24px from centre vs the 28px
   disc radius. Square/round icons must NOT use this (they'd break the
   inscription invariant above). */
.lw-card__icon--wide {
	padding: 0.465rem; /* content 41.1px = the lotus at +7% (H) */
}
.lw-card__icon img {
	display: block;
	width: 100%;
	aspect-ratio: 1;
	/* contain, not cover: a non-square file (Illustrator exports crop tight)
	   letterboxes safely instead of blowing up and cropping (H, 2026-07-06).
	   Trade-off: a photo dropped in renders inside the ring, not disc-filling. */
	object-fit: contain;
}

/* ---------------------------------------------------------------------------
   Trust strip — a thin surface band directly under the hero (it caps the hero
   gradient's bottom edge, per the master). Four factual credentials in a
   per-mode grid, each led by a sage checkmark drawn as a CSS mask filled with
   the primary token (palette-driven — no baked hex). Locked contentOnly, so
   Nancy edits the four lines of copy but not the layout.
   --------------------------------------------------------------------------- */
.lw-trust {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	/* per-mode columns (781 doctrine): 1 mobile · 2 tablet · 4 desktop */
	grid-template-columns: 1fr;
	gap: 0.9rem 1.7rem;
}
@media (min-width: 782px) and (max-width: 999px) { /* tablet */
	.lw-trust {
		grid-template-columns: repeat(2, 1fr);
	}
}
@media (min-width: 1000px) { /* desktop */
	.lw-trust {
		grid-template-columns: repeat(4, 1fr);
	}
}
.lw-trust li {
	display: flex;
	align-items: flex-start;
	gap: 0.6rem;
	margin: 0;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.4;
	color: var(--wp--preset--color--contrast);
}
.lw-trust li::before {
	content: "";
	flex: none;
	width: 1.25rem;
	height: 1.25rem;
	margin-top: 0.05rem;
	background-color: var(--wp--preset--color--primary);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M20 6L9 17l-5-5' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M20 6L9 17l-5-5' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* ---------------------------------------------------------------------------
   Empathy band — quiet centered statement between the trust strip and services
   (locked 2026-07-02: master layout × the live site's "A Supportive Beginning"
   messaging). Heading/lead sizes are the master's empathy scale.
   --------------------------------------------------------------------------- */
.lw-empathy h2 {
	font-size: clamp(1.8rem, 3.4vw, 2.5rem);
	line-height: 1.18;
}
.lw-empathy__lead {
	font-size: clamp(1.05rem, 1.7vw, 1.28rem);
	line-height: 1.6;
	color: var(--lw-ink-soft);
}

/* Arrow link — the master's quiet card/CTA link: sage, bold, a transparent
   underline that colours on hover/focus. Shared by the empathy band and the
   service cards (resources cards adopt it in their redesign). */
.lw-arrow-link a {
	color: var(--wp--preset--color--primary);
	font-weight: 700;
	text-decoration: none;
	border-bottom: 1.5px solid transparent;
	padding-bottom: 1px;
	transition: color 0.16s, border-color 0.16s;
}
.lw-arrow-link a:hover,
.lw-arrow-link a:focus {
	color: var(--wp--preset--color--primary-hover);
	border-color: var(--wp--preset--color--primary-hover);
}

/* ---------------------------------------------------------------------------
   Services band — the master's card section on the current copy (locked
   2026-07-03). The hairline divider lives here (border-top), relocated from
   the empathy band's temporary border-bottom.
   --------------------------------------------------------------------------- */
.lw-services {
	border-top: 1px solid var(--lw-hairline-soft);
}

/* Hand-rolled grid (wp:columns stacks all-or-nothing and WP's grid layout
   emits auto-FILL) — per-mode columns (781 doctrine): 1 mobile · 2 tablet ·
   3 desktop. */
.lw-services__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.2rem;
}
@media (min-width: 782px) and (max-width: 999px) { /* tablet */
	.lw-services__grid {
		grid-template-columns: repeat(2, 1fr);
	}
	/* An odd card count wraps 2+1: centre the orphan at its siblings' exact
	   width instead of leaving it in the left track (H). Even counts (the hub's
	   six) fill both tracks and never match :nth-child(odd) on :last-child.
	   Child-generic on purpose — the 2-col geometry strands the orphan, not any
	   card modifier. (Desktop's 3-col grid needs no rule: every shipped grid
	   holds a multiple of 3.) */
	.lw-services__grid > :last-child:nth-child(odd) {
		grid-column: 1 / -1;
		justify-self: center;
		width: calc(50% - 0.6rem); /* half the row minus half the 1.2rem gap = sibling width */
	}
}
@media (min-width: 1000px) { /* desktop */
	.lw-services__grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

/* Service card chrome — the master's rose-bordered surface card, scoped to the
   modifier so post cards (shared .lw-card base) are untouched. The border is
   the master's rgba(149,90,84,.16) = accent @ 16%. */
.lw-card--service {
	position: relative; /* containing block for the stretched link */
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--accent) 16%, transparent);
	border-radius: var(--lw-radius-lg);
	padding: clamp(1.4rem, 3vw, 1.85rem);
	transition: transform 0.18s ease, box-shadow 0.18s ease;
}

/* Whole card clickable: stretch the card's one real link over it. Exactly one
   link per card in the a11y tree; pointer cursor comes free (the overlay IS
   the anchor). Tradeoff: card text can't be mouse-drag-selected. If style.css
   is ever enqueued into the editor iframe, suppress this ::after there — it
   would hijack block-selection clicks in the canvas. */
.lw-card--service .lw-arrow-link a::after {
	content: "";
	position: absolute;
	inset: 0;
}

/* The master's lift + shadow — deliberately NOT gated behind a hover/any-hover
   media query: Chrome's input detection is unreliable (H's mouse-only Windows
   Chrome reported hover:none AND any-hover:none — phantom touch digitizer or
   the touch-events flag — and lost all card feedback; Firefox was fine,
   2026-07-06). Plain :hover only fires transiently on a touch tap, and the
   card navigates on tap anyway; the ::before chevron stays the touch cue.
   (The arrow link needs no card-hover rule: the stretched ::after IS the
   anchor, so hovering anywhere on the card is a:hover.) */
.lw-card--service:hover {
	transform: translateY(-3px);
	box-shadow: 0 18px 42px -28px color-mix(in srgb, var(--wp--preset--color--contrast) 45%, transparent);
}
@media (prefers-reduced-motion: reduce) {
	.lw-card--service {
		transition: none;
	}
	.lw-card--service:hover {
		transform: none;
	}
	/* motion is gone, feedback shouldn't be: clickable cards still respond with a
	   static cue — the border deepens (16% → 45% accent) beside the kept shadow.
	   (Discovered when H's animations-off Windows read as "hover is broken".) */
	.lw-card--service:not(.lw-card--static):hover {
		border-color: color-mix(in srgb, var(--wp--preset--color--accent) 45%, transparent);
	}
}

/* Clickability cue — an always-on chevron top-right (H: consistent across all
   devices rather than gated to touch). */
.lw-card--service::before {
	content: "";
	position: absolute;
	top: 1.15rem;
	right: 1.15rem;
	width: 1.05rem;
	height: 1.05rem;
	background-color: var(--wp--preset--color--primary);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M9 5l7 7-7 7' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M9 5l7 7-7 7' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* --static: a non-clickable service card (no link inside — About's "grounded"
   trio). Kills the clickability cue and the desktop hover lift, both of which
   would promise a click that isn't there (H, 2026-07-06). Opt-in per card in
   page content; every card with a real link keeps the cue everywhere else. */
.lw-card--static::before {
	content: none;
}
.lw-card--static:hover {
	transform: none;
	box-shadow: none;
}

/* Keyboard: promote the focus ring from the (stretched) anchor to the card.
   Browsers without :has() skip both rules and fall back to the anchor's own
   global ring. */
.lw-card--service:has(a:focus-visible) {
	outline: 3px solid var(--wp--preset--color--primary);
	outline-offset: 2px;
}
.lw-card--service:has(a:focus-visible) a:focus-visible {
	outline: none;
}

/* ---------------------------------------------------------------------------
   Areas of focus — informational chip cloud on the surface band. The chips are
   a plain list: Nancy adds/removes items like list lines (works under
   contentOnly); every chip visual lives here, not in the editor, so new items
   are born chips and wrapping/centering can't be broken from the canvas.
   --------------------------------------------------------------------------- */
.lw-chips {
	list-style: none;
	margin-top: 1.4rem; /* h2 → chips gap (master); beats the group's 0.5rem blockGap */
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	justify-content: center; /* centered rows at every width (H) */
	gap: 0.65rem;
}
.lw-chips li {
	padding: 0.6rem 1.05rem;
	border: 1px solid color-mix(in srgb, var(--wp--preset--color--accent) 40%, transparent);
	border-radius: var(--lw-radius);
	background: var(--wp--preset--color--base);
	color: var(--lw-ink-soft);
	font-size: 0.96rem;
	font-weight: 600;
	line-height: 1.3;
}

/* --fill: the master's second chip style (about credentials) — surface fill,
   no border, a step smaller, left-aligned in its text column. */
.lw-chips--fill {
	justify-content: flex-start;
	gap: 0.55rem;
}
.lw-chips--fill li {
	padding: 0.5rem 0.9rem;
	border: 0;
	background: var(--wp--preset--color--surface);
	font-size: 0.88rem;
}

/* ---------------------------------------------------------------------------
   About / founder — the master's credential-forward two-column section:
   soft-ink bio in a 560px measure, master-framed portrait, and a decorative
   rose ring behind the frame's bottom-right corner. The ring is pure CSS on
   the media column — nothing for the editor or the a11y tree to see.
   --------------------------------------------------------------------------- */
/* master's text measure — only alongside the portrait; the stacked layout runs full
   width (H). tablet + desktop (≥782; columns are side-by-side there) */
@media (min-width: 782px) {
	.lw-about .lw-split > .wp-block-column:first-child {
		max-width: 560px;
	}
}
.lw-about .lw-split > .wp-block-column:first-child p {
	color: var(--lw-ink-soft); /* body paras; the eyebrow's preset colour class outranks this */
}
.lw-about .lw-arrow-link {
	margin-top: 1.5rem; /* chips → link gap (master); scoped — empathy/cards place theirs differently */
}
.lw-about .lw-photo {
	position: relative;
	z-index: 1; /* above the ring */
	border-radius: 18px; /* the master's portrait frame — photo frames carry master radii (cf. the hero's 20px) */
	border: 1px solid var(--lw-hairline-soft);
}
.lw-about .lw-split > .wp-block-column:last-child {
	position: relative;
}
.lw-about .lw-split > .wp-block-column:last-child::before {
	content: "";
	position: absolute;
	right: -18px;
	bottom: -18px;
	width: 62%;
	aspect-ratio: 1;
	border: 1.5px solid color-mix(in srgb, var(--lw-dot) 60%, transparent);
	border-radius: 50%;
}

/* ---------------------------------------------------------------------------
   Founder spotlight — facts ledger (About master v2, variant B; freeze
   amendment #6, locked 2026-07-05). Hairline-ruled label → chips rows beside
   the portrait. The 12%/8% mixes are the master's literal values, kept
   verbatim per H's "exactly like the master" — deliberately NOT the
   --lw-hairline tokens (10%/8%).
   --------------------------------------------------------------------------- */
.lw-ledger {
	margin-top: var(--wp--preset--spacing--40);
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 12%, transparent);
}
.lw-ledger__row {
	display: grid;
	grid-template-columns: clamp(110px, 14vw, 150px) minmax(0, 1fr);
	column-gap: 1.5rem;
	align-items: start;
	padding: 0.85rem 0;
	border-bottom: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 8%, transparent);
}
.lw-ledger__row > * {
	margin: 0; /* the grid owns the rhythm (cf. .lw-steps) — cancels blockGap + .lw-chips' top gap */
}
.lw-ledger__row > .lw-eyebrow {
	padding-top: 0.55rem; /* optically centres the label on the chips' first row */
}

/* ---------------------------------------------------------------------------
   How it works — three numbered steps on the surface band, closing on the
   booking button. The circles are CSS counters: the numerals renumber
   themselves and can't be edited out of sequence; the owner only touches
   each step's title and line.
   --------------------------------------------------------------------------- */
.lw-steps {
	margin-top: 2.2rem; /* h2 → steps (master); beats the group's 0.5rem blockGap */
	display: grid;
	/* always 3-up on tablet + desktop — the columns just get narrower (H);
	   mobile switches to one list row per step below (a 2+1 wrap state is
	   not wanted for the numbered sequence). */
	grid-template-columns: repeat(3, 1fr);
	gap: 1.4rem;
	counter-reset: lw-step;
}
.lw-steps > .wp-block-group {
	margin-block: 0; /* the grid gap owns the rhythm (cancels the flow blockGap on 2nd+ cells) */
	display: flex;
	flex-direction: column;
	gap: 0.7rem;
}
.lw-steps > .wp-block-group > * {
	margin-block: 0; /* the flex gap owns the step rhythm (cancels the flow blockGap margins) */
}
.lw-steps > .wp-block-group::before {
	counter-increment: lw-step;
	content: counter(lw-step);
	display: grid;
	place-items: center;
	width: 46px;
	height: 46px;
	border-radius: 50%;
	background: var(--wp--preset--color--primary);
	color: var(--wp--preset--color--base);
	font-family: var(--wp--preset--font-family--literata);
	font-weight: 600;
	font-size: 1.2rem;
}
.lw-steps h3 {
	font-size: 1.25rem; /* the master's step-title scale (a step under the x-large h3 preset) */
}
.lw-steps p {
	color: var(--lw-ink-soft);
	line-height: 1.55;
}
/* mobile (≤781): the steps become one full-width numbered LIST — circle left,
   title beside it, the line hanging under the title (H). */
@media (max-width: 781px) {
	.lw-steps {
		grid-template-columns: 1fr;
	}
	.lw-steps > .wp-block-group {
		display: grid;
		grid-template-columns: auto 1fr;
		column-gap: 0.9rem;
		row-gap: 0.4rem;
		align-items: center; /* circle and title centre against each other in row 1 */
	}
	.lw-steps > .wp-block-group > p {
		grid-column: 2; /* the line hangs under the title, not the circle */
	}
}
.lw-how .wp-block-buttons {
	margin-top: 2.3rem; /* steps → button (master) */
}

/* ---------------------------------------------------------------------------
   CTA band — the master's closing contact section on the solid sage band:
   cream booking button (highest contrast on sage) beside an outlined email
   button, decorative cream rings clipped at the corners, small contact line.
   Overrides theme.json's default button colours (incl. hover) for this
   context only. Soft-cream text is a 90% base mix (4.71:1 on sage — the
   master's 82% contact line reads 4.22 here, under AA).
   --------------------------------------------------------------------------- */
.lw-cta {
	position: relative;
	overflow: clip; /* clip (not hidden): contains the corner rings without creating a scroll container (same idiom as .lw-hero) */
	/* soft cream, shared by the lead + contact line — the tuned 90% AA value in one place */
	--lw-cta-soft: color-mix(in srgb, var(--wp--preset--color--base) 90%, var(--wp--preset--color--primary));
}
/* lotus-motif corner rings (master) — the content group's z-index lift below
   keeps them under the text/buttons */
.lw-cta::before,
.lw-cta::after {
	content: "";
	position: absolute;
	border-radius: 50%;
	pointer-events: none;
}
.lw-cta::before {
	top: -80px;
	right: -80px;
	width: 340px;
	height: 340px;
	border: 1.5px solid color-mix(in srgb, var(--wp--preset--color--base) 22%, transparent);
}
.lw-cta::after {
	left: -60px;
	bottom: -110px;
	width: 260px;
	height: 260px;
	border: 1.5px solid color-mix(in srgb, var(--wp--preset--color--base) 16%, transparent);
}
@media (max-width: 781px) { /* mobile: rings scale down (~58%), same overhang proportions */
	.lw-cta::before {
		top: -47px;
		right: -47px;
		width: 200px;
		height: 200px;
	}
	.lw-cta::after {
		left: -35px;
		bottom: -63px;
		width: 150px;
		height: 150px;
	}
}
.lw-cta > .wp-block-group {
	position: relative;
	z-index: 1;
}
/* in-band rhythm (master) — the group's 0.5rem blockGap covers eyebrow → h2 */
.lw-cta p.lw-measure {
	margin-top: 1rem; /* h2 → lead */
	color: var(--lw-cta-soft);
}
.lw-cta .wp-block-buttons {
	margin-top: 1.9rem; /* lead → buttons */
}
.lw-cta__contact {
	margin-top: 1.5rem; /* buttons → contact line */
	font-size: 0.92rem;
	color: var(--lw-cta-soft);
}
/* clickable email in the contact line (H, 2026-07-06) — the theme's sage link
   colour would vanish on the sage band, so it inherits the AA soft cream and
   signals with an underline instead */
.lw-cta__contact a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 3px;
}
.lw-cta__contact a:hover,
.lw-cta__contact a:focus {
	color: var(--wp--preset--color--base);
}
/* solid cream booking button — sage ink, blush-cream hover; the master gives
   BOTH buttons a 1.5px border (invisible on the solid one) with the padding
   reduced to compensate, so the pair sits at equal height */
.lw-cta .wp-block-button__link {
	background-color: var(--wp--preset--color--base);
	color: var(--wp--preset--color--primary-hover);
	border: 1.5px solid var(--wp--preset--color--base);
	padding: calc(0.7rem - 1.5px) calc(1.4rem - 1.5px);
}
.lw-cta .wp-block-button__link:hover,
.lw-cta .wp-block-button__link:focus,
.lw-cta .wp-block-button__link:active {
	background-color: color-mix(in srgb, var(--wp--preset--color--base) 55%, var(--wp--preset--color--surface));
	border-color: color-mix(in srgb, var(--wp--preset--color--base) 55%, var(--wp--preset--color--surface));
}
/* outlined "Email the clinic" ghost button — border at a 60% mix (3.05:1 on
   sage; the master's 55% reads 2.81 here, under the 3:1 non-text minimum).
   Selector mirrors the theme's rose outline rule above (its
   .wp-block-button.is-style-outline > … form out-specifies a plain class
   chain, so the .lw-cta scope must carry the same shape to win). */
.lw-cta .wp-block-button.is-style-outline > .wp-block-button__link.wp-element-button {
	color: var(--wp--preset--color--base);
	border: 1.5px solid color-mix(in srgb, var(--wp--preset--color--base) 60%, transparent);
	padding: calc(0.7rem - 1.5px) calc(1.4rem - 1.5px);
}
.lw-cta .wp-block-button.is-style-outline > .wp-block-button__link.wp-element-button:hover,
.lw-cta .wp-block-button.is-style-outline > .wp-block-button__link.wp-element-button:focus,
.lw-cta .wp-block-button.is-style-outline > .wp-block-button__link.wp-element-button:active {
	background-color: color-mix(in srgb, var(--wp--preset--color--base) 12%, transparent);
	border-color: var(--wp--preset--color--base);
}

/* ---------------------------------------------------------------------------
   Practitioner profile — the "at a glance" list (label + value rows).
   --------------------------------------------------------------------------- */
.lw-speclist {
	list-style: none;
	margin: 0;
	padding: var(--wp--preset--spacing--30) 0 0;
	border-top: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 12%, transparent);
}
.lw-speclist li {
	padding: 0.5rem 0;
	border-bottom: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 8%, transparent);
}
.lw-speclist strong {
	display: inline-block;
	min-width: 7.5rem;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--wp--preset--color--primary);
}

/* ---------------------------------------------------------------------------
   FAQ — native details/summary with a custom chevron, plus the progressive-
   enhancement search (hidden until the `js` class lands; see functions.php).
   --------------------------------------------------------------------------- */
.lw-faq .wp-block-details {
	border-bottom: 1px solid color-mix(in srgb, var(--wp--preset--color--contrast) 14%, transparent);
}
.lw-faq .wp-block-details summary {
	list-style: none;
	cursor: pointer;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.1rem 0.2rem;
	font-family: var(--wp--preset--font-family--literata);
	font-weight: 600;
	font-size: var(--wp--preset--font-size--large);
	color: var(--wp--preset--color--contrast);
}
.lw-faq .wp-block-details summary::-webkit-details-marker {
	display: none;
}
.lw-faq .wp-block-details summary::after {
	content: "";
	flex: none;
	width: 0.7rem;
	height: 0.7rem;
	margin-right: 0.3rem;
	border-right: 2px solid var(--wp--preset--color--primary);
	border-bottom: 2px solid var(--wp--preset--color--primary);
	transform: rotate(45deg);
	transition: transform 0.2s ease;
}
.lw-faq .wp-block-details[open] summary::after {
	transform: rotate(-135deg);
}
.lw-faq .wp-block-details.is-hidden {
	display: none;
}
.lw-faq__search {
	display: none;
}
.js .lw-faq__search {
	display: block;
}
.lw-faq__search label {
	display: block;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast-2);
	margin-bottom: 0.5rem;
}
.lw-faq__search input {
	width: 100%;
	font: inherit;
	padding: 0.7rem 1rem;
	border: 1.5px solid var(--wp--preset--color--contrast-2);
	border-radius: var(--lw-radius);
	background: var(--wp--preset--color--base);
	color: var(--wp--preset--color--contrast);
}
.lw-faq__count {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--contrast-2);
}
.lw-faq__none {
	display: none;
	color: var(--wp--preset--color--contrast);
}
.lw-faq__none.is-visible {
	display: block;
}

/* ---------------------------------------------------------------------------
   Footer — the master's light `base` footer: top hairline, 4-cell per-mode
   grid (brand lockup · Explore · Services · Get in touch), a `surface` crisis
   box between the grid and the bottom bar. Links keep the theme's underline
   hover — a deliberate deviation from the master's colour-shift hover.
   --------------------------------------------------------------------------- */
.site-footer {
	padding-block: clamp(2.8rem, 5vw, 4rem) 2rem; /* the master's footer padding (2.8rem floor ≠ the spacing-60 preset's 2.5rem) */
	border-top: 1px solid var(--lw-hairline);
}
/* Kill the root block-gap on the footer's template-part wrapper so the hairline
   sits flush against whatever band precedes it (H's feedback — no floating bar). */
.wp-site-blocks > footer.wp-block-template-part {
	margin-block-start: 0;
}

/* Hand-rolled grid (like .lw-trust) — per-mode columns (781 doctrine):
   1 mobile · 2 tablet · 4 desktop (brand · Explore · Services · Get in touch). */
.lw-footer__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 2rem;
}
@media (min-width: 782px) and (max-width: 999px) { /* tablet */
	.lw-footer__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}
@media (min-width: 1000px) { /* desktop */
	.lw-footer__grid {
		grid-template-columns: repeat(4, 1fr);
	}
}
.lw-footer__brand {
	max-width: 300px;
}

/* Brand lockup — chrome shared with the header (see the header Brand rules);
   only the footer's sizes live here. */
.site-footer .wp-block-site-logo img {
	width: 44px;
	height: 44px;
	border-radius: var(--lw-radius-lg);
}
.lw-footer__name {
	font-size: 1.1rem;
	line-height: 1.05;
	color: var(--wp--preset--color--contrast);
}
.lw-footer__subtitle {
	font-size: 0.6rem;
}
.lw-footer__tagline {
	font-size: 0.92rem;
	font-weight: 600;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--primary);
}
.lw-footer__blurb {
	font-size: 0.92rem;
	line-height: 1.5;
	color: var(--wp--preset--color--contrast-2);
}

/* Column labels: the shared eyebrow at the master's footer scale — colour comes
   from the blocks' textColor (contrast-2), per the eyebrow's own contract.
   The margin-bottom collapses with the columns' 0.6rem blockGap to give every
   heading the master's uniform 0.9rem gap (H: keep the label gaps identical). */
.site-footer .lw-eyebrow {
	font-size: 0.74rem;
	letter-spacing: 0.12em;
	margin-bottom: 0.9rem;
}

/* Link stacks — one shape for wp:page-list and wp:list output alike */
.lw-footer__col {
	font-size: 0.96rem;
}
.lw-footer__col ul {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.6rem;
}

/* Ink links on the light ground; hover keeps the theme's underline */
.site-footer a:where(:not(.wp-element-button)) {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}
.site-footer a:where(:not(.wp-element-button)):hover,
.site-footer a:where(:not(.wp-element-button)):focus {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* The small Book button — colours/hover/radius come from theme.json */
.lw-footer__book .wp-block-button__link {
	font-size: 0.9rem;
	padding: 0.6rem 1.05rem;
}

/* Crisis notice — a quiet surface box; soft ink ≈ the master's #544a42, AA on
   surface. Sizes are the master's. */
.lw-crisis {
	background: var(--wp--preset--color--surface);
	border-radius: var(--lw-radius-lg);
	padding: 1rem 1.2rem;
	font-size: 0.86rem;
	line-height: 1.5;
	color: var(--lw-ink-soft);
}
.lw-crisis strong {
	color: var(--wp--preset--color--contrast);
}

/* Bottom bar — hairline above the © line and the Privacy/Accessibility links;
   0.84rem is the master's bottom-bar size. Paragraphs inherit the colour. */
.lw-footer__bottom {
	border-top: 1px solid var(--lw-hairline-soft);
	padding-top: 1.4rem;
	font-size: 0.84rem;
	color: var(--wp--preset--color--contrast-2);
}
.lw-footer__bottom a {
	color: var(--wp--preset--color--contrast-2);
}
