// src/sections.jsx — page sections

const { useState: useS } = React;

// ─── hamburger button ─────────────────────────────────────────────────
function Hamburger({ open, onClick, palette }) {
	const bar = (i) => ({
		position: "absolute",
		left: 12,
		right: 12,
		top: "50%",
		height: 1.5,
		background: palette.ink,
		borderRadius: 1,
		transformOrigin: "center",
		transition: "transform .3s ease, opacity .25s ease",
		transform:
			i === 0
				? open
					? "translateY(-50%) rotate(45deg)"
					: "translateY(calc(-50% - 7px))"
				: i === 1
					? open
						? "translateY(-50%) scaleX(0)"
						: "translateY(-50%)"
					: open
						? "translateY(-50%) rotate(-45deg)"
						: "translateY(calc(-50% + 7px))",
		opacity: i === 1 && open ? 0 : 1,
	});
	return (
		<button
			aria-label={open ? "Close menu" : "Open menu"}
			aria-expanded={open}
			onClick={onClick}
			style={{
				width: 44,
				height: 44,
				position: "relative",
				display: "inline-flex",
			}}
		>
			<span style={bar(0)} />
			<span style={bar(1)} />
			<span style={bar(2)} />
		</button>
	);
}

// ─── full-screen mobile menu drawer ───────────────────────────────────
function MobileMenu({ open, onClose, palette, fonts }) {
	const closeBtnRef = React.useRef(null);
	const lastFocusRef = React.useRef(null);

	React.useEffect(() => {
		if (!open) return;
		lastFocusRef.current = document.activeElement;
		const prev = document.body.style.overflow;
		document.body.style.overflow = "hidden";
		const onKey = (e) => {
			if (e.key === "Escape") onClose();
		};
		window.addEventListener("keydown", onKey);
		// delay focus until after slide-in begins
		const t = setTimeout(
			() => closeBtnRef.current && closeBtnRef.current.focus(),
			60,
		);
		return () => {
			document.body.style.overflow = prev;
			window.removeEventListener("keydown", onKey);
			clearTimeout(t);
			if (lastFocusRef.current && lastFocusRef.current.focus)
				lastFocusRef.current.focus();
		};
	}, [open, onClose]);

	const links = [
		{ href: "#approach", label: "Approach" },
		{ href: "#sessions", label: "Sessions" },
		{ href: "#membership", label: "Membership" },
		{ href: "#practitioner", label: "Practitioner" },
		{ href: "#faq", label: "FAQ" },
		{ href: "#visit", label: "Visit" },
	];

	const node = (
		<div
			role="dialog"
			aria-modal="true"
			aria-hidden={!open}
			style={{
				position: "fixed",
				inset: 0,
				zIndex: 200,
				background: palette.bg,
				color: palette.ink,
				transform: open ? "translateX(0)" : "translateX(100%)",
				transition: "transform .35s cubic-bezier(.22,.61,.36,1)",
				visibility: open ? "visible" : "hidden",
				display: "flex",
				flexDirection: "column",
				padding:
					"calc(20px + env(safe-area-inset-top, 0px)) var(--gutter) calc(32px + var(--safe-bottom))",
				overflowY: "auto",
				WebkitOverflowScrolling: "touch",
			}}
		>
			<div style={{ display: "flex", justifyContent: "flex-end" }}>
				<button
					ref={closeBtnRef}
					onClick={onClose}
					aria-label="Close menu"
					style={{
						width: 44,
						height: 44,
						display: "inline-flex",
						alignItems: "center",
						justifyContent: "center",
						fontFamily: '"JetBrains Mono", monospace',
						fontSize: 26,
						color: palette.ink,
						lineHeight: 1,
					}}
				>
					×
				</button>
			</div>

			<nav
				style={{
					display: "flex",
					flexDirection: "column",
					marginTop: 16,
					flex: 1,
				}}
			>
				{links.map((l) => (
					<a
						key={l.href}
						href={l.href}
						onClick={onClose}
						style={{
							fontFamily: fonts.display,
							fontWeight: fonts.displayWeight,
							fontSize: "clamp(36px, 9vw, 56px)",
							lineHeight: 1.1,
							padding: "16px 0",
							borderBottom: `1px solid ${palette.rim}`,
							minHeight: 64,
							display: "flex",
							alignItems: "center",
						}}
					>
						{l.label}
					</a>
				))}
			</nav>

			<div
				style={{
					marginTop: 28,
					display: "flex",
					flexDirection: "column",
					gap: 6,
				}}
			>
				<a
					href={STUDIO.phoneHref}
					className="mono"
					style={{ opacity: 0.85, fontSize: 12, padding: "6px 0" }}
				>
					{STUDIO.phone}
				</a>
				<a
					href={STUDIO.instagramUrl}
					target="_blank"
					rel="noopener"
					className="mono"
					style={{ opacity: 0.7, fontSize: 11, padding: "6px 0" }}
				>
					{STUDIO.instagramHandle}
				</a>
				<div
					className="mono"
					style={{ opacity: 0.55, fontSize: 11, marginTop: 4, lineHeight: 1.5 }}
				>
					{STUDIO.addressLine1} · {STUDIO.addressLine2}
					<br />
					{STUDIO.addressLine3}
				</div>
			</div>

			<a
				href={BOOKING_URL}
				target="_blank"
				rel="noopener"
				onClick={onClose}
				style={{
					marginTop: 28,
					padding: "18px 24px",
					background: palette.accent,
					color: palette.bg,
					borderRadius: 999,
					textAlign: "center",
					fontFamily: '"JetBrains Mono", monospace',
					fontSize: 13,
					letterSpacing: ".06em",
					textTransform: "uppercase",
					minHeight: 56,
					display: "flex",
					alignItems: "center",
					justifyContent: "center",
				}}
			>
				Book a session →
			</a>
		</div>
	);
	return ReactDOM.createPortal(node, document.body);
}

