/* =============================================================================
   Where's Pinky — component styles.
   Source: Claude Design project 1f1d183e… (design-system/components/*.jsx, site.css, Home.dc.html).
   Every colour, font size, spacing value, shadow and z-index goes through a token defined in
   theme.json (guard: npm run guard:tokens). Breakpoints: 480 / 640 / 900 / 1024 / 1060 / 1240 only.
   ============================================================================= */

/* ---- Short aliases for theme.json tokens --------------------------------- */
:root {
	--c-navy: var(--wp--preset--color--navy);
	--c-pink: var(--wp--preset--color--pink);
	--c-pink-text: var(--wp--preset--color--pink-text);
	--c-teal: var(--wp--preset--color--teal);
	--c-sand: var(--wp--preset--color--sand);
	--c-cream: var(--wp--preset--color--cream);
	--c-white: var(--wp--preset--color--white);
	--c-ink: var(--wp--preset--color--ink);
	--c-muted: var(--wp--preset--color--muted);
	--c-body: var(--wp--preset--color--body);
	--c-star: var(--wp--preset--color--star);
	--a: var(--wp--custom--alpha--navy-08);

	--f-display: var(--wp--preset--font-family--display);
	--f-label: var(--wp--preset--font-family--label);
	--f-body: var(--wp--preset--font-family--body);

	--fs-xs: var(--wp--preset--font-size--xs);
	--fs-sm: var(--wp--preset--font-size--sm);
	--fs-button: var(--wp--preset--font-size--button);
	--fs-md: var(--wp--preset--font-size--md);
	--fs-body: var(--wp--preset--font-size--body);
	--fs-lede: var(--wp--preset--font-size--lede);
	--fs-quote: var(--wp--preset--font-size--quote);
	--fs-h3: var(--wp--preset--font-size--h-3);
	--fs-lg: var(--wp--preset--font-size--lg);
	--fs-xl: var(--wp--preset--font-size--xl);
	--fs-2xl: var(--wp--preset--font-size--2-xl);
	--fs-3xl: var(--wp--preset--font-size--3-xl);
	--fs-h2: var(--wp--preset--font-size--h-2);
	--fs-h2-compact: var(--wp--preset--font-size--h-2-compact); /* the design's in-section H2s: clamp(32px, 3.6vw, 44–48px) */

	--s-1: var(--wp--preset--spacing--1);
	--s-2: var(--wp--preset--spacing--2);
	--s-3: var(--wp--preset--spacing--3);
	--s-4: var(--wp--preset--spacing--4);
	--s-5: var(--wp--preset--spacing--5);
	--s-6: var(--wp--preset--spacing--6);
	--s-8: var(--wp--preset--spacing--8);
	--s-10: var(--wp--preset--spacing--10);
	--s-12: var(--wp--preset--spacing--12);
	--s-16: var(--wp--preset--spacing--16);
	--s-20: var(--wp--preset--spacing--20);
	--s-24: var(--wp--preset--spacing--24);

	--sh-sm: var(--wp--preset--shadow--sm);
	--sh-md: var(--wp--preset--shadow--md);
	--sh-lg: var(--wp--preset--shadow--lg);
	--sh-xl: var(--wp--preset--shadow--xl);
	--sh-hero: var(--wp--preset--shadow--hero);
	--sh-hover-lg: var(--wp--preset--shadow--hover-lg);
	--sh-soft: var(--wp--preset--shadow--soft);

	--lift: var(--wp--custom--lift--sm);
	--lift-lg: var(--wp--custom--lift--lg);
	/* Motion (theme.json settings.custom.motion). Every transition/animation uses these; guard: wsp/motion-token. */
	--m-fast: var(--wp--custom--motion--duration--fast);
	--m-base: var(--wp--custom--motion--duration--base);
	--m-slow: var(--wp--custom--motion--duration--slow);
	--e-std: var(--wp--custom--motion--ease--standard);
	--e-enter: var(--wp--custom--motion--ease--enter);
	--e-exit: var(--wp--custom--motion--ease--exit);
	--e-linear: var(--wp--custom--motion--ease--linear);

	--wsp-focus: var(--wp--custom--focus--light);
}

/* ---- Base ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { -webkit-font-smoothing: antialiased; overflow-x: hidden; max-width: 100%; }
h1, h2, h3 { overflow-wrap: break-word; }
.wsp-main > * { margin-block: 0; }
/* Sticky footer: on a page shorter than the window the footer sits at the window's bottom, and the space
   above it takes the colour of the last section: main fills that space and its last section grows into it,
   so the page reads as one block into the footer (prompt 14 #1; check: ops/report/footer-gap.mjs). Every
   template, since each one's <main> is .wsp-main. Long pages are unchanged. Main's children keep block
   sizing (full width, capped by their own max-width, centred by their own auto margins); the fixed phone
   book bars ([data-wsp-sticky]) are left out of both rules. */
.wp-site-blocks { display: flex; flex-direction: column; min-height: calc(100dvh - var(--wp-admin--admin-bar--height, 0px)); }
.wsp-main { flex: 1 0 auto; display: flex; flex-direction: column; }
.wsp-main > :not([data-wsp-sticky]) { width: 100%; }
.wsp-main > :nth-last-child(1 of :not([data-wsp-sticky])) { flex-grow: 1; }
.wsp-footer { margin-top: auto; }
a { transition: color var(--m-fast) var(--e-std); }

/* Reduced motion: nothing moves. Transforms, sizes and positions change instantly; only colour and
   opacity still ease (opacity-only change). Marquees and autoplay never start (site.js and the page
   scripts check the same media query); a keyframe entrance must switch itself off here too. */
@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after { transition-property: opacity, color, background-color, border-color, visibility !important; }
}
img { max-width: 100%; height: auto; }
picture { display: contents; }
[id] { scroll-margin-top: var(--s-24); }

.screen-reader-text {
	position: absolute; width: 1px; height: 1px; overflow: hidden;
	clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.wsp-skip-link:focus {
	position: fixed; top: var(--s-2); left: var(--s-2); z-index: var(--wp--custom--z--dropdown);
	width: auto; height: auto; clip: auto; clip-path: none;
	padding: var(--s-3) var(--s-5); background: var(--c-navy); color: var(--c-sand);
	font-family: var(--f-label); font-size: var(--fs-md); letter-spacing: var(--wp--custom--ls--button);
}

/* Focus: one treatment sitewide (3px ring, 3px offset); the ring colour follows the band. */
[data-band="pink"], [data-band="dark"], .wsp-util { --wsp-focus: var(--wp--custom--focus--on-dark); }
[data-band="bright"] { --wsp-focus: var(--wp--custom--focus--on-bright); }
.wsp-header, .wsp-dropdown { --wsp-focus: var(--wp--custom--focus--light); }
a:focus-visible, button:focus-visible, [tabindex]:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wsp-focus);
	outline-offset: var(--wp--custom--focus--offset);
}

/* ---- Layout -------------------------------------------------------------- */
.wsp-sec { padding: var(--wp--custom--section--pad-y) var(--wp--custom--section--pad-x); position: relative; }
.wsp-sec.is-white { background-color: var(--c-white); }
.wsp-sec.is-sand { background-color: var(--c-sand); }
.wsp-sec.has-dashed-rule { border-bottom: 3px dashed var(--c-navy); }
/* No partner strip between them (it renders only with real logos, G1): the white hero meets the white section below. */
.wsp-hero:has(+ .wsp-locations) { border-bottom: 3px dashed var(--c-navy); }
.wsp-sec.is-pink-band {
	background: var(--c-pink) repeating-linear-gradient(45deg, transparent, transparent 40px, var(--wp--custom--alpha--sand-07) 40px, var(--wp--custom--alpha--sand-07) 42px);
}
.wsp-wide { max-width: var(--wp--custom--maxw--wide); margin: 0 auto; }
/* Breakpoints (Ben, 20 Oct, prompt 18): one shared set, theme.json settings.custom.breakpoint. Phone-sm below 481,
   phone below 641, tablet 641–899, desktop from 900 (every side-by-side layout and the full nav), wide from 1240
   (the 4- and 6-across grids and the roomy nav). Media queries name a tier's start (min-width: 900px) or the width
   just before it (max-width: 899px); grids name their columns per tier, never auto-fit (npm run guard:tokens). */