// ─── sticky mobile book bar ───────────────────────────────────────────
function MobileBookBar({ palette }) {
	const mobile = useMediaQuery("(max-width: 720px)");
	if (!mobile) return null;
	return (
		<div
			role="region"
			aria-label="Booking"
			style={{
				position: "fixed",
				left: 0,
				right: 0,
				bottom: 0,
				zIndex: 60,
				background: `${palette.bg}f0`,
				backdropFilter: "blur(12px) saturate(140%)",
				WebkitBackdropFilter: "blur(12px) saturate(140%)",
				borderTop: `1px solid ${palette.rim}`,
				padding: "10px var(--gutter) calc(10px + var(--safe-bottom))",
				display: "flex",
				alignItems: "center",
				justifyContent: "space-between",
				gap: 12,
				color: palette.ink,
			}}
		>
			<div
				style={{
					display: "flex",
					flexDirection: "column",
					lineHeight: 1.15,
					minWidth: 0,
				}}
			>
				<span className="mono" style={{ fontSize: 11, opacity: 0.9 }}>
					Healing Hub
				</span>
				<span style={{ fontSize: 12, opacity: 0.6 }}>60 min from $105</span>
			</div>
			<a
				href={BOOKING_URL}
				target="_blank"
				rel="noopener"
				style={{
					padding: "12px 22px",
					minHeight: 44,
					display: "inline-flex",
					alignItems: "center",
					justifyContent: "center",
					background: palette.accent,
					color: palette.bg,
					borderRadius: 999,
					fontFamily: '"JetBrains Mono", monospace',
					fontSize: 12,
					letterSpacing: ".06em",
					textTransform: "uppercase",
					flexShrink: 0,
				}}
			>
				Book →
			</a>
		</div>
	);
}

// ─── header ───────────────────────────────────────────────────────────
function Header({ palette, fonts }) {
	const [scrolled, setScrolled] = useS(false);
	const [menuOpen, setMenuOpen] = useS(false);
	const mobile = useMediaQuery("(max-width: 720px)");

	React.useEffect(() => {
		const onScroll = () => setScrolled(window.scrollY > 60);
		window.addEventListener("scroll", onScroll, { passive: true });
		onScroll();
		return () => window.removeEventListener("scroll", onScroll);
	}, []);

	return (
		<>
			<header
				style={{
					position: "fixed",
					top: 0,
					left: 0,
					right: 0,
					zIndex: 50,
					padding: scrolled ? "12px var(--gutter)" : "20px var(--gutter)",
					display: "flex",
					alignItems: "center",
					justifyContent: "space-between",
					gap: 16,
					color: palette.ink,
					background: scrolled ? palette.bg : "transparent",
					borderBottom: scrolled
						? `1px solid ${palette.rim}`
						: "1px solid transparent",
					boxShadow: scrolled ? "0 8px 24px rgba(0,0,0,.18)" : "none",
					transition:
						"background .25s ease, padding .25s ease, box-shadow .25s ease, border-color .25s ease",
				}}
			>
				<a
					href="#top"
					style={{ display: "flex", alignItems: "center", gap: 12 }}
				>
					<img
						src="assets/healing_hub_logo_white.png"
						alt="The Healing Hub — Massage & Wellness"
						style={{
							height: "clamp(40px, 8vw, 60px)",
							width: "auto",
							display: "block",
							filter: palette.isDark ? "none" : "brightness(0) saturate(100%)",
							opacity: palette.isDark ? 1 : 0.9,
						}}
					/>
				</a>

				{!mobile && (
					<nav style={{ display: "flex", gap: 32 }} className="mono">
						<a href="#approach" style={{ opacity: 0.75 }}>
							Approach
						</a>
						<a href="#sessions" style={{ opacity: 0.75 }}>
							Sessions
						</a>
						<a href="#membership" style={{ opacity: 0.75 }}>
							Membership
						</a>
						<a href="#visit" style={{ opacity: 0.75 }}>
							Visit
						</a>
					</nav>
				)}

				{!mobile && (
					<a
						href={BOOKING_URL}
						target="_blank"
						rel="noopener"
						style={{
							padding: "12px 22px",
							border: `1px solid ${palette.accent}`,
							color: palette.accent,
							borderRadius: 999,
							fontSize: 12,
							letterSpacing: ".06em",
							textTransform: "uppercase",
							fontFamily: '"JetBrains Mono", monospace',
							minHeight: 44,
							display: "inline-flex",
							alignItems: "center",
						}}
					>
						Book a session →
					</a>
				)}

				{mobile && (
					<Hamburger
						open={menuOpen}
						onClick={() => setMenuOpen((o) => !o)}
						palette={palette}
					/>
				)}
			</header>

			{mobile && (
				<MobileMenu
					open={menuOpen}
					onClose={() => setMenuOpen(false)}
					palette={palette}
					fonts={fonts}
				/>
			)}
		</>
	);
}