@media (min-width: 641px) and (max-width: 899px) {
	.wsp-sec:not(.wsp-hero) { padding: var(--wp--custom--section--pad-y-tablet) var(--wp--custom--section--pad-x-tablet); }
}
@media (max-width: 640px) {
	.wsp-sec { padding: var(--wp--custom--section--pad-y-mobile) var(--wp--custom--section--pad-x-mobile); }
}

/* ---- Header (SiteHeader) ------------------------------------------------- */
/* The template-part wrapper must not become the sticky header's containing block. */
.wsp-header-part, .wsp-footer-part { display: contents; }

.wsp-util {
	background: var(--c-navy); color: var(--c-sand);
	font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--button);
	padding: var(--s-2) var(--s-6);
	display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--s-1) var(--s-10);
}
.wsp-util a { color: var(--c-sand); transition: color var(--m-fast) var(--e-std); }
.wsp-util a:hover { color: var(--c-pink); }
.wsp-util-sep { opacity: 0.35; }

.wsp-header {
	position: sticky; top: 0; z-index: var(--wp--custom--z--header);
	background: var(--c-sand); border-bottom: 3px solid var(--c-navy);
	transition: box-shadow var(--m-base) var(--e-std);
}
.wsp-header.is-scrolled { box-shadow: var(--wp--custom--shadow--header); }
.wsp-nav-inner {
	max-width: var(--wp--custom--maxw--header); margin: 0 auto; padding: var(--s-4) var(--s-6);
	display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--s-8);
}
.wsp-brand { display: flex; align-items: center; flex-shrink: 0; }
.wsp-brand-logo { height: 64px; width: auto; display: block; }
.wsp-brand-text { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-h3); color: var(--c-navy); }
.wsp-nav-links {
	list-style: none; padding: 0; margin: 0;
	display: flex; align-items: center; justify-content: center; gap: var(--s-1);
	font-family: var(--f-label); font-size: var(--fs-lede); letter-spacing: var(--wp--custom--ls--button);
}
.wsp-nav-links li { position: relative; }
.wsp-nav-links > li > a { color: var(--c-navy); padding: var(--s-2) var(--s-3); display: flex; align-items: center; gap: var(--s-1); transition: color var(--m-fast) var(--e-std); }
.wsp-nav-links a:hover, .wsp-nav-links a[aria-current="page"] { color: var(--c-pink); }
.wsp-nav-links > li > a[aria-current="page"]::after {
	content: ""; position: absolute; left: var(--s-3); right: var(--s-3); bottom: calc(-1 * var(--s-1)); height: 3px; background: var(--c-pink);
}
.wsp-drop-arrow { font-size: var(--fs-xs); display: inline-block; transition: transform var(--m-base) var(--e-std); }
.wsp-has-dropdown:hover .wsp-drop-arrow, .wsp-has-dropdown:focus-within .wsp-drop-arrow, .wsp-has-dropdown.is-open .wsp-drop-arrow { transform: rotate(180deg); }
.wsp-dropdown {
	position: absolute; top: calc(100% + var(--s-2)); left: 0; z-index: var(--wp--custom--z--dropdown);
	background: var(--c-white); border: 2px solid var(--c-navy); box-shadow: var(--sh-md);
	min-width: 230px; display: flex; flex-direction: column;
	/* Exit: fades and lifts away quickly. visibility stays visible for the whole transition, then flips,
	   so the menu leaves the tab order only once it has faded. */
	opacity: 0; visibility: hidden; transform: translateY(calc(-1 * var(--s-2)));
	transition: opacity var(--m-fast) var(--e-exit), transform var(--m-fast) var(--e-exit), visibility var(--m-fast) var(--e-exit);
}
.wsp-has-dropdown:hover .wsp-dropdown, .wsp-has-dropdown:focus-within .wsp-dropdown, .wsp-has-dropdown.is-open .wsp-dropdown {
	opacity: 1; visibility: visible; transform: none;
	transition: opacity var(--m-base) var(--e-enter), transform var(--m-base) var(--e-enter), visibility var(--m-base) var(--e-enter);
}
.wsp-dropdown a {
	font-family: var(--f-label); font-size: var(--fs-md); letter-spacing: var(--wp--custom--ls--button); color: var(--c-navy);
	padding: var(--s-3) var(--s-5); border-bottom: 1px solid var(--wp--custom--alpha--navy-08);
	transition: background-color var(--m-fast) var(--e-std), color var(--m-fast) var(--e-std);
}
.wsp-dropdown a:last-child { border-bottom: none; }
.wsp-dropdown a:hover { background: var(--c-navy); color: var(--c-sand); }
.wsp-dropdown a[data-external] { border-top: 2px dashed var(--wp--custom--alpha--navy-25); }
.wsp-nav-cta {
	flex-shrink: 0; background: var(--c-pink); color: var(--c-white);
	font-family: var(--f-label); font-size: var(--fs-body); letter-spacing: var(--wp--custom--ls--button); text-transform: uppercase;
	padding: var(--s-3) var(--s-6); border: 3px solid var(--c-navy); box-shadow: var(--sh-md);
	white-space: nowrap; transition: transform var(--m-fast) var(--e-std), box-shadow var(--m-fast) var(--e-std);
}
.wsp-nav-cta:hover { transform: var(--lift); box-shadow: var(--wp--custom--shadow--navy-6); color: var(--c-white); }
.wsp-menu-btn {
	display: none; background: var(--c-navy); color: var(--c-sand); border: 3px solid var(--c-navy);
	width: 44px; height: 44px; font-size: var(--fs-lede); cursor: pointer;
	align-items: center; justify-content: center; flex-shrink: 0; margin-left: auto;
}
/* Drawer: height animates 0fr → 1fr (grid rows), with a fade; closed, it is visibility:hidden (out of the tab order). */
.wsp-mobile-menu {
	display: none; grid-template-rows: 0fr; background: var(--c-sand); opacity: 0; visibility: hidden;
	transition: grid-template-rows var(--m-base) var(--e-exit), opacity var(--m-fast) var(--e-exit), visibility var(--m-base) var(--e-exit);
}
.wsp-mobile-menu.is-open {
	grid-template-rows: 1fr; opacity: 1; visibility: visible;
	transition: grid-template-rows var(--m-slow) var(--e-enter), opacity var(--m-base) var(--e-enter), visibility var(--m-base) var(--e-enter);
}
.wsp-mobile-menu-inner { min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
/* The top rule lives inside the clipped box, so a closed drawer is 0px tall, not a stray line. */
.wsp-mobile-menu-inner::before { content: ""; flex-shrink: 0; border-top: 2px solid var(--wp--custom--alpha--navy-12); margin-bottom: var(--s-3); }
.wsp-mobile-menu a {
	display: block; font-family: var(--f-label); font-size: var(--fs-md); letter-spacing: var(--wp--custom--ls--button); color: var(--c-navy);
	padding: var(--s-3) var(--s-6); border-bottom: 1px solid var(--wp--custom--alpha--navy-08); transition: color var(--m-fast) var(--e-std);
}
.wsp-mobile-menu a:hover, .wsp-mobile-menu a[aria-current="page"] { color: var(--c-pink); }
.wsp-mobile-sub a { padding-left: var(--s-10); font-size: var(--fs-sm); color: var(--c-muted); }
.wsp-mobile-menu .wsp-mobile-cta {
	margin: var(--s-4) var(--s-6) var(--s-5); background: var(--c-pink); color: var(--c-white); text-align: center;
	padding: var(--s-4) var(--s-6); border: 3px solid var(--c-navy); box-shadow: var(--sh-sm);
}
/* Desktop below wide: the nav's compact sizes. The full nav fits from 900 (A1: 200 px spare at 900). */
@media (max-width: 1239px) {
	.wsp-nav-inner { gap: var(--s-5); }
	.wsp-nav-links { font-size: var(--fs-md); gap: 0; }
	.wsp-nav-links > li > a { padding: var(--s-2); }
	.wsp-brand-logo { height: 56px; }
	.wsp-nav-cta { font-size: var(--fs-button); padding: var(--s-3) var(--s-5); }
}
@media (max-width: 899px) {
	.wsp-nav, .wsp-nav-cta { display: none; }
	.wsp-menu-btn { display: flex; }
	.wsp-mobile-menu { display: grid; }
}
@media (max-width: 899px) {
	.wsp-brand-logo { height: 54px; }
	.wsp-util { gap: var(--s-1) var(--s-4); letter-spacing: var(--wp--custom--ls--tight); }
}
@media (max-width: 480px) { .wsp-util-sep { display: none; } }

/* ---- Footer (SiteFooter) ------------------------------------------------- */
.wsp-footer { background: var(--c-navy); color: var(--c-sand); padding: var(--s-16) var(--s-6) var(--s-6); }
.wsp-footer-inner {
	max-width: var(--wp--custom--maxw--wide); margin: 0 auto;
	display: grid; grid-template-columns: 1.2fr 2fr; gap: var(--wp--custom--gap--hero); align-items: start;
}
.wsp-footer-logo { height: 88px; width: auto; display: block; margin-bottom: var(--s-4); }
.wsp-footer-tagline { color: var(--wp--custom--alpha--sand-80); font-size: var(--fs-button); line-height: 1.5; margin: 0 0 var(--s-5); max-width: 300px; }
.wsp-footer-social { display: flex; gap: var(--s-3); margin-top: var(--s-5); }
.wsp-footer-social a {
	width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
	color: var(--wp--custom--alpha--sand-85); border: 1px solid var(--wp--custom--alpha--sand-35);
	transition: color var(--m-fast) var(--e-std), border-color var(--m-fast) var(--e-std);
}
.wsp-footer-social a:hover { color: var(--c-sand); border-color: var(--wp--custom--alpha--sand-50); }
.wsp-footer-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-8); }
.wsp-footer-col { display: flex; flex-direction: column; gap: var(--s-2); }
.wsp-footer-col-h {
	font-family: var(--f-label); font-weight: 400; font-size: var(--fs-button); line-height: 1.2; letter-spacing: var(--wp--custom--ls--label);
	color: var(--c-sand); text-transform: uppercase; align-self: flex-start;
	margin: 0 0 var(--s-2); padding-bottom: var(--s-1); border-bottom: 2px solid var(--c-pink);
}
.wsp-footer-col a { font-family: var(--f-display); font-size: var(--fs-button); line-height: 1.4; color: var(--wp--custom--alpha--sand-85); transition: color var(--m-fast) var(--e-std); }
.wsp-footer-col a:hover, .wsp-footer-bottom a:hover { color: var(--c-white); }
.wsp-footer-bottom {
	max-width: var(--wp--custom--maxw--wide); margin: var(--s-10) auto 0; padding-top: var(--s-5);
	border-top: 1px solid var(--wp--custom--alpha--sand-12);
	display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--s-3);
	font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--button); text-transform: uppercase;
	color: var(--wp--custom--alpha--sand-75);
}
.wsp-footer-bottom a { color: var(--wp--custom--alpha--sand-75); transition: color var(--m-fast) var(--e-std); }
.wsp-footer-bottom-links { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); }
/* Tap to call: phones only (below). The header's phone number (render.php reads the same top-bar tel: link). */
.wsp-footer-social .wsp-footer-call { display: none; }
@media (max-width: 899px) { .wsp-footer-inner { grid-template-columns: 1fr; gap: var(--s-10); } }
/* Phones (Ben, 20 Oct): the brand block (logo, tagline, social row) full width on top; the links in two columns,
   Locations on the left and Company with Book under it on the right; the legal links 2 × 2 with the copyright under
   them. The call button sits in the social row, in the icon buttons' style (40 px, hairline border, sand ink). */