// ─── hero ─────────────────────────────────────────────────────────────
function Hero({ palette, fonts, motion: _motion }) {
	// Lock the hero to the visible viewport at mount so the URL-bar collapse
	// on iOS Safari / Firefox Android doesn't grow the section as the user
	// scrolls. Re-measure only on orientation change.
	const [minH, setMinH] = useS(null);
	React.useEffect(() => {
		const measure = () => {
			const h = window.innerHeight;
			if (h > 0) setMinH(h);
		};
		measure();
		const onOrient = () => setTimeout(measure, 250);
		window.addEventListener("orientationchange", onOrient);
		return () => window.removeEventListener("orientationchange", onOrient);
	}, []);

	return (
		<section
			id="top"
			data-screen-label="01 Hero"
			className="hero-fill"
			style={{
				position: "relative",
				padding:
					"clamp(96px, 12vw, 132px) var(--gutter) clamp(56px, 8vw, 96px)",
				color: palette.ink,
				...(minH != null ? { minHeight: `${minH}px` } : null),
			}}
		>
			<div className="hero-inner">
				<div className="hero-copy">
					<div
						style={{
							fontFamily: '"Sacramento", cursive',
							fontWeight: 400,
							color: palette.accent,
							opacity: 0.82,
							marginBottom: 8,
							fontSize: "clamp(16px, 1.55vw, 22px)",
							lineHeight: 1,
							letterSpacing: ".01em",
						}}
					>
						Welcome to
					</div>
					<h1
						style={{
							fontFamily: fonts.display,
							fontSize: "clamp(52px, 8.8vw, 132px)",
							lineHeight: 0.92,
							fontWeight: fonts.displayWeight,
							letterSpacing: "-.035em",
							marginBottom: 24,
							whiteSpace: "nowrap",
						}}
					>
						The Healing Hub
					</h1>
					<p
						style={{
							maxWidth: "100%",
							fontFamily: '"Fraunces", "Cormorant Garamond", serif',
							fontSize: "clamp(21px, 2.2vw, 31px)",
							fontVariationSettings: '"SOFT" 60, "opsz" 72',
							fontWeight: 400,
							lineHeight: 1.08,
							letterSpacing: ".005em",
							color: palette.accent,
							marginBottom: 24,
							whiteSpace: "nowrap",
						}}
					>
						Rest is where healing begins.
					</p>
					<p
						style={{
							maxWidth: 820,
							fontSize: 18,
							lineHeight: 1.55,
							color: palette.inkSoft,
							marginBottom: 48,
						}}
					>
						A grounded space for therapeutic massage, nervous system support,
						and intentional bodywork designed to help you slow down, release
						tension, and reconnect with your body.
						<br></br>
						<br></br>
						Here, care is unhurried and deeply intentional—an invitation to
						return to your sacred well, and in doing so, return to yourself.
					</p>

					<div className="hero-actions">
						<a
							href={BOOKING_URL}
							target="_blank"
							rel="noopener"
							style={{
								padding: "clamp(14px, 4vw, 18px) clamp(22px, 6vw, 32px)",
								background: palette.accent,
								color: palette.bg,
								borderRadius: 999,
								fontWeight: 500,
								fontSize: 14,
								letterSpacing: ".04em",
								textTransform: "uppercase",
								fontFamily: '"JetBrains Mono", monospace',
								minHeight: 48,
								display: "inline-flex",
								alignItems: "center",
							}}
						>
							Book a Session
						</a>
						<a
							href="#membership"
							className="mono"
							style={{
								padding: "clamp(14px, 4vw, 18px) clamp(18px, 5vw, 24px)",
								color: palette.ink,
								opacity: 0.8,
								display: "inline-flex",
								alignItems: "center",
								gap: 10,
								fontSize: 13,
								minHeight: 48,
							}}
						>
							Join the Slow Down Club
						</a>
					</div>
				</div>

				<div
					className="hero-studio-placeholder"
					aria-label="Massage studio image placeholder"
				>
					<div
						className="hero-studio-frame"
						style={{
							border: `1px solid ${palette.rim}`,
							background: `linear-gradient(145deg, ${palette.surfaceWarm} 0%, ${palette.surface} 48%, ${palette.accent}26 100%)`,
							boxShadow: "0 28px 90px rgba(6,40,61,.14)",
							display: "grid",
							placeItems: "center",
							position: "relative",
						}}
					>
						<div
							style={{
								position: "absolute",
								inset: 18,
								border: `1px solid ${palette.rim}`,
								borderRadius: "inherit",
								opacity: 0.55,
							}}
						/>
						<span
							className="mono"
							style={{
								color: palette.inkSoft,
								opacity: 0.72,
								textAlign: "center",
								padding: 24,
							}}
						>
							Studio image placeholder
						</span>
					</div>
				</div>
			</div>
		</section>
	);
}

// ─── approach / philosophy ────────────────────────────────────────────
function Approach({ palette, fonts }) {
	const items = [
		{
			n: "01",
			h: "Slow descent",
			p: "We begin where you actually are: wired, depleted, somewhere in between. The first ten minutes are about letting the room hold you.",
		},
		{
			n: "02",
			h: "Therapeutic depth",
			p: "Real bodywork on tissue and fascia, including the places that have been gripping for weeks. The pace is slow enough that your body can actually drop into it instead of bracing against it.",
		},
		{
			n: "03",
			h: "Ritual elements",
			p: "Hot towels, aromatherapy, optional sound and intuitive cards. There's more to a body than tissue, and the work is built that way.",
		},
		{
			n: "04",
			h: "Carry it home",
			p: "You leave with the well a little fuller. The work compounds; monthly visits keep the level up.",
		},
	];
	return (
		<section
			id="approach"
			data-screen-label="02 Approach"
			style={{
				position: "relative",
				padding: "var(--section-y) var(--gutter)",
				color: palette.ink,
			}}
		>
			<h2
				style={{
					fontFamily: fonts.display,
					fontWeight: fonts.displayWeight,
					fontSize: "clamp(40px, 5vw, 72px)",
					lineHeight: 1.05,
					letterSpacing: "-.01em",
					marginBottom: "clamp(32px, 5vw, 48px)",
				}}
			>
				The body is a vessel. Most arrive carrying it{" "}
				<em
					style={{
						fontStyle: fonts.displayItalic ? "italic" : "normal",
						color: palette.accent,
					}}
				>
					nearly empty
				</em>
				.
			</h2>
			<div className="grid-2">
				{items.map((b) => (
					<div key={b.n}>
						<div
							className="mono"
							style={{ color: palette.accent, marginBottom: 10 }}
						>
							{b.n}
						</div>
						<h3
							style={{
								fontFamily: fonts.display,
								fontSize: 24,
								fontWeight: fonts.displayWeight,
								marginBottom: 8,
							}}
						>
							{b.h}
						</h3>
						<p
							style={{ fontSize: 15, lineHeight: 1.55, color: palette.inkSoft }}
						>
							{b.p}
						</p>
					</div>
				))}
			</div>
		</section>
	);
}

// ─── sessions ─────────────────────────────────────────────────────────
function SessionCard({ s, palette, fonts, motion, signature }) {
	return (
		<Ripple palette={palette} motion={motion}>
			<div
				style={{
					border: `1px solid ${palette.rim}`,
					background: signature ? palette.surface : "transparent",
					padding: signature
						? "clamp(24px, 5vw, 40px) clamp(20px, 5vw, 36px)"
						: "clamp(20px, 4vw, 28px) clamp(20px, 4vw, 32px)",
					display: "flex",
					flexDirection: "column",
					gap: 18,
					height: "100%",
				}}
			>
				<h3
					style={{
						fontFamily: fonts.display,
						fontWeight: fonts.displayWeight,
						fontSize: signature
							? "clamp(36px, 7vw, 56px)"
							: "clamp(28px, 5vw, 36px)",
						lineHeight: 0.95,
						letterSpacing: "-.01em",
					}}
				>
					{s.name}
				</h3>
				<div
					style={{
						display: "flex",
						alignItems: "baseline",
						gap: 14,
						flexWrap: "wrap",
					}}
				>
					<div
						style={{
							fontFamily: fonts.display,
							fontSize: signature
								? "clamp(32px, 6vw, 44px)"
								: "clamp(24px, 5vw, 32px)",
							color: palette.accent,
							fontWeight: fonts.displayWeight,
						}}
					>
						${s.price}
					</div>
					<div className="mono" style={{ opacity: 0.6 }}>
						· {s.duration}
					</div>
				</div>
				<p
					style={{
						fontSize: 14.5,
						lineHeight: 1.55,
						color: palette.inkSoft,
						flex: 1,
					}}
				>
					{s.blurb}
				</p>
				{s.includes && (
					<ul
						style={{
							listStyle: "none",
							display: "flex",
							flexWrap: "wrap",
							gap: "6px 14px",
						}}
					>
						{s.includes.map((i) => (
							<li
								key={i}
								className="mono"
								style={{
									fontSize: 9,
									opacity: 0.85,
									padding: "4px 10px",
									border: `1px solid ${palette.rim}`,
									borderRadius: 999,
								}}
							>
								· {i}
							</li>
						))}
					</ul>
				)}
				{s.id === "extended" ? (
					<div
						className="mono"
						style={{
							marginTop: 8,
							color: palette.inkSoft,
							fontSize: 11,
							borderTop: `1px solid ${palette.rim}`,
							paddingTop: 18,
						}}
					>
						Add to session when booking
					</div>
				) : (
					<a
						href={BOOKING_URL}
						target="_blank"
						rel="noopener"
						className="mono"
						style={{
							marginTop: 8,
							color: palette.accent,
							fontSize: 11,
							borderTop: `1px solid ${palette.rim}`,
							paddingTop: 18,
							paddingBottom: 6,
							minHeight: 44,
							display: "inline-flex",
							alignItems: "center",
						}}
					>
						Reserve →
					</a>
				)}
			</div>
		</Ripple>
	);
}

function Sessions({ palette, fonts, motion }) {
	const featured = SIGNATURE.find(
		(s) => s.id === "75-minute-signature-massage",
	);
	const supporting = SIGNATURE.filter(
		(s) => s.id !== "75-minute-signature-massage",
	);

	return (
		<section
			id="sessions"
			data-screen-label="03 Sessions"
			style={{
				padding: "var(--section-y) var(--gutter)",
				color: palette.ink,
				position: "relative",
			}}
		>
			<h2
				style={{
					fontFamily: fonts.display,
					fontSize: "clamp(48px,6vw,88px)",
					fontWeight: fonts.displayWeight,
					lineHeight: 0.95,
					marginBottom: "clamp(40px, 6vw, 64px)",
				}}
			>
				Signature
				<br />
				<em
					style={{
						color: palette.accent,
						fontStyle: fonts.displayItalic ? "italic" : "normal",
					}}
				>
					sessions
				</em>
			</h2>

			{featured && (
				<div style={{ marginBottom: "clamp(28px, 4vw, 48px)" }}>
					<SessionCard
						s={featured}
						palette={palette}
						fonts={fonts}
						motion={motion}
						signature
					/>
				</div>
			)}

			<div className="grid-3" style={{ marginBottom: "var(--rhythm)" }}>
				{supporting.map((s) => (
					<SessionCard
						key={s.id}
						s={s}
						palette={palette}
						fonts={fonts}
						motion={motion}
					/>
				))}
			</div>
		</section>
	);
}

// ─── enhancements ─────────────────────────────────────────────────────
function Enhancements({ palette, fonts }) {
	const mobile = useMediaQuery("(max-width: 720px)");

	if (mobile) {
		return (
			<section
				id="enhancements"
				data-screen-label="04 Enhancements"
				style={{
					padding: "var(--section-y) var(--gutter)",
					color: palette.ink,
					position: "relative",
				}}
			>
				<div style={{ marginBottom: 28 }}>
					<h2
						style={{
							fontFamily: fonts.display,
							fontSize: "clamp(40px, 9vw, 68px)",
							fontWeight: fonts.displayWeight,
							lineHeight: 1.0,
							marginBottom: 16,
						}}
					>
						Enhancements
					</h2>
					<p style={{ fontSize: 15, color: palette.inkSoft, lineHeight: 1.6 }}>
						Each ritual is $25 and woven directly into your session. Layer
						freely — add to any massage service.
					</p>
				</div>
				<div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
					{ENHANCEMENTS.map((e, i) => (
						<div
							key={e.id}
							style={{
								border: `1px solid ${palette.rim}`,
								padding: "20px 20px",
								display: "grid",
								gridTemplateColumns: "auto 1fr auto",
								gap: "8px 16px",
								alignItems: "baseline",
							}}
						>
							<div
								className="mono"
								style={{ color: palette.accent, opacity: 0.85, fontSize: 11 }}
							>
								0{i + 1}
							</div>
							<div />
							<div
								style={{
									fontFamily: fonts.display,
									fontSize: 24,
									color: palette.accent,
									fontWeight: fonts.displayWeight,
									textAlign: "right",
								}}
							>
								+${e.price}
							</div>
							<h3
								style={{
									fontFamily: fonts.display,
									fontSize: 22,
									fontWeight: fonts.displayWeight,
									gridColumn: "1 / -1",
									marginTop: 4,
									lineHeight: 1.15,
								}}
							>
								{e.name}
							</h3>
							<p
								style={{
									fontSize: 14,
									color: palette.inkSoft,
									lineHeight: 1.5,
									gridColumn: "1 / -1",
									marginTop: 2,
								}}
							>
								{e.detail}
							</p>
						</div>
					))}
				</div>
			</section>
		);
	}

	return (
		<section
			id="enhancements"
			data-screen-label="04 Enhancements"
			style={{
				padding: "var(--section-y) var(--gutter)",
				color: palette.ink,
				position: "relative",
			}}
		>
			<div
				style={{
					display: "grid",
					gridTemplateColumns: "1fr 2fr",
					gap: 64,
					alignItems: "start",
				}}
			>
				<div>
					<h2
						style={{
							fontFamily: fonts.display,
							fontSize: "clamp(40px,5vw,68px)",
							fontWeight: fonts.displayWeight,
							lineHeight: 1.0,
							marginBottom: 24,
						}}
					>
						Enhancements
					</h2>
					<p style={{ fontSize: 15, color: palette.inkSoft, lineHeight: 1.6 }}>
						Each ritual is $25 and woven directly into your session. Layer
						freely — add to any massage service.
					</p>
				</div>
				<div>
					{ENHANCEMENTS.map((e, i) => (
						<div
							key={e.id}
							style={{
								display: "grid",
								gridTemplateColumns: "40px 1fr 80px",
								gap: 24,
								alignItems: "baseline",
								padding: "28px 0",
								borderTop: i === 0 ? `1px solid ${palette.rim}` : "none",
								borderBottom: `1px solid ${palette.rim}`,
							}}
						>
							<div
								className="mono"
								style={{ color: palette.accent, opacity: 0.85 }}
							>
								0{i + 1}
							</div>
							<div>
								<h3
									style={{
										fontFamily: fonts.display,
										fontSize: 28,
										fontWeight: fonts.displayWeight,
										marginBottom: 6,
									}}
								>
									{e.name}
								</h3>
								<p
									style={{
										fontSize: 14,
										color: palette.inkSoft,
										lineHeight: 1.5,
									}}
								>
									{e.detail}
								</p>
							</div>
							<div
								style={{
									textAlign: "right",
									fontFamily: fonts.display,
									fontSize: 28,
									color: palette.accent,
									fontWeight: fonts.displayWeight,
								}}
							>
								+${e.price}
							</div>
						</div>
					))}
				</div>
			</div>
		</section>
	);
}