@media (max-width: 640px) {
	.wsp-footer-social { flex-wrap: wrap; }
	.wsp-footer-social .wsp-footer-call {
		display: inline-flex; width: auto; padding: 0 var(--s-4); white-space: nowrap;
		font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--button); text-transform: uppercase;
	}
	.wsp-footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-6); align-items: start; }
	.wsp-footer-col:first-child { grid-row: span 2; }
	.wsp-footer-logo { height: 72px; }
	.wsp-footer-bottom { flex-direction: column; align-items: flex-start; gap: var(--s-4); }
	.wsp-footer-bottom-links { order: -1; width: 100%; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3) var(--s-6); }
	/* The consent tool adds a fifth link while it's loaded (inc/cmp.php): an odd last link takes the whole row. */
	.wsp-footer-bottom-links > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}

/* ---- Shared components --------------------------------------------------- */
/* SectionHead + Eyebrow */
.wsp-section-head { max-width: var(--wp--custom--maxw--content); margin: 0 auto var(--s-16); text-align: center; }
.wsp-section-head.is-left { margin: 0 0 var(--s-10); text-align: left; }
.wsp-eyebrow-wrap { margin-bottom: var(--s-4); }
.wsp-eyebrow {
	display: inline-block; font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--label);
	text-transform: uppercase; color: var(--c-pink-text); border-bottom: 2px solid var(--c-pink); padding-bottom: var(--s-1);
}
.wsp-section-title {
	font-family: var(--f-display); font-weight: 700; font-size: var(--fs-h2); line-height: var(--wp--custom--lh--heading);
	letter-spacing: var(--wp--custom--ls--title); color: var(--c-navy); margin: 0;
}
.wsp-section-sub { font-size: var(--fs-body); line-height: var(--wp--custom--lh--body); color: var(--c-muted); max-width: var(--wp--custom--maxw--prose); margin: var(--s-5) auto 0; }
.wsp-section-head.is-left .wsp-section-sub { margin: var(--s-5) 0 0; }
/* On pink bands: eyebrow, title and subtitle in white (cream/sand on pink fails AA). */
.wsp-section-head.is-dark .wsp-eyebrow { color: var(--c-white); border-bottom-color: var(--c-white); }
.wsp-section-head.is-dark .wsp-section-title, .wsp-section-head.is-dark .wsp-section-sub { color: var(--c-white); }

/* Button */
.wsp-btn {
	display: inline-flex; align-items: center; justify-content: center; gap: var(--s-3);
	font-family: var(--f-label); letter-spacing: var(--wp--custom--ls--button); text-transform: uppercase; white-space: nowrap;
	border: 3px solid var(--c-navy); box-shadow: var(--sh-lg);
	transition: transform var(--m-fast) var(--e-std), box-shadow var(--m-fast) var(--e-std), background-color var(--m-fast) var(--e-std);
}
.wsp-btn:hover { transform: var(--lift); box-shadow: var(--wp--custom--shadow--navy-7); }
.wsp-btn.is-md { padding: var(--s-4) var(--s-8); font-size: var(--fs-button); }
.wsp-btn.is-lg { padding: var(--s-5) var(--s-10); font-size: var(--fs-md); }
.wsp-btn.is-primary, .wsp-btn.is-primary:hover { background: var(--c-pink); color: var(--c-white); }
.wsp-btn.is-secondary, .wsp-btn.is-secondary:hover { background: var(--c-cream); color: var(--c-navy); }
.wsp-btn.is-on-dark, .wsp-btn.is-on-dark:hover { background: var(--c-sand); color: var(--c-pink-text); border-color: var(--c-sand); }
.wsp-cta-row { display: flex; justify-content: center; margin-top: var(--s-12); }
.wsp-cta-row.is-far { margin-top: var(--s-16); }
.wsp-cta-row.is-near { margin-top: var(--s-5); }

/* PostcardFrame */
.wsp-postcard { position: relative; background: var(--c-sand); border: 3px solid var(--c-navy); box-shadow: var(--sh-hero); }
.wsp-postcard::before, .wsp-frame-dash, .wsp-testimonial::before {
	content: ""; position: absolute; inset: var(--s-2); pointer-events: none; border: 1px dashed var(--wp--custom--alpha--navy-35);
}
.wsp-frame-dash.is-light { border-color: var(--wp--custom--alpha--sand-70); }
.wsp-postcard > * { position: relative; }

/* Rotated stamp card (hero badge, groups badge, bento stamp) */
.wsp-stamp-card {
	position: absolute; top: var(--s-6); right: var(--s-6); z-index: var(--wp--custom--z--raised);
	background: var(--c-cream); border: 2px solid var(--c-navy); text-align: center;
	padding: var(--s-3) var(--s-5); transform: rotate(8deg); box-shadow: var(--sh-sm);
}
.wsp-stamp-num { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-lg); line-height: 1; color: var(--c-pink); }
.wsp-stamp-num.is-lg { font-size: var(--fs-xl); }
.wsp-stamp-label { font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--tight); color: var(--c-navy); margin-top: var(--s-1); }

/* Crossfading slides (hero, groups, Meet Pinky) */
.wsp-slide { position: absolute; inset: 0; opacity: 0; transition: opacity var(--m-slow) var(--e-std); }
.wsp-slide.is-active { opacity: 1; }
.wsp-slide img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Carousel controls */
.wsp-carousel-controls { display: flex; justify-content: space-between; align-items: center; }
.wsp-dots { display: flex; margin-left: calc(-1 * var(--s-2)); }
.wsp-dot { min-width: 24px; height: 32px; padding: 0 var(--s-2); background: transparent; border: 0; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.wsp-dot span { display: block; width: 12px; height: 12px; border: 2px solid var(--c-navy); background: transparent; transition: width var(--m-base) var(--e-std), background-color var(--m-base) var(--e-std); }
.wsp-dot.is-bar[aria-current="true"] span { width: 28px; background: var(--c-pink); }
.wsp-dot.is-round { width: 24px; padding: 0; }
.wsp-dot.is-round span { border-radius: var(--wp--custom--radius--round); }
.wsp-dot.is-round[aria-current="true"] span { background: var(--c-pink); }
.wsp-arrows { display: flex; gap: var(--s-3); }
.wsp-arrow {
	width: 44px; height: 44px; border: 2px solid var(--c-navy); color: var(--c-navy);
	font-family: var(--f-display); font-weight: 700; font-size: var(--fs-lede); box-shadow: var(--sh-sm);
	cursor: pointer; transition: transform var(--m-fast) var(--e-std), box-shadow var(--m-fast) var(--e-std), background-color var(--m-fast) var(--e-std), color var(--m-fast) var(--e-std);
}
.wsp-carousel-controls.is-sand .wsp-arrow { background: var(--c-sand); }
.wsp-carousel-controls.is-cream .wsp-arrow, .wsp-carousel-controls.is-on-pink .wsp-arrow { background: var(--c-cream); }
.wsp-carousel-controls.is-sand .wsp-arrow:hover, .wsp-carousel-controls.is-cream .wsp-arrow:hover {
	transform: var(--lift); box-shadow: var(--wp--custom--shadow--pink-lg); background: var(--c-pink); color: var(--c-cream);
}
.wsp-carousel-controls.is-on-pink .wsp-arrow:hover { transform: var(--lift); box-shadow: var(--sh-lg); }
.wsp-autoplay-toggle { font-family: var(--f-body); font-size: var(--fs-sm); }
.wsp-autoplay-toggle[hidden] { display: none; }
.wsp-carousel-controls.is-on-pink .wsp-dot span { border-color: var(--c-white); }
.wsp-carousel-controls.is-on-pink .wsp-dot[aria-current="true"] span { background: var(--c-white); }

/* ---- Home: hero ---------------------------------------------------------- */
.wsp-hero { background: var(--c-white); overflow: hidden; padding: var(--s-16) var(--s-8) var(--s-24); }
.wsp-hero-inner {
	max-width: var(--wp--custom--maxw--wide); margin: 0 auto;
	display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--wp--custom--gap--hero); align-items: stretch;
}
/* Side by side from desktop (900): copy and city picker left, photo right. */
@media (min-width: 900px) { .wsp-hero-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.wsp-postcard.is-hero { padding: var(--s-12) var(--s-10); }
.wsp-hero-greeting { font-family: var(--f-label); font-size: var(--fs-lede); letter-spacing: var(--wp--custom--ls--greeting); color: var(--c-pink-text); margin-bottom: var(--s-3); text-wrap: balance; }
.wsp-hero-title {
	font-family: var(--f-display); font-weight: 700; font-size: var(--wp--preset--font-size--display-hero); line-height: 1.02;
	letter-spacing: var(--wp--custom--ls--hero); color: var(--c-navy); margin: 0 0 var(--s-6); text-wrap: balance;
}
.wsp-hero-lede { font-size: var(--fs-body); line-height: var(--wp--custom--lh--body); color: var(--c-body); max-width: var(--wp--custom--maxw--prose); margin: 0 0 var(--s-8); text-wrap: pretty; }
.wsp-chooser { border: 2px solid var(--c-navy); background: var(--c-white); box-shadow: var(--sh-md); padding: var(--s-5); max-width: var(--wp--custom--maxw--prose); }
.wsp-chooser-label { font-family: var(--f-label); font-size: var(--fs-button); letter-spacing: var(--wp--custom--ls--button); color: var(--c-navy); margin-bottom: var(--s-4); }
.wsp-chips { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.wsp-chip {
	font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--tight);
	padding: var(--s-2) var(--s-4); border: 2px solid var(--c-navy); background: var(--c-cream); color: var(--c-navy);
	box-shadow: var(--sh-sm); transition: transform var(--m-fast) var(--e-std), box-shadow var(--m-fast) var(--e-std), background-color var(--m-base) var(--e-std), color var(--m-base) var(--e-std);
}
.wsp-chip.is-active { background: var(--c-navy); color: var(--c-cream); }
.wsp-chip:hover { transform: var(--lift); box-shadow: var(--wp--custom--shadow--pink-lg); color: var(--c-navy); }
.wsp-chip.is-active:hover { color: var(--c-cream); }
.wsp-hero-media { display: flex; flex-direction: column; gap: var(--s-6); min-height: 480px; }
.wsp-hero-stage {
	position: relative; flex: 1; min-height: 420px; background: var(--c-sand);
	border: 3px solid var(--c-navy); box-shadow: var(--sh-hero); overflow: hidden;
}
.wsp-hero-badge { padding: var(--s-3) var(--s-5); }
.wsp-hero-cap {
	position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); z-index: var(--wp--custom--z--raised);
	background: var(--c-navy); color: var(--c-cream); padding: var(--s-3) var(--s-8);
	font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--label);
	border: 2px solid var(--c-cream); box-shadow: var(--wp--custom--shadow--pink-sm); white-space: nowrap;
}
@media (max-width: 640px) {
	.wsp-hero { padding: var(--s-10) var(--wp--custom--section--pad-x-mobile) var(--wp--custom--section--pad-y-mobile); }
	/* Ben, 19 Oct: on a phone the postcard's padding (48/40) and the dashed frame's inset (8) left the copy a 264 px
	   column. Both come down (padding 32/20, inset 4), so the copy takes more of the width; the frame still clears the
	   text by 16 px, and the frame and the shadow stay. The kicker's tracking tightens (6 → 3 px) and balances, so
	   "Your adventure starts here!" never leaves "here!" alone on the second line. */
	.wsp-postcard.is-hero { padding: var(--s-8) var(--s-5); }
	.wsp-postcard.is-hero::before { inset: var(--s-1); }
	.wsp-hero-greeting { letter-spacing: var(--wp--custom--ls--label); text-wrap: balance; }
	.wsp-hero-media { min-height: 0; }
	.wsp-hero-stage { min-height: 320px; }
}
@media (max-width: 480px) {
	.wsp-hero-cap {
		white-space: normal; width: max-content; max-width: calc(100% - 32px); text-align: center;
		letter-spacing: var(--wp--custom--ls--button); padding: var(--s-2) var(--s-4); line-height: 1.25;
	}
}