// ─── membership ───────────────────────────────────────────────────────
function Membership({ palette, fonts, motion: _motion }) {
	return (
		<section
			id="membership"
			data-screen-label="05 Membership"
			style={{
				padding: "var(--section-y) var(--gutter)",
				color: palette.ink,
				position: "relative",
			}}
		>
			<h2
				style={{
					fontFamily: fonts.display,
					fontSize: "clamp(48px,6vw,88px)",
					fontWeight: fonts.displayWeight,
					lineHeight: 0.95,
					marginBottom: "clamp(40px, 6vw, 64px)",
				}}
			>
				The Slow Down
				<br />
				<em
					style={{
						color: palette.accent,
						fontStyle: fonts.displayItalic ? "italic" : "normal",
					}}
				>
					Club
				</em>
			</h2>
			<div
				style={{
					border: `1px solid ${palette.rim}`,
					background: `linear-gradient(180deg, ${palette.surface}, ${palette.surfaceWarm})`,
					padding: "clamp(40px, 8vw, 72px) clamp(24px, 6vw, 64px)",
					position: "relative",
					overflow: "hidden",
				}}
			>
				<svg
					aria-hidden
					viewBox="0 0 500 500"
					style={{
						position: "absolute",
						right: "clamp(-100px, -8vw, -30px)",
						top: "clamp(-100px, -8vw, -30px)",
						opacity: 0.18,
						width: "clamp(280px, 50vw, 500px)",
						height: "clamp(280px, 50vw, 500px)",
						pointerEvents: "none",
					}}
				>
					{[0, 1, 2, 3, 4, 5, 6].map((i) => (
						<circle
							key={i}
							cx="250"
							cy="250"
							r={40 + i * 30}
							fill="none"
							stroke={palette.accent}
							strokeWidth="1"
						/>
					))}
				</svg>

				<div
					className="grid-2"
					style={{ position: "relative", gap: "clamp(32px, 5vw, 80px)" }}
				>
					<div>
						<h3
							style={{
								fontFamily: fonts.display,
								fontWeight: fonts.displayWeight,
								fontSize: "clamp(32px,3.6vw,52px)",
								lineHeight: 1,
								marginBottom: 24,
								letterSpacing: "-.01em",
							}}
						>
							A rhythm of
							<br />
							<em
								style={{
									fontStyle: fonts.displayItalic ? "italic" : "normal",
									color: palette.accent,
								}}
							>
								consistent
							</em>{" "}
							care.
						</h3>
						<p
							style={{
								fontSize: 17,
								color: palette.inkSoft,
								lineHeight: 1.55,
								maxWidth: 480,
								marginBottom: 32,
							}}
						>
							Membership is designed to support consistency of care,
							restoration, and ongoing wellness through intentional therapeutic
							bodywork
						</p>
						<a
							href={BOOKING_URL}
							target="_blank"
							rel="noopener"
							style={{
								display: "inline-flex",
								alignItems: "center",
								padding: "16px 28px",
								background: palette.accent,
								color: palette.bg,
								borderRadius: 999,
								fontFamily: '"JetBrains Mono", monospace',
								fontSize: 12,
								letterSpacing: ".06em",
								textTransform: "uppercase",
								minHeight: 48,
							}}
						>
							Begin membership →
						</a>
					</div>
					<ul
						style={{
							listStyle: "none",
							display: "flex",
							flexDirection: "column",
							gap: 14,
						}}
					>
						{MEMBERSHIP.bullets.map((b, i) => (
							<li
								key={i}
								style={{
									display: "grid",
									gridTemplateColumns: "24px 1fr",
									gap: 14,
									alignItems: "baseline",
									paddingBottom: 14,
									borderBottom: `1px solid ${palette.rim}`,
								}}
							>
								<span
									style={{
										color: palette.accent,
										fontFamily: '"JetBrains Mono", monospace',
										fontSize: 11,
									}}
								>
									0{i + 1}
								</span>
								<span style={{ fontSize: 15, lineHeight: 1.45 }}>{b}</span>
							</li>
						))}
					</ul>
				</div>
			</div>
		</section>
	);
}

// ─── practitioner ─────────────────────────────────────────────────────
function Practitioner({ palette, fonts }) {
	return (
		<section
			id="practitioner"
			data-screen-label="06 Practitioner"
			style={{
				padding: "var(--section-y) var(--gutter)",
				color: palette.ink,
				position: "relative",
			}}
		>
			<div className="grid-2" style={{ alignItems: "end" }}>
				<img
					src={PRACTITIONER.photo}
					alt="Nicole Farrell, licensed massage therapist"
					style={{
						width: "100%",
						aspectRatio: "4 / 5",
						objectFit: "cover",
						border: `1px solid ${palette.rim}`,
						borderRadius: 2,
						display: "block",
					}}
				/>
				<div style={{ paddingBottom: "clamp(0px, 4vw, 40px)" }}>
					<h2
						style={{
							fontFamily: fonts.display,
							fontSize: "clamp(44px,5vw,76px)",
							fontWeight: fonts.displayWeight,
							lineHeight: 1,
							letterSpacing: "-.01em",
							marginBottom: 8,
						}}
					>
						{PRACTITIONER.name}
					</h2>
					<h3
						style={{
							fontFamily: fonts.display,
							fontSize: "clamp(28px,3vw,40px)",
							fontWeight: fonts.displayWeight,
							lineHeight: 1.1,
							color: palette.accent,
							marginBottom: 24,
						}}
					>
						{PRACTITIONER.title}
					</h3>
					<p
						style={{
							fontSize: 17,
							lineHeight: 1.6,
							color: palette.inkSoft,
							marginBottom: 32,
							maxWidth: 520,
							whiteSpace: "pre-line",
						}}
					>
						{PRACTITIONER.body}
					</p>
					<ul
						style={{
							listStyle: "none",
							display: "flex",
							flexWrap: "wrap",
							gap: 8,
						}}
					>
						{PRACTITIONER.credentials.map((c) => (
							<li
								key={c}
								className="mono"
								style={{
									fontSize: 10,
									padding: "8px 14px",
									border: `1px solid ${palette.rim}`,
									borderRadius: 999,
									opacity: 0.85,
								}}
							>
								{c}
							</li>
						))}
					</ul>
				</div>
			</div>
		</section>
	);
}