/* ---- Logo bar (LogoBar) -------------------------------------------------- */
.wsp-logobar { background: var(--c-navy); padding: var(--s-10) 0; border-top: 3px solid var(--c-pink); border-bottom: 3px solid var(--c-pink); }
.wsp-logobar-inner { max-width: var(--wp--custom--maxw--wide); margin: 0 auto; }
.wsp-logobar-head { display: flex; align-items: center; justify-content: center; gap: var(--s-4); margin-bottom: var(--s-6); padding: 0 var(--s-6); flex-wrap: wrap; }
.wsp-logobar-label { font-family: var(--f-label); font-size: var(--fs-md); letter-spacing: var(--wp--custom--ls--label); text-transform: uppercase; color: var(--c-white); text-align: center; }
.wsp-logobar-toggle {
	background: transparent; border: 2px solid var(--wp--custom--alpha--white-55); color: var(--c-white);
	width: 44px; height: 44px; font-size: var(--fs-xs); cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0;
	transition: background-color var(--m-fast) var(--e-std), border-color var(--m-fast) var(--e-std);
}
.wsp-logobar-toggle[hidden] { display: none; }
.wsp-logobar-toggle:hover { background: var(--c-navy); border-color: var(--c-white); }
.wsp-logobar-view { overflow-x: auto; overscroll-behavior-x: contain; }
/* Still (no JS, reduced motion): one row the visitor can scroll, centred when it fits, never a wall of wrapped rows. */
.wsp-logobar-track { display: flex; flex-wrap: nowrap; width: max-content; margin-inline: auto; gap: var(--s-8); padding: var(--s-1) var(--s-6) var(--s-2); }
.wsp-logobar.is-moving .wsp-logobar-view {
	overflow: hidden;
	-webkit-mask-image: linear-gradient(90deg, transparent 0, var(--c-navy) 8%, var(--c-navy) 92%, transparent 100%);
	mask-image: linear-gradient(90deg, transparent 0, var(--c-navy) 8%, var(--c-navy) 92%, transparent 100%);
}
.wsp-logobar.is-moving .wsp-logobar-track {
	margin-inline: 0; padding: var(--s-1) var(--s-8) var(--s-2) var(--s-1);
}
/* site.js moves the track with the Web Animations API and eases its speed to a stop and back (hover, focus, the pause
   button), so nothing halts dead. The shuffle fades the track out and in when the strip is already on screen. */
/* Every tile the same width (Ben, 21 Oct): the logos' 174 px box + padding + border, so the strip is even. */
.wsp-logo-tile {
	position: relative; height: 80px; width: 220px; padding: 0 var(--s-5); flex-shrink: 0;
	background: var(--c-cream); border: 3px solid var(--c-navy); box-shadow: var(--wp--custom--shadow--pink-lg);
	display: flex; align-items: center; justify-content: center;
	font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--button); color: var(--c-navy);
}
/* Final logos (Dev Context §4, prompt 19a): sized by ops/design/normalise-logos.mjs to fit 174 × 48 by optical area; the
   width and height attributes reserve the box before the lazy image loads. */
.wsp-logo-pic { display: block; }
.wsp-logo-img { display: block; max-height: var(--s-12); max-width: 100%; height: auto; object-fit: contain; }
/* Treatment b (data/partners.json "navy"): the navy logo sits over the colour one and fades out on hover and focus. */
.wsp-logo-navy { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: var(--c-cream); transition: opacity var(--m-base) var(--e-std); }
.wsp-logo-tile:hover .wsp-logo-navy, .wsp-logobar-view:focus-within .wsp-logo-navy { opacity: 0; }

/* ---- Home: locations ----------------------------------------------------- */
.wsp-locations-intro { text-align: center; font-size: var(--fs-body); color: var(--c-muted); margin: calc(-1 * var(--s-10)) auto var(--s-16); }
.wsp-locations-intro a { color: var(--c-pink); border-bottom: 2px solid var(--c-pink); }
.wsp-locations-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-8); }
@media (min-width: 900px) { .wsp-locations-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.wsp-feature-city {
	position: relative; isolation: isolate; overflow: hidden; min-height: 600px;
	display: flex; flex-direction: column; justify-content: flex-end; padding: var(--s-12);
	color: var(--c-cream); border: 3px solid var(--c-navy); box-shadow: var(--sh-hover-lg);
	transition: transform var(--m-base) var(--e-std), box-shadow var(--m-base) var(--e-std);
}
.wsp-feature-city::before {
	content: ""; position: absolute; inset: 0; z-index: var(--wp--custom--z--behind);
	background: linear-gradient(138.81deg, var(--wp--custom--alpha--navy-92) 19.63%, var(--wp--custom--alpha--pink-60) 100.62%);
}
.wsp-feature-city-img { position: absolute; inset: 0; z-index: var(--wp--custom--z--behind-2); width: 100%; height: 100%; object-fit: cover; }
.wsp-feature-city:hover { transform: var(--lift-lg); box-shadow: var(--wp--custom--shadow--pink-11); color: var(--c-cream); }
.wsp-feature-city-dash { position: absolute; inset: var(--s-4); border: 1px dashed var(--wp--custom--alpha--sand-35); pointer-events: none; }
.wsp-feature-city-stamp {
	position: absolute; top: var(--s-8); left: var(--s-8);
	background: var(--c-pink); color: var(--c-white); padding: var(--s-3) var(--s-5); border: 2px solid var(--c-cream);
	font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--button);
	transform: rotate(-3deg); box-shadow: var(--wp--custom--shadow--stamp);
}
.wsp-feature-city-title {
	font-family: var(--f-display); font-weight: 700; font-size: var(--wp--preset--font-size--display-card); line-height: 0.95;
	letter-spacing: var(--wp--custom--ls--hero); color: inherit; margin: 0 0 var(--s-4);
}
.wsp-feature-city-text { font-size: var(--fs-body); line-height: 1.55; max-width: 480px; margin: 0 0 var(--s-8); opacity: 0.92; }
.wsp-feature-city-cta {
	align-self: flex-start; background: var(--c-cream); color: var(--c-navy); padding: var(--s-4) var(--s-8);
	border: 2px solid var(--c-cream); font-family: var(--f-label); font-size: var(--fs-button); letter-spacing: var(--wp--custom--ls--button);
	box-shadow: var(--wp--custom--shadow--pink-md);
}
.wsp-location-list { display: flex; flex-direction: column; gap: var(--s-5); }
.wsp-location-item {
	flex: 1 1 0; min-height: 112px; display: flex; align-items: center; gap: var(--s-4);
	background: var(--c-cream); border: 2px solid var(--c-navy); padding: var(--s-5) var(--s-6); box-shadow: var(--sh-md);
	transition: transform var(--m-base) var(--e-std), box-shadow var(--m-base) var(--e-std), background-color var(--m-base) var(--e-std);
}
.wsp-location-item:hover { background: var(--c-sand); box-shadow: var(--wp--custom--shadow--pink-7); transform: var(--lift-lg); color: inherit; }
.wsp-location-num {
	width: 48px; height: 48px; flex-shrink: 0; background: var(--c-teal); border: 2px solid var(--c-navy);
	display: flex; align-items: center; justify-content: center;
	font-family: var(--f-display); font-weight: 700; font-size: var(--fs-lede); color: var(--c-ink);
}
.wsp-location-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.wsp-location-name { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-lede); line-height: 1.1; color: var(--c-navy); }
.wsp-location-meta { font-family: var(--f-label); font-size: var(--fs-xs); letter-spacing: var(--wp--custom--ls--tight); color: var(--c-muted); margin-top: var(--s-1); }
.wsp-location-arrow { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-lg); color: var(--c-pink); }
@media (min-width: 641px) and (max-width: 899px) {
	.wsp-feature-city { min-height: 480px; padding: var(--s-10); }
}
@media (max-width: 640px) {
	.wsp-feature-city { min-height: 420px; padding: var(--s-6); }
	.wsp-feature-city-stamp { top: var(--s-5); left: var(--s-5); }
}

/* ---- Home: why (bento of FeatureCards) ----------------------------------- */
.wsp-bento { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-6); margin-top: var(--s-4); }
.wsp-feature-card {
	position: relative; background: var(--c-sand); border: 2px solid var(--c-navy); padding: var(--s-8) var(--s-6);
	box-shadow: var(--sh-lg); height: 100%; display: flex; flex-direction: column;
	transition: transform var(--m-base) var(--e-std), box-shadow var(--m-base) var(--e-std);
}
.wsp-feature-card:hover { box-shadow: var(--sh-hover-lg); transform: var(--lift-lg); }
.wsp-feature-num {
	position: absolute; top: calc(-1 * var(--s-4)); left: var(--s-6); width: 36px; height: 36px;
	border-radius: var(--wp--custom--radius--round); background: var(--c-pink); color: var(--c-white); border: 2px solid var(--c-navy);
	display: flex; align-items: center; justify-content: center;
	font-family: var(--f-display); font-weight: 700; font-size: var(--fs-md);
}
.wsp-feature-title { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-h3); line-height: var(--wp--custom--lh--tight); color: var(--c-navy); margin: var(--s-4) 0 var(--s-3); }
.wsp-feature-text { font-size: var(--fs-sm); line-height: var(--wp--custom--lh--body); color: var(--c-muted); margin: 0; flex: 1; }
.wsp-bento-photo {
	grid-column: 2 / 4; grid-row: 1 / 3; position: relative; overflow: hidden; min-height: 420px;
	border: 3px solid var(--c-navy); box-shadow: var(--wp--custom--shadow--card); transition: transform var(--m-base) var(--e-std), box-shadow var(--m-base) var(--e-std);
}
.wsp-bento-photo:hover { transform: var(--lift-lg); box-shadow: var(--wp--custom--shadow--pink-9); }
.wsp-bento-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Video (inc/video.php): fills its frame like the photo it replaces; the controls sit bottom-left on the picture. */
.wsp-video { position: absolute; inset: 0; background-color: var(--c-navy); }
.wsp-video-el { width: 100%; height: 100%; object-fit: cover; display: block; }
.wsp-video-poster img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.wsp-video-controls {
	position: absolute; left: var(--s-4); bottom: var(--s-4); z-index: var(--wp--custom--z--raised); display: flex; gap: var(--s-3);
	opacity: 0; transform: translateY(var(--s-3));
	transition: opacity var(--m-slow) var(--e-enter), transform var(--m-slow) var(--e-enter);
}
.wsp-video-controls[hidden] { display: none; }
/* The sound and play buttons ease in once the video is running (site.js initVideo), never pop. */
.wsp-video.is-ready .wsp-video-controls { opacity: 1; transform: none; }
.wsp-video-btn {
	position: relative; width: 44px; height: 44px; padding: 0; cursor: pointer;
	background-color: var(--c-cream); border: 2px solid var(--c-navy); color: var(--c-navy); box-shadow: var(--sh-sm);
	transition: background-color var(--m-fast) var(--e-std), color var(--m-fast) var(--e-std), transform var(--m-fast) var(--e-std), box-shadow var(--m-fast) var(--e-std);
}
.wsp-video-btn:hover { background-color: var(--c-pink); color: var(--c-white); transform: var(--lift); box-shadow: var(--wp--custom--shadow--pink-lg); }
/* Two icons per button, one per state (aria-pressed): they crossfade, never pop. */
.wsp-video-icon {
	position: absolute; inset: 0; margin: auto; width: var(--s-5); height: var(--s-5);
	transition: opacity var(--m-base) var(--e-std), transform var(--m-base) var(--e-std);
}
.wsp-video-btn .wsp-video-icon.is-on { opacity: 0; transform: scale(0.6); }
.wsp-video-btn[aria-pressed="true"] .wsp-video-icon.is-on { opacity: 1; transform: none; }
.wsp-video-btn[aria-pressed="true"] .wsp-video-icon.is-off { opacity: 0; transform: scale(0.6); }
.wsp-bento-stamp { border-width: 3px; padding: var(--s-5) var(--s-8); transform: rotate(6deg); box-shadow: var(--sh-md); }
.wsp-bento-star { color: var(--c-pink); font-size: var(--fs-2xl); line-height: 1; }
.wsp-bento-stamp-label { font-family: var(--f-label); font-size: var(--fs-lg); letter-spacing: var(--wp--custom--ls--label); color: var(--c-navy); margin-top: var(--s-3); line-height: 1.1; }
/* Four feature cards around the video: the full bento from wide (1240); below it the video spans the top and the cards
   are 2 × 2 (at 900 the four columns were about 140 px a card). */
@media (max-width: 1239px) {
	.wsp-bento { grid-template-columns: 1fr 1fr; }
	.wsp-bento-photo { grid-column: 1 / 3; grid-row: auto; min-height: 0; aspect-ratio: 16 / 9; order: -1; }
}
@media (max-width: 640px) {
	.wsp-bento { grid-template-columns: 1fr; }
	.wsp-bento-photo { grid-column: auto; aspect-ratio: 4 / 3; }
	/* Ben, 19 Oct: on a phone the full-size stamp covered a quarter of the video (faces, the carts). It drops to about
	   55% of its size, sized from the tokens (not scaled, so the border and shadow stay crisp), keeps its 6° turn and
	   its shadow, and tucks into the top-right corner, clear of the play and sound buttons (bottom-left). */
	.wsp-bento-stamp { top: var(--s-3); right: var(--s-3); border-width: 2px; padding: var(--s-2) var(--s-4); box-shadow: var(--sh-sm); }
	.wsp-bento-star { font-size: var(--fs-lg); }
	.wsp-bento-stamp-label { font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--tight); margin-top: var(--s-1); }
}

/* ---- Home: how it works -------------------------------------------------- */
.wsp-how { padding-bottom: calc(var(--s-24) + var(--s-5)); }
.wsp-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--wp--custom--gap--grid); }
/* Three steps: one column on phones and tablets, three across from desktop (no 2 + 1 row). */
@media (min-width: 900px) { .wsp-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.wsp-step {
	background: var(--c-sand); border: 3px solid var(--c-navy); padding: var(--s-10) var(--wp--custom--gap--grid) var(--s-8);
	text-align: center; box-shadow: var(--wp--custom--shadow--card);
}
.wsp-step:nth-child(2) { transform: translateY(36px); }
.wsp-step-num {
	width: 80px; height: 80px; margin: 0 auto var(--s-5); border-radius: var(--wp--custom--radius--round);
	background: var(--c-teal); border: 3px solid var(--c-navy); display: flex; align-items: center; justify-content: center;
	font-family: var(--f-display); font-weight: 700; font-size: var(--fs-3xl); line-height: 1; color: var(--c-ink); box-shadow: var(--sh-soft);
}
.wsp-step-title { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-lg); line-height: var(--wp--custom--lh--tight); color: var(--c-navy); margin: 0 0 var(--s-3); }
.wsp-step-text { font-size: var(--fs-button); line-height: var(--wp--custom--lh--body); color: var(--c-muted); max-width: 340px; margin: 0 auto; text-wrap: pretty; }
@media (max-width: 899px) {
	.wsp-step:nth-child(2) { transform: none; }
	.wsp-how { padding-bottom: var(--wp--custom--section--pad-y-tablet); }
}
@media (max-width: 640px) { .wsp-how { padding-bottom: var(--wp--custom--section--pad-y-mobile); } }