// ─── testimonials ─────────────────────────────────────────────────────
function Testimonials({ palette, fonts }) {
	const mobile = useMediaQuery("(max-width: 720px)");
	const scrollerRef = React.useRef(null);
	const [active, setActive] = useS(0);

	React.useEffect(() => {
		if (!mobile) return;
		const root = scrollerRef.current;
		if (!root) return;
		const cards = Array.from(root.querySelectorAll("[data-card]"));
		const io = new IntersectionObserver(
			(entries) => {
				let best = { ratio: 0, idx: active };
				entries.forEach((en) => {
					if (en.intersectionRatio > best.ratio) {
						best = {
							ratio: en.intersectionRatio,
							idx: Number(en.target.dataset.idx),
						};
					}
				});
				if (best.ratio > 0.5) setActive(best.idx);
			},
			{ root, threshold: [0, 0.25, 0.5, 0.75, 1] },
		);
		cards.forEach((c) => io.observe(c));
		return () => io.disconnect();
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [mobile]);

	if (mobile) {
		return (
			<section
				id="testimonials"
				data-screen-label="07 Testimonials"
				style={{
					padding: "var(--section-y) var(--gutter)",
					color: palette.ink,
					position: "relative",
				}}
			>
				<div ref={scrollerRef} className="hsnap">
					{TESTIMONIALS.map((t, i) => (
						<figure
							key={i}
							data-card
							data-idx={i}
							style={{
								padding: 28,
								border: `1px solid ${palette.rim}`,
								display: "flex",
								flexDirection: "column",
								gap: 22,
								minHeight: 320,
							}}
						>
							<blockquote
								style={{
									fontFamily: fonts.display,
									fontSize: 22,
									lineHeight: 1.3,
									fontWeight: fonts.displayWeight,
									fontStyle: fonts.displayItalic ? "italic" : "normal",
								}}
							>
								"{t.quote}"
							</blockquote>
							<figcaption
								style={{
									borderTop: `1px solid ${palette.rim}`,
									paddingTop: 14,
									marginTop: "auto",
								}}
							>
								<div style={{ fontSize: 14, fontWeight: 500 }}>{t.who}</div>
								<div
									className="mono"
									style={{ opacity: 0.6, fontSize: 10, marginTop: 4 }}
								>
									{t.role}
								</div>
							</figcaption>
						</figure>
					))}
				</div>
				<div
					style={{
						display: "flex",
						justifyContent: "center",
						gap: 8,
						marginTop: 22,
					}}
					aria-hidden
				>
					{TESTIMONIALS.map((_, i) => (
						<span
							key={i}
							style={{
								width: i === active ? 22 : 6,
								height: 6,
								borderRadius: 999,
								background: i === active ? palette.accent : palette.rim,
								transition: "width .3s ease, background .3s ease",
							}}
						/>
					))}
				</div>
			</section>
		);
	}

	return (
		<section
			id="testimonials"
			data-screen-label="07 Testimonials"
			style={{
				padding: "var(--section-y) var(--gutter)",
				color: palette.ink,
				position: "relative",
			}}
		>
			<div
				style={{
					display: "grid",
					gridTemplateColumns: "repeat(3, 1fr)",
					gap: 32,
				}}
			>
				{TESTIMONIALS.map((t, i) => (
					<figure
						key={i}
						style={{
							padding: 36,
							border: `1px solid ${palette.rim}`,
							background: i === 1 ? palette.surface : "transparent",
							display: "flex",
							flexDirection: "column",
							gap: 24,
						}}
					>
						<blockquote
							style={{
								fontFamily: fonts.display,
								fontSize: 24,
								lineHeight: 1.3,
								fontWeight: fonts.displayWeight,
								fontStyle: fonts.displayItalic ? "italic" : "normal",
							}}
						>
							"{t.quote}"
						</blockquote>
						<figcaption
							style={{
								borderTop: `1px solid ${palette.rim}`,
								paddingTop: 14,
								marginTop: "auto",
							}}
						>
							<div style={{ fontSize: 14, fontWeight: 500 }}>{t.who}</div>
							<div
								className="mono"
								style={{ opacity: 0.6, fontSize: 10, marginTop: 4 }}
							>
								{t.role}
							</div>
						</figcaption>
					</figure>
				))}
			</div>
		</section>
	);
}

// ─── FAQ ──────────────────────────────────────────────────────────────
function FaqItem({ q, a, palette, fonts, idx }) {
	const [open, setOpen] = useS(idx === 0);
	return (
		<div style={{ borderBottom: `1px solid ${palette.rim}` }}>
			<button
				onClick={() => setOpen((o) => !o)}
				aria-expanded={open}
				style={{
					width: "100%",
					padding: "clamp(20px, 5vw, 28px) 0",
					display: "grid",
					gridTemplateColumns: "40px 1fr 40px",
					gap: "clamp(12px, 3vw, 24px)",
					alignItems: "center",
					textAlign: "left",
					color: "inherit",
					minHeight: 64,
				}}
			>
				<span className="mono" style={{ color: palette.accent, opacity: 0.85 }}>
					0{idx + 1}
				</span>
				<span
					style={{
						fontFamily: fonts.display,
						fontSize: "clamp(20px, 4vw, 24px)",
						fontWeight: fonts.displayWeight,
						lineHeight: 1.2,
					}}
				>
					{q}
				</span>
				<span
					style={{
						fontFamily: '"JetBrains Mono", monospace',
						fontSize: 18,
						opacity: 0.6,
						justifySelf: "end",
						transform: open ? "rotate(45deg)" : "rotate(0deg)",
						transition: "transform .3s",
					}}
				>
					+
				</span>
			</button>
			<div
				style={{
					display: "grid",
					gridTemplateRows: open ? "1fr" : "0fr",
					transition: "grid-template-rows .35s ease",
					overflow: "hidden",
				}}
			>
				<div style={{ minHeight: 0 }}>
					<div
						style={{
							padding: "0 0 clamp(20px, 5vw, 28px) clamp(40px, 10vw, 64px)",
							maxWidth: 720,
							fontSize: 15,
							lineHeight: 1.65,
							color: palette.inkSoft,
						}}
					>
						{a}
					</div>
				</div>
			</div>
		</div>
	);
}

function Faq({ palette, fonts }) {
	return (
		<section
			id="faq"
			data-screen-label="08 FAQ"
			style={{
				padding: "var(--section-y) var(--gutter)",
				color: palette.ink,
				position: "relative",
			}}
		>
			{/* flex-wrap preserves the heading-vs-list ratio on wide and stacks on narrow */}
			<div
				style={{
					display: "flex",
					flexWrap: "wrap",
					gap: "clamp(28px, 5vw, 64px)",
				}}
			>
				<div style={{ flex: "1 1 240px" }}>
					<h2
						style={{
							fontFamily: fonts.display,
							fontSize: "clamp(40px,5vw,68px)",
							fontWeight: fonts.displayWeight,
							lineHeight: 1,
							letterSpacing: "-.01em",
						}}
					>
						Before you
						<br />
						<em
							style={{
								fontStyle: fonts.displayItalic ? "italic" : "normal",
								color: palette.accent,
							}}
						>
							arrive
						</em>
						.
					</h2>
				</div>
				<div style={{ flex: "3 1 360px" }}>
					{FAQ.map((f, i) => (
						<FaqItem
							key={i}
							idx={i}
							q={f.q}
							a={f.a}
							palette={palette}
							fonts={fonts}
						/>
					))}
				</div>
			</div>
		</section>
	);
}

// ─── visit / contact ──────────────────────────────────────────────────
function Visit({ palette, fonts, motion: _motion }) {
	const mobile = useMediaQuery("(max-width: 720px)");
	return (
		<section
			id="visit"
			data-screen-label="09 Visit"
			style={{
				padding: "var(--section-y) var(--gutter) var(--section-y-tight)",
				color: palette.ink,
				position: "relative",
			}}
		>
			<h2
				style={{
					fontFamily: fonts.display,
					fontSize: "clamp(44px,9vw,140px)",
					fontWeight: fonts.displayWeight,
					lineHeight: 0.92,
					letterSpacing: "-.02em",
					marginBottom: "clamp(48px, 8vw, 80px)",
				}}
			>
				Visit the
				<br />
				<em
					style={{
						fontStyle: fonts.displayItalic ? "italic" : "normal",
						color: palette.accent,
					}}
				>
					studio
				</em>
				.
			</h2>

			{mobile ? (
				<div style={{ display: "flex", flexDirection: "column", gap: 32 }}>
					{/* Address */}
					<div>
						<div className="mono" style={{ opacity: 0.6, marginBottom: 14 }}>
							· address ·
						</div>
						<p
							style={{
								fontFamily: fonts.display,
								fontSize: 26,
								fontWeight: fonts.displayWeight,
								lineHeight: 1.2,
								marginBottom: 20,
							}}
						>
							{STUDIO.addressLine1}
							<br />
							{STUDIO.addressLine2}
							<br />
							<span style={{ opacity: 0.6 }}>{STUDIO.addressLine3}</span>
						</p>
						<a
							href={STUDIO.mapsUrl}
							target="_blank"
							rel="noopener"
							style={{
								display: "flex",
								alignItems: "center",
								justifyContent: "center",
								padding: "16px 24px",
								border: `1px solid ${palette.accent}`,
								color: palette.accent,
								borderRadius: 999,
								fontFamily: '"JetBrains Mono", monospace',
								fontSize: 12,
								letterSpacing: ".06em",
								textTransform: "uppercase",
								minHeight: 48,
							}}
						>
							Open in maps →
						</a>
					</div>

					{/* Contact */}
					<div>
						<div className="mono" style={{ opacity: 0.6, marginBottom: 14 }}>
							· reach out ·
						</div>
						<ul style={{ listStyle: "none" }}>
							<li style={{ borderTop: `1px solid ${palette.rim}` }}>
								<a
									href={`mailto:${STUDIO.email}`}
									style={{
										display: "flex",
										alignItems: "center",
										padding: "16px 0",
										minHeight: 56,
										fontFamily: fonts.display,
										fontSize: 18,
										fontWeight: fonts.displayWeight,
										wordBreak: "break-word",
									}}
								>
									{STUDIO.email}
								</a>
							</li>
							<li style={{ borderTop: `1px solid ${palette.rim}` }}>
								<a
									href={STUDIO.phoneHref}
									style={{
										display: "flex",
										alignItems: "center",
										padding: "18px 0",
										minHeight: 60,
										fontFamily: fonts.display,
										fontSize: 26,
										fontWeight: fonts.displayWeight,
									}}
								>
									{STUDIO.phone}
								</a>
							</li>
							<li
								style={{
									borderTop: `1px solid ${palette.rim}`,
									borderBottom: `1px solid ${palette.rim}`,
								}}
							>
								<a
									href={STUDIO.instagramUrl}
									target="_blank"
									rel="noopener"
									className="mono"
									style={{
										display: "flex",
										alignItems: "center",
										padding: "16px 0",
										minHeight: 48,
										opacity: 0.7,
										fontSize: 12,
									}}
								>
									{STUDIO.instagramHandle}
								</a>
							</li>
						</ul>
					</div>

					{/* Hours */}
					<div>
						<div className="mono" style={{ opacity: 0.6, marginBottom: 14 }}>
							· hours ·
						</div>
						<ul style={{ listStyle: "none" }}>
							{HOURS.map((h) => (
								<li
									key={h.day}
									style={{
										display: "flex",
										justifyContent: "space-between",
										padding: "12px 0",
										borderBottom: `1px solid ${palette.rim}`,
										fontFamily: '"JetBrains Mono", monospace',
										fontSize: 13,
									}}
								>
									<span style={{ opacity: 0.85 }}>{h.day}</span>
									<span
										style={{
											opacity: h.time === "rest" ? 0.4 : 1,
											color:
												h.time === "rest" ? palette.inkSoft : palette.accent,
										}}
									>
										{h.time}
									</span>
								</li>
							))}
						</ul>
					</div>
				</div>
			) : (
				<div
					style={{
						display: "grid",
						gridTemplateColumns:
							"repeat(auto-fit, minmax(min(100%, 260px), 1fr))",
						gap: 48,
					}}
				>
					<div>
						<div className="mono" style={{ opacity: 0.6, marginBottom: 14 }}>
							· address ·
						</div>
						<p
							style={{
								fontFamily: fonts.display,
								fontSize: 28,
								fontWeight: fonts.displayWeight,
								lineHeight: 1.2,
								marginBottom: 24,
							}}
						>
							{STUDIO.addressLine1}
							<br />
							{STUDIO.addressLine2}
							<br />
							<span style={{ opacity: 0.6 }}>{STUDIO.addressLine3}</span>
						</p>
						<a
							href={STUDIO.mapsUrl}
							target="_blank"
							rel="noopener"
							className="mono"
							style={{
								color: palette.accent,
								fontSize: 11,
								borderBottom: `1px solid ${palette.accent}`,
								paddingBottom: 2,
							}}
						>
							Open in maps →
						</a>
					</div>
					<div>
						<div className="mono" style={{ opacity: 0.6, marginBottom: 14 }}>
							· hours ·
						</div>
						<ul style={{ listStyle: "none" }}>
							{HOURS.map((h) => (
								<li
									key={h.day}
									style={{
										display: "flex",
										justifyContent: "space-between",
										padding: "10px 0",
										borderBottom: `1px solid ${palette.rim}`,
										fontFamily: '"JetBrains Mono", monospace',
										fontSize: 12,
									}}
								>
									<span style={{ opacity: 0.85 }}>{h.day}</span>
									<span
										style={{
											opacity: h.time === "rest" ? 0.4 : 1,
											color:
												h.time === "rest" ? palette.inkSoft : palette.accent,
										}}
									>
										{h.time}
									</span>
								</li>
							))}
						</ul>
					</div>
					<div>
						<div className="mono" style={{ opacity: 0.6, marginBottom: 14 }}>
							· reach out ·
						</div>
						<ul
							style={{
								listStyle: "none",
								display: "flex",
								flexDirection: "column",
								gap: 14,
							}}
						>
							<li>
								<a
									href={`mailto:${STUDIO.email}`}
									style={{
										fontFamily: fonts.display,
										fontSize: 22,
										fontWeight: fonts.displayWeight,
									}}
								>
									{STUDIO.email}
								</a>
							</li>
							<li>
								<a
									href={STUDIO.phoneHref}
									style={{
										fontFamily: fonts.display,
										fontSize: 22,
										fontWeight: fonts.displayWeight,
									}}
								>
									{STUDIO.phone}
								</a>
							</li>
							<li>
								<a
									href={STUDIO.instagramUrl}
									target="_blank"
									rel="noopener"
									className="mono"
									style={{
										opacity: 0.7,
										fontSize: 11,
										marginTop: 8,
										display: "inline-block",
									}}
								>
									{STUDIO.instagramHandle}
								</a>
							</li>
						</ul>
					</div>
				</div>
			)}

			{/* footer row */}
			<div
				style={{
					marginTop: "var(--rhythm)",
					paddingTop: "var(--rhythm)",
					borderTop: `1px solid ${palette.rim}`,
					display: "flex",
					flexDirection: mobile ? "column" : "row",
					justifyContent: "space-between",
					alignItems: mobile ? "flex-start" : "baseline",
					gap: mobile ? 10 : 0,
				}}
			>
				<div className="mono" style={{ opacity: 0.55 }}>
					© Healing Hub · all rights, all rest
				</div>
				<div className="mono" style={{ opacity: 0.55 }}>
					well full · 100% restored
				</div>
			</div>
		</section>
	);
}

// ─── sand-toned section wrap (alternates bg under mono palette) ───────
function SandWrap({ palette, alt, children }) {
	if (alt === palette) return <>{children}</>;
	return (
		<div
			style={{
				position: "relative",
				width: "100vw",
				marginLeft: "calc(50% - 50vw)",
				marginRight: "calc(50% - 50vw)",
				background: alt.bg,
				color: alt.ink,
				isolation: "isolate",
			}}
		>
			<svg
				aria-hidden
				viewBox="0 0 1440 80"
				preserveAspectRatio="none"
				style={{
					position: "absolute",
					top: -1,
					left: 0,
					width: "100%",
					height: 80,
					display: "block",
					zIndex: 1,
				}}
			>
				<path
					d="M0,0 L1440,0 L1440,30 C1260,68 1080,68 900,42 C720,16 540,16 360,38 C200,58 80,58 0,40 Z"
					fill={palette.bg}
				/>
			</svg>
			<svg
				aria-hidden
				viewBox="0 0 1440 80"
				preserveAspectRatio="none"
				style={{
					position: "absolute",
					bottom: -1,
					left: 0,
					width: "100%",
					height: 80,
					display: "block",
					zIndex: 1,
					transform: "scaleY(-1)",
				}}
			>
				<path
					d="M0,0 L1440,0 L1440,28 C1260,62 1080,62 900,40 C720,18 540,18 360,36 C200,54 80,54 0,38 Z"
					fill={palette.bg}
				/>
			</svg>
			<div
				aria-hidden
				style={{
					position: "absolute",
					inset: 0,
					pointerEvents: "none",
					zIndex: 0,
					opacity: 0.5,
					backgroundImage: `radial-gradient(${alt.accent}26 1px, transparent 1.2px), radial-gradient(${alt.accent}1A 1px, transparent 1.2px)`,
					backgroundSize: "22px 22px, 14px 14px",
					backgroundPosition: "0 0, 7px 11px",
					mixBlendMode: "multiply",
				}}
			/>
			<div
				style={{
					position: "relative",
					zIndex: 2,
					paddingTop: 40,
					paddingBottom: 40,
					maxWidth: 1600,
					margin: "0 auto",
				}}
			>
				{children}
			</div>
		</div>
	);
}

Object.assign(window, {
	Header,
	Hero,
	Approach,
	Sessions,
	Enhancements,
	Membership,
	Practitioner,
	Testimonials,
	Faq,
	Visit,
	SandWrap,
	Hamburger,
	MobileMenu,
	MobileBookBar,
});