/* ---- Home: for every group ----------------------------------------------- */
.wsp-groups-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-16); align-items: start; }
/* Side by side from desktop (900): sticky portrait photo left, rows right; unchanged above 1047, where it was already. */
@media (min-width: 900px) { .wsp-groups-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.wsp-groups-photo {
	position: sticky; top: calc(var(--s-24) + var(--s-5)); aspect-ratio: 4 / 5; max-height: 720px; overflow: hidden;
	border: 3px solid var(--c-navy); box-shadow: var(--wp--custom--shadow--photo); background: var(--c-sand);
}
.wsp-groups-badge { padding: var(--s-4) var(--s-6); }
.wsp-group-list { display: flex; flex-direction: column; }
.wsp-group-row {
	display: grid; grid-template-columns: 64px minmax(0, 1fr) auto; gap: var(--s-5); align-items: start;
	padding: var(--wp--custom--gap--grid) 0 var(--wp--custom--gap--grid) var(--s-5);
	border-bottom: 2px dashed var(--wp--custom--alpha--navy-30); border-left: 4px solid transparent;
	transition: border-color var(--m-base) var(--e-std);
}
.wsp-group-row:hover { color: inherit; }
.wsp-group-num, .wsp-group-arrow { font-family: var(--f-display); font-weight: 700; line-height: 1; color: var(--wp--custom--alpha--navy-60); transition: color var(--m-base) var(--e-std); }
.wsp-group-num { font-size: var(--fs-2xl); }
.wsp-group-arrow { align-self: center; font-size: var(--fs-lg); }
.wsp-group-tag {
	display: inline-block; font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--button);
	padding: var(--s-1) var(--s-3); margin-bottom: var(--s-3); border: 1.5px solid var(--c-navy);
	background: var(--c-sand); color: var(--c-navy); transition: background-color var(--m-base) var(--e-std), color var(--m-base) var(--e-std);
}
.wsp-group-title { font-family: var(--f-display); font-weight: 700; font-size: var(--wp--preset--font-size--display-row); line-height: 1.1; color: var(--c-navy); margin: 0 0 var(--s-3); }
.wsp-group-text { font-size: var(--fs-button); line-height: var(--wp--custom--lh--body); color: var(--c-muted); max-width: 520px; margin: 0; }
.wsp-group-row.is-active { border-left-color: var(--c-pink); }
.wsp-group-row.is-active .wsp-group-num, .wsp-group-row.is-active .wsp-group-arrow { color: var(--c-pink); }
.wsp-group-row.is-active .wsp-group-tag { background: var(--c-pink); color: var(--c-white); }
/* Stacked (below 900: phones and tablets), one carousel (Cara, 20 Oct, prompt 19): the photo, the active row directly
   under it, then the indicators. site.js marks the grid .is-stacked from its actual column count (the source of truth,
   Ben, 20 Oct); without JS it stays the photo over the full list. The rows are the slides' content (one list, two
   layouts): stacked they share one grid cell, like the reviews carousel's slides, so the tallest sets the height and the
   page never jumps between items; only the active one is shown (the others are visibility: hidden, out of the a11y tree
   and the tab order) and they cross-fade with the photo, so nothing pops. Each indicator is the carousel's square dot;
   the active one is a pink tab that opens to show its number and name ("02 GIVEBACK"): the width eases open
   (0fr → 1fr) while the text fades in. Every tab keeps a 32 × 44 px target. Side by side (desktop) the indicators are
   hidden and the list is the full list: desktop is unchanged. Spacing: the row sits s-6 under the photo (clear of its
   10 px pink shadow), the indicators s-5 under the row. */
.wsp-groups-tabs { display: none; }
.wsp-groups-grid.is-stacked { row-gap: 0; }
/* Stacked, the photo scrolls with the page; sticky only side by side. */
.wsp-groups-grid.is-stacked .wsp-groups-photo { position: relative; top: auto; touch-action: pan-y; }
.wsp-groups-grid.is-stacked .wsp-group-list { display: grid; margin-top: var(--s-6); touch-action: pan-y; }
.wsp-groups-grid.is-stacked .wsp-group-row {
	grid-area: 1 / 1; border-bottom-color: transparent; opacity: 0; visibility: hidden;
	transition: opacity var(--m-slow) var(--e-std), visibility var(--m-slow) var(--e-std), border-color var(--m-base) var(--e-std);
}
.wsp-groups-grid.is-stacked .wsp-group-row.is-active { opacity: 1; visibility: visible; }
.wsp-groups-grid.is-stacked .wsp-groups-tabs {
	display: flex; justify-content: center; flex-wrap: wrap; width: 100%; margin-top: var(--s-5);
}
.wsp-groups-tab {
	min-width: 32px; height: 44px; padding: 0 var(--s-2); background: transparent; border: 0; cursor: pointer;
	display: flex; align-items: center; justify-content: center; color: var(--c-white);
}
.wsp-groups-tab-pill {
	display: grid; grid-template-columns: 0fr; align-items: center; min-width: var(--s-3); min-height: var(--s-3);
	border: 2px solid var(--c-navy); background: transparent; padding: 0;
	font-family: var(--f-label); font-size: 0; line-height: 1; letter-spacing: var(--wp--custom--ls--button); white-space: nowrap;
	transition: grid-template-columns var(--m-base) var(--e-std), padding var(--m-base) var(--e-std), font-size var(--m-base) var(--e-std), background-color var(--m-base) var(--e-std);
}
.wsp-groups-tab-text { min-width: 0; overflow: hidden; }
.wsp-groups-tab-text > span { display: block; opacity: 0; transition: opacity var(--m-base) var(--e-std); }
.wsp-groups-tab[aria-selected="true"] .wsp-groups-tab-pill {
	grid-template-columns: 1fr; padding: var(--s-1) var(--s-3); font-size: var(--fs-sm); background: var(--c-pink); border-color: var(--c-navy);
}
.wsp-groups-tab[aria-selected="true"] .wsp-groups-tab-text > span { opacity: 1; }
.wsp-groups-tab:hover .wsp-groups-tab-pill { background-color: var(--wp--custom--alpha--navy-30); }
.wsp-groups-tab[aria-selected="true"]:hover .wsp-groups-tab-pill { background-color: var(--c-pink); }
/* Tablet (Ben, 20 Oct, prompt 18): stacked at the container's full width as a landscape 3 / 2 crop, not a 576 px
   portrait beside an empty half. Each photo crops on its own focal point (--wsp-pos on its slide, patterns/home-groups.php);
   tablet only, so the desktop portrait and the phone 4 / 3 crop are unchanged. */
@media (min-width: 641px) and (max-width: 899px) {
	.wsp-groups-photo { position: relative; top: auto; aspect-ratio: 3 / 2; max-height: none; }
	.wsp-groups-photo .wsp-slide img { object-position: var(--wsp-pos, 50% 50%); }
}
@media (max-width: 640px) {
	.wsp-groups-photo { position: relative; top: auto; aspect-ratio: 4 / 3; }
	.wsp-group-row { grid-template-columns: 40px minmax(0, 1fr) auto; gap: var(--s-3); }
}

/* ---- Home: reviews (TestimonialCard) ------------------------------------- */
/* Stacked (below 900 px), the head's own margin (s-10) + the row gap (s-6) = s-16, the site's standard space
   between a section head and its content (Cara, G9: it was s-10 + s-16 = 104 px). Side by side there is one row, so
   only the column gap counts. */
.wsp-reviews-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-6) var(--s-16); align-items: center; }
@media (min-width: 900px) { .wsp-reviews-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.wsp-testimonial { position: relative; background: var(--c-cream); border: 3px solid var(--c-navy); box-shadow: var(--sh-hover-lg); padding: var(--s-12); }
.wsp-testimonial::before { border-color: var(--wp--custom--alpha--navy-30); }
/* Slides share one grid cell. Only the active review sizes the card (a waiting one is height 0 but
   still painted while it fades out); on change, site.js eases the card's height between the two
   reviews, so a long review never pops the card taller. The outgoing review slides out and fades,
   the incoming one slides in from the side it came from (data-dir, set by site.js). Touch swipe. */
.wsp-testimonial { display: grid; align-items: start; touch-action: pan-y; }
.wsp-testimonial-slide {
	grid-area: 1 / 1; position: relative; inset: auto; margin: 0; height: 0;
	opacity: 0; visibility: hidden; transform: translateX(calc(-1 * var(--s-6)));
	transition: opacity var(--m-base) var(--e-exit), transform var(--m-base) var(--e-exit), visibility var(--m-base) var(--e-exit);
}
.wsp-testimonial[data-dir="prev"] .wsp-testimonial-slide:not(.is-active) { transform: translateX(var(--s-6)); }
.wsp-testimonial-slide.is-active {
	height: auto; opacity: 1; visibility: visible; transform: none;
	transition: opacity var(--m-slow) var(--e-enter) var(--m-fast), transform var(--m-slow) var(--e-enter) var(--m-fast), visibility var(--m-fast) var(--e-enter);
}
/* Before site.js runs, the waiting slides enter from the right. */
.wsp-testimonial:not([data-dir]) .wsp-testimonial-slide:not(.is-active) { transform: translateX(var(--s-6)); }
.wsp-stars { color: var(--c-star); font-size: var(--fs-lede); letter-spacing: var(--wp--custom--ls--label); margin-bottom: var(--s-5); }
.wsp-quote { margin: 0 0 var(--s-8); }
.wsp-quote p { font-style: italic; font-size: var(--fs-quote); line-height: var(--wp--custom--lh--body); color: var(--c-ink); margin: 0; }
.wsp-quote-author { padding-top: var(--s-5); border-top: 2px dashed var(--wp--custom--alpha--navy-25); display: flex; flex-direction: column; }
.wsp-quote-name { font-family: var(--f-display); font-weight: 700; font-size: var(--fs-body); line-height: 1.1; color: var(--c-navy); }
.wsp-quote-company { font-family: var(--f-label); font-size: var(--fs-xs); letter-spacing: var(--wp--custom--ls--tight); color: var(--c-pink-text); margin-top: var(--s-1); }
/* ii-reviews: a rating below five dims the remaining stars; the source label links to the review on Google. */
.wsp-stars .wsp-star-off { color: var(--wp--custom--alpha--navy-25); }
.wsp-quote-source { color: inherit; text-decoration: underline; text-underline-offset: var(--s-1); transition: color var(--m-fast) var(--e-std); }
.wsp-quote-source:hover, .wsp-quote-source:focus-visible { color: var(--c-navy); }
.wsp-reviews .wsp-carousel-controls { margin-top: var(--s-8); }

/* ---- Home: FAQ (FaqItem) ------------------------------------------------- */
.wsp-faq { background-image: image-set(url("../img/faq-band-1800.webp") type("image/webp"), url("../img/faq-band-1800.png") type("image/png")); background-position: center; background-size: contain; background-repeat: no-repeat; }
.wsp-faq-wrap { max-width: var(--wp--custom--maxw--text); margin: 0 auto; display: flex; flex-direction: column; gap: var(--s-4); min-height: 640px; }
.wsp-faq-item { background: var(--c-cream); border: 2px solid var(--c-navy); box-shadow: var(--sh-md); }
/* Answer height animates 0fr → 1fr open AND closed; the + turns into − in step (its vertical bar
   rotates flat and fades). Closed answers are visibility:hidden, so they are out of the a11y tree. */
.wsp-faq-a {
	display: grid; grid-template-rows: 0fr; visibility: hidden;
	transition: grid-template-rows var(--m-base) var(--e-std), visibility var(--m-base) var(--e-std);
}
.wsp-faq-item.is-open .wsp-faq-a { grid-template-rows: 1fr; visibility: visible; }
.wsp-faq-a > .wsp-faq-a-inner { min-height: 0; overflow: hidden; }
.wsp-faq-a-inner > * { margin: 0; }
.wsp-faq-a-inner > * + * { margin-top: var(--s-3); }
.wsp-faq-q { margin: 0; font-size: inherit; }
.wsp-faq-q button {
	width: 100%; min-height: 64px; background: none; border: none; cursor: pointer; text-align: left;
	padding: var(--s-6); display: flex; justify-content: space-between; align-items: center; gap: var(--s-4);
	font-family: var(--f-display); font-weight: 700; font-size: var(--fs-body); color: var(--c-navy);
}
.wsp-faq-icon {
	flex-shrink: 0; width: 30px; height: 30px; background: var(--c-pink); color: var(--c-cream); border: 2px solid var(--c-navy);
	position: relative;
}
.wsp-faq-icon::before, .wsp-faq-icon::after {
	content: ""; position: absolute; inset: 0; margin: auto; width: 14px; height: 2px;
	background: currentColor; transition: transform var(--m-base) var(--e-std), opacity var(--m-base) var(--e-std);
}
.wsp-faq-icon::after { transform: rotate(90deg); }
.wsp-faq-item.is-open .wsp-faq-icon::after { transform: rotate(180deg); opacity: 0; }
.wsp-faq-a-inner { padding: 0 var(--s-6); font-size: var(--fs-button); line-height: 1.65; color: var(--c-muted); }
.wsp-faq-a-inner::after { content: ""; display: block; height: var(--s-6); }
@media (max-width: 899px) {
	.wsp-faq { background-image: none; }
	.wsp-faq-wrap { min-height: 600px; }
}
@media (max-width: 640px) { .wsp-faq-wrap { min-height: 520px; gap: var(--s-3); } }

/* ---- Home: meet Pinky ---------------------------------------------------- */
.wsp-pinky-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--s-16); align-items: center; }
@media (min-width: 900px) { .wsp-pinky-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.wsp-pinky-copy { color: var(--c-cream); }
.wsp-pinky-badge {
	display: inline-block; background: var(--c-white); color: var(--c-pink); padding: var(--s-2) var(--s-5);
	font-family: var(--f-label); font-size: var(--fs-sm); letter-spacing: var(--wp--custom--ls--label);
	box-shadow: var(--sh-sm); margin-bottom: var(--s-8);
}
.wsp-pinky-title {
	font-family: var(--f-display); font-weight: 700; font-size: var(--wp--preset--font-size--display-band); line-height: var(--wp--custom--lh--heading);
	letter-spacing: var(--wp--custom--ls--hero); color: inherit; margin: 0 0 var(--s-6); text-wrap: balance;
}
.wsp-pinky-text { font-size: var(--fs-body); line-height: 1.65; max-width: var(--wp--custom--maxw--prose); margin: 0 0 var(--s-10); text-wrap: pretty; color: var(--c-white); }
.wsp-pinky-media { display: flex; flex-direction: column; gap: var(--s-6); }
.wsp-pinky-frame { position: relative; aspect-ratio: 5 / 4; border: 3px solid var(--c-navy); box-shadow: var(--sh-xl); background: var(--c-sand); overflow: hidden; }

/* ---- Generic page (index.html, 404.html) --------------------------------- */
.wsp-page { padding: var(--s-16) var(--wp--custom--section--pad-x); }
.wsp-page-title { font-size: var(--fs-h2); margin: 0 0 var(--s-6); }

