/*
Theme Name: cpbmd
Theme URI: https://cpbmd.com/
Author: The Peak CRTVE Group
Author URI: https://peakcrtve.com/
Description: Block theme for Craig P. Bushong, MD (CPB-2026-01). Tokens in theme.json are the build contract; this sheet covers what theme.json cannot express — the crisis strip, sticky header, card surfaces, media frames and the CPB-2026-01-M motion layer.
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 8.1
Version: 1.4.31
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: cpbmd
*/

/* ==========================================================================
   1. Tokens — design-system names, bound to the theme.json presets
   ========================================================================== */

:root {
	--forest-900: var(--wp--preset--color--forest-900);
	--forest-800: var(--wp--preset--color--forest-800);
	--forest-700: var(--wp--preset--color--forest-700);
	--forest-600: var(--wp--preset--color--forest-600);
	--forest-500: var(--wp--preset--color--forest-500);
	--forest-300: var(--wp--preset--color--forest-300);
	--forest-200: var(--wp--preset--color--forest-200);
	--forest-100: var(--wp--preset--color--forest-100);
	--forest-050: var(--wp--preset--color--forest-050);
	--sage-100: var(--wp--preset--color--sage-100);
	--cream-050: var(--wp--preset--color--cream-050);
	--cream-100: var(--wp--preset--color--cream-100);
	--cream-200: var(--wp--preset--color--cream-200);
	--cream-300: var(--wp--preset--color--cream-300);
	--stone-600: var(--wp--preset--color--stone-600);
	--stone-700: var(--wp--preset--color--stone-700);
	--gold-600: var(--wp--preset--color--gold-600);
	--white: #fff;

	/*
	 * Label ink bound to the build contract (round 4). theme.json 6c1115ff corrects the
	 * sage-600 slot to #55705f (AA on every ground it sits on; worst case 4.56:1 on
	 * cream-200 and sage-100) and keeps #5f7a6c as sage-600-brand for non-text use.
	 * The palette preset reaches nothing unless a theme role reads it, so the role reads it
	 * here. Replaces the round-1 D-01 patch (--sage-700 #556d61), retired after verification.
	 */
	--sage-600: var(--wp--preset--color--sage-600);
	/* The original #5f7a6c, for large graphic use only and never for text. The Breath's outer
	   contours read this: v1.0 wrote `var(--sage-600, #5f7a6c)` because in the design token
	   sheet that slot IS #5f7a6c, but this build corrected it to #55705f for text AA. Binding
	   the role here keeps the graphic at the colour it was approved at. */
	--sage-600-brand: var(--wp--preset--color--sage-600-brand);
	/* --text-eyebrow: small sage label text — eyebrows, step labels, media placeholder labels. */
	--text-eyebrow: var(--sage-600);


	--brand: var(--forest-700);
	--brand-hover: var(--forest-800);
	--brand-active: var(--forest-900);
	--brand-soft: var(--forest-050);
	--text-heading: var(--forest-700);
	--text-body: var(--stone-700);
	--text-muted: var(--stone-600);
	--text-link: var(--forest-700);
	--text-link-hover: var(--forest-500);
	--border-hairline: var(--cream-300);
	--border-on-inverse: rgba(247, 244, 236, .22);
	--focus-ring: var(--forest-500);

	--radius-card: 12px;
	--radius-media: 20px;
	--radius-pill: 999px;

	--shadow-sm: 0 2px 8px rgba(12, 36, 31, .07);
	--shadow-md: 0 8px 24px rgba(12, 36, 31, .09);
	--shadow-lg: 0 18px 44px rgba(12, 36, 31, .12);
	--shadow-focus: 0 0 0 3px rgba(42, 93, 81, .28);

	/* Ruling 37 (Principal-approved, round 5): content caps at 1440px, always inside the 24px
	   gutter. Backgrounds still bleed full width (38); prose keeps its ~68ch measure (39). */
	--container-max: 1440px;
	/* Round 6 ruling: 1440 is a ceiling, not a target. Components that only stretched because
	   nothing stopped them cap themselves: the side-rail layout (rail + content column as one
	   unit) and the office strip both keep their 1180 composition. */
	--container-rail: 1180px;
	--container-strip: 1180px;
	--gutter: 24px;
	--section-y: 96px;
	--section-y-tight: 64px;

	--font-display: var(--wp--preset--font-family--display);
	--font-sans: var(--wp--preset--font-family--sans);
	--type-h2: 400 40px/1.25 var(--font-display);
	--type-h3: 400 26px/1.25 var(--font-display);
	--type-h4: 500 19px/1.25 var(--font-sans);
	--type-eyebrow: 500 13px/1.4 var(--font-sans);
	--type-lead: 300 19px/1.7 var(--font-sans);
	--type-body: 400 17px/1.55 var(--font-sans);
	--type-small: 400 15px/1.55 var(--font-sans);
	--type-label: 500 15px/1.3 var(--font-sans);
	--type-button: 500 15px/1 var(--font-sans);

	/* CPB-2026-01-M motion tokens (tokens/cpb-token-extensions.css) */
	--ease-out: cubic-bezier(.22, .61, .36, 1);
	--motion-press: 120ms cubic-bezier(.2, .7, .3, 1);
	--motion-focus: 160ms ease-out;
	--motion-resolve: 240ms cubic-bezier(.22, .8, .3, 1);
	--motion-morph: 420ms cubic-bezier(.22, .8, .3, 1);
	--motion-stagger: 70ms;
	/* Duration ONLY (ruling 277): the Breath's per-phase easing lives inside its keyframes,
	   and v1.0 consumes this as `animation-duration`, where a shorthand value would be
	   invalid and silently drop the animation. Lands in the v1.1 token package. */
	--motion-breath: 19s;

	--crisis-bg: var(--forest-800);
	--crisis-ink: var(--cream-100);
	--crisis-ink-muted: var(--forest-200);
}

/*
 * Metric-matched fallbacks while the Adobe Fonts kit loads (the licence prohibits
 * self-hosting). Overrides measured from the kit's own OS/2 + hhea tables; size-adjust
 * against Georgia / Arial average glyph width. Keeps the swap from moving layout.
 */
@font-face {
	font-family: "aesthet-nova-fallback";
	src: local("Georgia");
	/* Round 16: calibrated on the site's own display text (54 headings): Aesthet Nova sets at 94.45% of
	   Georgia's width. At 87% the fallback was ~8% narrower, so headings wrapped differently when the kit
	   font swapped in — the Aspen hero H1 went 1 line → 2 and shifted the photo (CLS). */
	size-adjust: 94.5%;
	ascent-override: 106.8%;
	descent-override: 26.4%;
	line-gap-override: 0%;
}

@font-face {
	font-family: "quasimoda-fallback";
	src: local("Arial"), local("Helvetica Neue"), local("Helvetica");
	/* Round 16: calibrated on 189 body strings: Quasimoda sets at 100.49% of Arial's width (p10–p90
	   99.2–101.5%). Was 96.6%, ~4% narrow, so hero copy re-wrapped when the kit font swapped in (Contact
	   CLS). 101% is inside the measured spread and gave the fewest first-screen shifts across all nine
	   pages at 412px in a grid search (97–104%). No single value zeroes every page: line breaks are
	   per-string thresholds. */
	size-adjust: 101%;
	ascent-override: 115.4%;
	descent-override: 28.4%;
	line-gap-override: 0%;
}

html:root {
	--wp--preset--font-family--display: "aesthet-nova", "Aesthet Nova", "aesthet-nova-fallback", Georgia, "Times New Roman", serif;
	--wp--preset--font-family--sans: "quasimoda", "Quasimoda", "quasimoda-fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ==========================================================================
   2. Base
   ========================================================================== */

*,
*::before,
*::after {
	box-sizing: border-box;
}

body {
	margin: 0;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

body .wp-site-blocks > *,
.cpb-main.is-layout-flow > *,
.cpb-site-header .is-layout-flow > *,
.cpb-main .is-layout-flow > *,
.cpb-site-footer .is-layout-flow > * {
	margin-block: 0;
}

:is(.cpb-site-header, .cpb-main, .cpb-site-footer) :is(h1, h2, h3, h4, h5, h6, p, figure, ul) {
	margin: 0;
}

:is(h1, h2, h3, h4, h5, h6) {
	text-wrap: balance;
}

p {
	text-wrap: pretty;
}

a {
	color: var(--text-link);
	text-decoration-color: var(--forest-300);
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	transition: color 160ms var(--ease-out);
}

a:hover {
	color: var(--text-link-hover);
	text-decoration-color: currentColor;
}

/* Focus is never removed (README §5). */
:focus-visible {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

img,
svg {
	display: block;
	max-width: 100%;
	height: auto;
}

::selection {
	background: var(--forest-200);
	color: var(--forest-900);
}

.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}

/* ==========================================================================
   3. Layout primitives
   ========================================================================== */

.cpb-section {
	padding: var(--section-y) var(--gutter);
}

.cpb-section--tight {
	padding-block: var(--section-y-tight);
}

.cpb-inner {
	max-width: var(--container-max);
	margin-inline: auto;
}

.cpb-bg-page { background: var(--cream-100); }
.cpb-bg-raised { background: var(--cream-050); }
.cpb-bg-sunken { background: var(--cream-200); }
.cpb-bg-forest { background: var(--forest-700); }

.cpb-stack { display: flex; flex-direction: column; }
.cpb-gap-8 { gap: 8px; }
.cpb-gap-12 { gap: 12px; }
.cpb-gap-16 { gap: 16px; }
.cpb-gap-20 { gap: 20px; }
.cpb-gap-24 { gap: 24px; }
.cpb-gap-32 { gap: 32px; }

.cpb-actions {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 24px;
}

.cpb-actions--tight { gap: 16px; }

.cpb-actions .wp-block-buttons {
	margin: 0;
}

/* ==========================================================================
   4. Type roles
   ========================================================================== */

.cpb-eyebrow {
	font: var(--type-eyebrow);
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--text-eyebrow);
}

.cpb-bg-forest .cpb-eyebrow { color: var(--forest-200); }

.cpb-h2,
.cpb-main .cpb-h2 {
	font: var(--type-h2);
	letter-spacing: -.01em;
	color: var(--text-heading);
}

.cpb-h3,
.cpb-main .cpb-h3 {
	font: var(--type-h3);
	letter-spacing: -.01em;
	color: var(--text-heading);
}

.cpb-h4,
.cpb-main .cpb-h4 {
	font: var(--type-h4);
	letter-spacing: 0;
	color: var(--text-heading);
}

.cpb-lead { font: var(--type-lead); color: var(--text-body); }
.cpb-body { font: var(--type-body); color: var(--text-body); }
.cpb-small { font: var(--type-small); color: var(--text-body); }
.cpb-muted { color: var(--text-muted); }

.cpb-heading {
	display: flex;
	flex-direction: column;
	gap: 16px;
	max-width: 640px;
}

.cpb-main .cpb-heading--center {
	align-items: center;
	text-align: center;
	margin-inline: auto;
	margin-bottom: 48px;
}

.cpb-heading--narrow { max-width: 560px; }

.cpb-bg-forest .cpb-h2 { color: var(--cream-100); }
.cpb-bg-forest .cpb-lead { color: var(--forest-100); }

/* Text link — no underline at rest, revealed on hover (README §5). */
.cpb-textlink {
	font: var(--type-label);
}

.cpb-textlink a,
.cpb-card__more a {
	color: var(--text-link);
	text-decoration: none;
}

.cpb-textlink a:hover,
.cpb-card__more a:hover {
	color: var(--text-link-hover);
	text-decoration: underline;
	text-decoration-color: currentColor;
}

/* ==========================================================================
   5. Icons — Lucide 0.454.0 (flagged substitution), inlined as CSS masks.
      24px grid, 2px stroke, no fill; colour is currentColor. Always decorative
      and always paired with a visible label.
   ========================================================================== */

.cpb-i-award { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15.477 12.89 1.515 8.526a.5.5 0 0 1-.81.47l-3.58-2.687a1 1 0 0 0-1.197 0l-3.586 2.686a.5.5 0 0 1-.81-.469l1.514-8.526'/%3E%3Ccircle cx='12' cy='8' r='6'/%3E%3C/svg%3E"); }
.cpb-i-map-pin { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0'/%3E%3Ccircle cx='12' cy='10' r='3'/%3E%3C/svg%3E"); }
.cpb-i-clock { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpolyline points='12 6 12 12 16 14'/%3E%3C/svg%3E"); }
.cpb-i-messages-square { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14 9a2 2 0 0 1-2 2H6l-4 4V4a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2z'/%3E%3Cpath d='M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1'/%3E%3C/svg%3E"); }
.cpb-i-pill { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m10.5 20.5 10-10a4.95 4.95 0 1 0-7-7l-10 10a4.95 4.95 0 1 0 7 7Z'/%3E%3Cpath d='m8.5 8.5 7 7'/%3E%3C/svg%3E"); }
.cpb-i-house { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8'/%3E%3Cpath d='M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/%3E%3C/svg%3E"); }
.cpb-i-calendar-check { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2v4'/%3E%3Cpath d='M16 2v4'/%3E%3Crect width='18' height='18' x='3' y='4' rx='2'/%3E%3Cpath d='M3 10h18'/%3E%3Cpath d='m9 16 2 2 4-4'/%3E%3C/svg%3E"); }
.cpb-i-heart-handshake { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3Cpath d='M12 5 9.04 7.96a2.17 2.17 0 0 0 0 3.08c.82.82 2.13.85 3 .07l2.07-1.9a2.82 2.82 0 0 1 3.79 0l2.96 2.66'/%3E%3Cpath d='m18 15-2-2'/%3E%3Cpath d='m15 18-2-2'/%3E%3C/svg%3E"); }
.cpb-i-accessibility { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='16' cy='4' r='1'/%3E%3Cpath d='m18 19 1-7-6 1'/%3E%3Cpath d='m5 8 3-3 5.5 3-2.36 3.5'/%3E%3Cpath d='M4.24 14.5a5 5 0 0 0 6.88 6'/%3E%3Cpath d='M13.76 17.5a5 5 0 0 0-6.88-6'/%3E%3C/svg%3E"); }
.cpb-i-shield-check { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E"); }
.cpb-i-mail { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect width='20' height='16' x='2' y='4' rx='2'/%3E%3Cpath d='m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7'/%3E%3C/svg%3E"); }
.cpb-i-phone { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'/%3E%3C/svg%3E"); }
.cpb-i-mountain-snow { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m8 3 4 8 5-5 5 15H2L8 3z'/%3E%3Cpath d='M4.14 15.08c2.62-1.57 5.24-1.43 7.86.42 2.74 1.94 5.49 2 8.23.19'/%3E%3C/svg%3E"); }
.cpb-i-flask-conical { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.55a1 1 0 0 0 .9 1.45h12.76a1 1 0 0 0 .9-1.45l-5.069-10.127A2 2 0 0 1 14 9.527V2'/%3E%3Cpath d='M8.5 2h7'/%3E%3Cpath d='M7 16h10'/%3E%3C/svg%3E"); }
.cpb-i-git-branch { --cpb-i: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='6' x2='6' y1='3' y2='15'/%3E%3Ccircle cx='18' cy='6' r='3'/%3E%3Ccircle cx='6' cy='18' r='3'/%3E%3Cpath d='M18 9a9 9 0 0 1-9 9'/%3E%3C/svg%3E"); }

.cpb-ic,
.cpb-well::before,
.cpb-credential::before,
.cpb-icon-line::before {
	content: "";
	display: block;
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	background-color: currentColor;
	-webkit-mask: var(--cpb-i) center / contain no-repeat;
	mask: var(--cpb-i) center / contain no-repeat;
}

@media (forced-colors: active) {
	.cpb-ic,
	.cpb-well::before,
	.cpb-credential::before,
	.cpb-icon-line::before {
		forced-color-adjust: none;
		background-color: CanvasText;
	}
}

/* Circular icon well: 40px sage (value rows), 52px brand-soft (service cards), inverse on forest. */
.cpb-well {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--sage-100);
	color: var(--forest-600);
}

.cpb-well--lg {
	width: 52px;
	height: 52px;
	background: var(--brand-soft);
	color: var(--brand);
}

.cpb-well--white {
	background: var(--white);
}

.cpb-well--inverse {
	background: rgba(247, 244, 236, .14);
	color: var(--cream-100);
}

/* ==========================================================================
   6. Buttons (P-08). theme.json supplies the primary fill, hover and active.
      TEMPORARY — token package v1.1 (ruling D-03): theme.json references
      --wp--custom--radius-button and --wp--custom--radius-media, but WordPress emits
      nested custom tokens with a double dash (--wp--custom--radius--button). Both
      declarations resolve to nothing, so the pill and media radii are restated here.
   ========================================================================== */

.wp-site-blocks .wp-element-button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	border: 1px solid var(--brand);
	border-radius: var(--radius-pill);
	line-height: 1;
	letter-spacing: .04em;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	transition:
		background-color 160ms var(--ease-out),
		color 160ms var(--ease-out),
		border-color 160ms var(--ease-out),
		box-shadow 160ms var(--ease-out),
		transform var(--motion-press);
}

.wp-site-blocks .wp-element-button:hover { border-color: var(--brand-hover); }

/* TEMPORARY (D-03) — theme.json styles.blocks.core/image border radius. */
.wp-block-image img { border-radius: var(--radius-media); }
.wp-site-blocks .wp-element-button:active { border-color: var(--brand-active); transform: scale(.985); }

.wp-site-blocks button.cpb-btn--lg,
.wp-site-blocks .cpb-btn-lg .wp-element-button {
	padding: 18px 34px;
	font-size: 17px;
}

.wp-site-blocks .cpb-btn-sm.wp-element-button {
	padding: 10px 20px;
	font-size: 13px;
}

.wp-site-blocks a.cpb-btn--secondary,
.wp-site-blocks .is-style-secondary .wp-element-button {
	background: var(--white);
	color: var(--brand);
	border-color: var(--brand);
}

.wp-site-blocks a.cpb-btn--secondary:is(:hover, :active),
.wp-site-blocks .is-style-secondary .wp-element-button:is(:hover, :active) {
	background: var(--brand-soft);
	color: var(--brand);
	border-color: var(--brand);
}

.wp-site-blocks .is-style-inverse .wp-element-button {
	background: var(--cream-100);
	color: var(--forest-700);
	border-color: var(--cream-100);
}

.wp-site-blocks .is-style-inverse .wp-element-button:is(:hover, :active) {
	background: var(--white);
	color: var(--forest-700);
	border-color: var(--white);
}

.wp-site-blocks .wp-element-button[aria-disabled="true"] {
	opacity: .45;
	pointer-events: none;
}

/* ==========================================================================
   7. Cards + media frames
   ========================================================================== */

.cpb-card {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 28px;
	border: 1px solid transparent;
	border-radius: var(--radius-card);
	background: var(--white);
	transition: transform var(--motion-resolve), box-shadow var(--motion-resolve);
}

.cpb-card--lg { padding: 36px; }
.cpb-card--plain { box-shadow: var(--shadow-sm); }
.cpb-card--outline { border-color: var(--border-hairline); }

.cpb-card--soft {
	background: var(--brand-soft);
	border-color: var(--forest-200);
}

a.cpb-card {
	color: inherit;
	text-decoration: none;
}

.cpb-card--interactive:is(:hover, :focus-within, :focus-visible) {
	transform: translateY(-2px);
	box-shadow: var(--shadow-md);
}

.cpb-main .cpb-card__more {
	margin-top: 8px;
	font: var(--type-button);
	letter-spacing: .04em;
}

/* Media frame. Placeholder state is labelled with the approved asset that belongs
   there — no stock photography (README §4.1). */
.cpb-media {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;
	aspect-ratio: 3 / 2;
	padding: 24px;
	border-radius: var(--radius-media);
	background: repeating-linear-gradient(135deg, var(--sage-100) 0 12px, var(--cream-200) 12px 24px);
	box-shadow: var(--shadow-lg);
	text-align: center;
}

.cpb-media--4x5 { aspect-ratio: 4 / 5; }
.cpb-media--3x4 { aspect-ratio: 3 / 4; }
.cpb-media--circle { aspect-ratio: 1; border-radius: 50%; padding: 16px; }

.cpb-media img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.cpb-media__label {
	font: var(--type-small);
	color: var(--text-eyebrow);
}

/* ==========================================================================
   8. Site header — crisis strip → nav → locations panel → reading rail
   ========================================================================== */

.cpb-site-header {
	position: sticky;
	top: 0;
	z-index: 40;
	background: var(--cream-100);
}

.admin-bar .cpb-site-header { top: var(--wp-admin--admin-bar--height, 32px); }

@media (max-width: 600px) {
	.admin-bar .cpb-site-header { top: 0; }
}

/* P-00 — the one element with zero motion. Ever. */
.cpb-crisis {
	background: var(--crisis-bg);
	color: var(--crisis-ink);
}

.cpb-crisis,
.cpb-crisis * {
	transition: none !important;
	animation: none !important;
	transform: none !important;
}

.cpb-crisis__inner {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 4px 20px;
	max-width: var(--container-max);
	margin-inline: auto;
	padding: 10px var(--gutter);
	font: 400 13px/1.55 var(--font-sans);
}

.cpb-crisis p { color: var(--crisis-ink); }
.cpb-crisis__meta { margin-left: auto; }
.cpb-site-header .cpb-crisis .cpb-crisis__meta { color: var(--crisis-ink-muted); }

.cpb-crisis a,
.cpb-crisis a:hover {
	color: var(--crisis-ink);
	text-decoration-color: var(--forest-300);
}

.cpb-crisis__lead a { font-weight: 500; }
.cpb-crisis :focus-visible { outline-color: var(--cream-100); }

.cpb-skip:not(:focus) {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.cpb-skip:focus {
	position: absolute;
	top: 8px;
	left: 8px;
	z-index: 60;
	padding: 10px 16px;
	border-radius: 8px;
	background: var(--cream-050);
	color: var(--brand);
	font: var(--type-label);
}

.cpb-nav {
	position: relative;
	border-bottom: 1px solid var(--border-hairline);
}

.cpb-nav__inner {
	display: flex;
	align-items: center;
	gap: 40px;
	max-width: var(--container-max);
	margin-inline: auto;
	padding: 16px var(--gutter);
}

.cpb-nav__logo {
	display: block;
	flex: 0 0 auto;
}

.cpb-nav__logo img {
	width: auto;
	height: 52px;
}

.cpb-nav__menu { margin-left: auto; }

.cpb-nav__list {
	display: flex;
	align-items: center;
	gap: 32px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.cpb-nav__link {
	display: block;
	padding-bottom: 3px;
	border-bottom: 1px solid transparent;
	color: var(--stone-700);
	font: var(--type-label);
	letter-spacing: .04em;
	text-decoration: none;
	cursor: pointer;
	transition: color 160ms var(--ease-out), border-color 160ms var(--ease-out);
}

.cpb-nav__link:hover { color: var(--forest-700); }

.cpb-nav__link[aria-current],
.cpb-loc[open] > .cpb-nav__link {
	color: var(--forest-700);
	border-bottom-color: var(--forest-700);
}

/* Locations — native disclosure: click, keyboard and no-JS all work. */
.cpb-loc > summary {
	list-style: none;
}

.cpb-loc > summary::-webkit-details-marker {
	display: none;
}

.cpb-loc__panel {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	background: var(--cream-050);
	border-bottom: 1px solid var(--border-hairline);
	box-shadow: var(--shadow-sm);
}

.cpb-loc__inner {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 24px;
	max-width: var(--container-max);
	margin-inline: auto;
	padding: 32px var(--gutter);
}

.cpb-loc__title {
	display: flex;
	align-items: center;
	gap: 12px;
	color: var(--forest-600);
}

.cpb-loc__addr {
	font: var(--type-small);
	color: var(--text-muted);
}

.cpb-loc__cta {
	font: var(--type-button);
	letter-spacing: .04em;
	color: var(--brand);
}

.cpb-loc__card:hover .cpb-loc__cta { color: var(--text-link-hover); }

/* P-07 — reading rail. Hidden in the base layer so it never shows as a stray line. */
.cpb-rail {
	height: 2px;
	background: var(--brand);
	transform-origin: 0 50%;
	transform: scaleX(0);
	opacity: 0;
	pointer-events: none;
}

/* ==========================================================================
   9. Home sections
   ========================================================================== */

/* 4.1 Hero */
.cpb-hero { padding-block: 80px; }

/* The Breath is absolutely positioned and deliberately bleeds past the right edge, so the
   Home hero is its containing block and crops it. Scoped away from .cpb-loc-hero (About and
   the two location pages share .cpb-hero and carry no Breath). */
.cpb-hero:not(.cpb-loc-hero) {
	position: relative;
	overflow: hidden;
}

.cpb-hero__grid {
	display: grid;
	grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
	gap: 64px;
	align-items: center;
	/* The Breath is a later sibling, so it would paint over the hero. Raising the grid keeps
	   the graphic as the field behind and floats the photograph above it (design direction,
	   round 22). Both columns are opaque-free, so the contours still read between them. */
	position: relative;
	z-index: 1;
}

/* Ruling 298: if the Home hero ever loses its photograph again it falls to one column, and the
   copy holds its own measure rather than running to 1440, leaving the right of the field to the
   Breath.

   SCOPED TO HOME, and testing for media of ANY class. Round 22 wrote this as a bare
   `.cpb-hero__grid:not(:has(> .cpb-hero__media))`, which was a regression: About and the two
   location pages share .cpb-hero__grid but their media child is `.cpb-media`, not
   `.cpb-hero__media`. The selector therefore matched them, collapsed their two-column heroes to
   one, and dropped a 1392px-wide portrait below the copy at 1440. Reported by design, round 32.

   Keep both halves of the guard: `.cpb-hero:not(.cpb-loc-hero)` so only Home can match, and the
   two-class :has() so a hero that labels its media differently is never caught again. */
.cpb-hero:not(.cpb-loc-hero) .cpb-hero__grid:not(:has(> .cpb-hero__media)):not(:has(> .cpb-media)) {
	grid-template-columns: minmax(0, 1fr);
}

.cpb-hero:not(.cpb-loc-hero) .cpb-hero__grid:not(:has(> .cpb-hero__media)):not(:has(> .cpb-media)) > .cpb-hero__copy {
	max-width: min(100%, 680px);
}

.cpb-main .cpb-hero__title {
	font: 400 50px/1.08 var(--font-display);
	letter-spacing: -.01em;
	color: var(--text-heading);
}

.cpb-hero__lead { max-width: 54ch; }

.cpb-credential {
	display: flex;
	align-items: flex-start;
	gap: 12px;
	padding-top: 20px;
	border-top: 1px solid var(--border-hairline);
	color: var(--forest-600);
}

.cpb-credential p {
	max-width: 48ch;
	font: var(--type-small);
	color: var(--text-body);
}

.cpb-hero__media { position: relative; }

/* First screen (961px and up, where the two-column hero can fit): the hero fills the viewport
   below the sticky header, content centred, and the 4:5 frame scales down (ratio kept) until it
   fits. If the copy itself is taller than the space, min-height lets the hero grow. Below 961px
   the hero stacks and is taller than any phone screen, so it keeps its natural height.
   --cpb-header-h is the desktop header: crisis strip 40px (one line from 961px) + nav 85px. */
:root { --cpb-header-h: 125px; }
.admin-bar { --cpb-admin-h: var(--wp-admin--admin-bar--height, 32px); }

@media (min-width: 961px) {
	/* Home only: About and the location pages share .cpb-hero but carry .cpb-loc-hero. */
	.cpb-hero:not(.cpb-loc-hero) {
		--cpb-hero-pad: clamp(24px, 4vh, 64px);
		display: grid;
		align-content: center;
		min-height: calc(100vh - var(--cpb-header-h) - var(--cpb-admin-h, 0px));
		min-height: calc(100svh - var(--cpb-header-h) - var(--cpb-admin-h, 0px));
		padding-block: var(--cpb-hero-pad);
	}

	.cpb-hero:not(.cpb-loc-hero) > .cpb-inner { width: 100%; }

	.cpb-hero__media {
		justify-self: end;
		width: min(100%, calc((100vh - var(--cpb-header-h) - var(--cpb-admin-h, 0px) - 2 * var(--cpb-hero-pad)) * 4 / 5));
		width: min(100%, calc((100svh - var(--cpb-header-h) - var(--cpb-admin-h, 0px) - 2 * var(--cpb-hero-pad)) * 4 / 5));
	}
}

/* --------------------------------------------------------------------------
   P-01 — The Breath · CPB-2026-01-B v1.0 (approved 16 Sep, lifted in round 22).
   Concentric topographic contours, Home hero only. Ambient, never instructional:
   do not add a label, caption, count, control or phase text.

   GEOMETRY   480×480 view box, eight nested contours, summit off-centre high-left.
              Full-bleed: anchored past the right edge and cropped by the hero.
   MOTION     19.00s · inhale 0→21.05% · hold →57.89% · exhale →100%. Per-phase easing
              lives inside the keyframes; --motion-breath carries duration ONLY (ruling 277).
   PHASING    Positive delays 0 → 0.40s increasing outward — the centre leads and the
              ripple runs out through the field. No will-change: a continuously running
              transform is composited without it, and eight permanent layers is memory
              these patients' phones should not spend.
   REST       The rest frame is authored inline on each contour, so both the @supports
              guard and reduced motion fall back to a designed still, not frame zero.
   -------------------------------------------------------------------------- */
.cpb-breath {
	position: absolute;
	top: 50%;
	right: 0;
	width: clamp(420px, 78vw, 1180px);
	aspect-ratio: 1;
	margin: 0;
	transform: translate(34%, -50%);
	pointer-events: none;
	contain: layout paint style;
}

.cpb-breath svg { display: block; width: 100%; height: 100%; overflow: visible; }

.cpb-breath [data-breath] {
	transform-box: view-box;
	transform-origin: 50% 50%;
}

@supports (transform-box: view-box) {
	@media (prefers-reduced-motion: no-preference) {
		.cpb-breath [data-breath] {
			animation-name: cpb-breath;
			animation-duration: var(--motion-breath, 19s);
			animation-iteration-count: infinite;
			animation-fill-mode: both;
		}
	}
}

/* --------------------------------------------------------------------------
   P-01 mobile — The Breath, band · CPB-2026-01-B2 v1.1 (cleared round 25, ruling 384).
   960px and below. A companion composition, NOT the desktop field scaled: a 480x480
   eight-contour field on a phone either crosses text or becomes a sliver (measured,
   round 22). Six purpose-drawn ridges in a 96px strip instead.

   The rest frame travels as --breath-rest and is applied here, never inline: a custom
   property survives a templating layer and cannot be removed by a harness. That is the
   state a reduced-motion visitor sees and what the @supports guard falls through to.

   The band lives in the hero's existing 96px bottom rhythm. Do NOT add padding,
   min-height or margin for it; if that padding ever drops below 96px the band is
   re-measured, not rescaled.

   Boundary: see §12, where the two display rules sit together.
   -------------------------------------------------------------------------- */
.cpb-band {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 96px;
  margin: 0;
  pointer-events: none;
  contain: layout paint style;
}
.cpb-band svg { display: block; width: 100%; height: 100%; }

/* The rest frame. A custom property, not an inline transform: it cannot be dropped by a
   templating layer and cannot be removed by a harness. This is the state a reduced-motion
   visitor sees, and the state the @supports guard falls through to. */
.cpb-band [data-breath] {
  transform-box: view-box;
  transform-origin: 600px 700px;
  transform: scale(var(--breath-rest, 1));
}

@keyframes cpb-band {
  0% {
    transform: scale(var(--breath-min, .966));
    animation-timing-function: cubic-bezier(.4, 0, .5, 1);      /* inhale — 4s */
  }
  21.05% {
    transform: scale(var(--breath-max, 1));
    animation-timing-function: linear;                          /* hold — 7s, no travel */
  }
  57.89% {
    transform: scale(var(--breath-max, 1));
    animation-timing-function: cubic-bezier(.3, 0, .3, 1);      /* exhale — 8s, slow release */
  }
  100% { transform: scale(var(--breath-min, .966)); }
}

@supports (transform-box: view-box) {
  @media (prefers-reduced-motion: no-preference) {
    .cpb-band [data-breath] {
      animation-name: cpb-band;
      animation-duration: var(--motion-breath, 19s);
      animation-iteration-count: infinite;
      animation-fill-mode: both;
    }
  }

/* 4.2 Office bar */
.cpb-offices { padding-block: 32px; }

.cpb-offices__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 24px;
}

/* NAP strip: capped and centred — an address spread across 1440 is harder to scan. On wide
   screens the three items size to their content and share the spare width as equal gaps, so
   the group reads centred instead of leaving the last column's text short of the edge. */
.cpb-inner.cpb-offices__grid { max-width: var(--container-strip); }

@media (min-width: 961px) {
	.cpb-inner.cpb-offices__grid {
		grid-template-columns: repeat(3, auto);
		justify-content: space-between;
	}
}

.cpb-offices__item {
	display: flex;
	align-items: center;
	gap: 16px;
}

.cpb-offices__item p {
	font: var(--type-small);
	color: var(--forest-100);
}

/* 4.3 Services */
.cpb-services__grid {
	display: grid;
	grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
	gap: 64px;
	align-items: center;
}

/* Ruling 260: with the photograph slot hidden, the services grid is one column, capped. */
.cpb-services__grid:not(:has(> .cpb-media)) {
	grid-template-columns: minmax(0, 1fr);
	max-width: var(--container-rail);
}

.cpb-services__cards {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20px;
}

.cpb-service { gap: 16px; }

/* 4.4 Provider */
.cpb-provider__grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 320px;
	gap: 64px;
	align-items: start;
}

.cpb-statement { max-width: 34ch; }
.cpb-provider__lead { max-width: 60ch; }

.cpb-values {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 24px;
}

.cpb-value {
	display: flex;
	align-items: flex-start;
	gap: 16px;
}

.cpb-value__text {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.cpb-value__text p {
	font: var(--type-small);
	color: var(--text-muted);
}

/* 4.5 Process band */
.cpb-main .cpb-process__head {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: space-between;
	gap: 40px;
	margin-bottom: 64px;
}

.cpb-process__head .cpb-heading { max-width: 620px; }

.cpb-main .cpb-steps {
	display: grid;
	margin: 0;
	padding: 0;
	list-style: none;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	grid-auto-rows: 1fr;
	gap: 40px;
}

.cpb-step {
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding-top: 24px;
	border-top: 1px solid var(--border-on-inverse);
}

.cpb-main .cpb-step .cpb-h3 { color: var(--cream-100); }

.cpb-step__num {
	font: var(--type-eyebrow);
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--forest-200);
}

.cpb-step p:last-child {
	font: var(--type-small);
	color: var(--forest-100);
}

/* 4.6 Payment */
.cpb-payment {
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 48px;
}

.cpb-payment__copy {
	display: flex;
	flex-direction: column;
	gap: 12px;
	max-width: 58ch;
}

/* 4.7 Patient reviews — conditional pattern, not inserted until consent is on file. */
.cpb-reviews__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 20px;
}

.cpb-review { gap: 20px; }

.cpb-review__stars {
	display: inline-flex;
	gap: 3px;
	font-size: 16px;
	line-height: 1;
	/* Round 3c disposition: star glyphs are graphics (WCAG 1.4.11, 3:1). gold-500 fails
	   (2.59:1 white); gold-600 passes (3.65:1 white, 3.32:1 cream-100). Final, not a patch. */
	color: var(--gold-600);
}

.cpb-review__quote {
	font: 400 17px/1.55 var(--font-display);
	color: var(--text-body);
}

.cpb-review__date {
	margin-top: auto;
	font: 400 13px/1.55 var(--font-sans);
	color: var(--text-muted);
}

.cpb-reviews__disclaimer {
	max-width: 72ch;
	margin: 32px auto 0;
	font: 400 13px/1.55 var(--font-sans);
	color: var(--text-muted);
	text-align: center;
}

/* 4.8 Crisis & support resources */
.cpb-resources__grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 20px;
	/*
	 * Ruling 418: equal card height is ENFORCED here, not left to coincidence. The four cards
	 * used to measure the same only because their content happened to be the same height — and
	 * not even always: at 320 they were 249 / 225 / 288 / 225, because SAMHSA's note wraps.
	 * Ruling 417 gave card 1 a third action, which would otherwise leave a 52px ragged edge
	 * between the rows at 768 and 960. This makes explicit what the cards only ever had by
	 * accident, so no card is ever stretched by a taller neighbour in another row.
	 */
	grid-auto-rows: 1fr;
}

/* Ruling 206: the card is a container; its actions are the links. Every action is at least
   44 × 44 CSS px. The first action (call or text) is the largest target. */
.cpb-resource__note {
	font: var(--type-small);
	color: var(--text-muted);
}

.cpb-resource__actions {
	display: flex;
	flex-direction: column;
	gap: 4px;
	margin-top: auto;
}

.cpb-resource__action {
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 44px;
	font: var(--type-label);
	color: var(--brand);
	text-decoration: none;
}

.cpb-resource__action--call,
.cpb-resource__action--text {
	min-height: 48px;
	padding: 10px 16px;
	border: 1px solid var(--forest-200);
	border-radius: var(--radius-pill);
	background: var(--brand-soft);
	font-size: 16px;
}

.cpb-resource__action--call:hover,
.cpb-resource__action--text:hover {
	border-color: var(--brand);
}

.cpb-nowrap { white-space: nowrap; }

.cpb-resource__action--web {
	font: var(--type-button);
	letter-spacing: .04em;
}

.cpb-resource__action--web:hover { color: var(--text-link-hover); text-decoration: underline; }

/* ==========================================================================
   10. Footer
   ========================================================================== */

.cpb-footer {
	padding: 96px var(--gutter) 32px;
	background: var(--forest-700);
	color: var(--forest-100);
}

.cpb-footer__grid {
	display: grid;
	grid-template-columns: minmax(220px, 1.1fr) repeat(auto-fit, minmax(150px, 1fr));
	gap: 48px;
	max-width: var(--container-max);
	margin-inline: auto;
	padding-bottom: var(--gutter);
}

.cpb-footer__brand {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.cpb-footer__brand img {
	width: 64px;
	height: auto;
}

.cpb-footer__tagline {
	max-width: 260px;
	font: var(--type-small);
	color: var(--forest-100);
}

.cpb-footer__contact {
	display: flex;
	flex-direction: column;
	gap: 8px;
	font: var(--type-small);
}

.cpb-footer__col {
	display: flex;
	flex-direction: column;
	gap: 16px;
	min-width: 0;
}

.cpb-site-footer .cpb-footer__heading {
	font: var(--type-eyebrow);
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--forest-200);
}

.cpb-footer__links {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
	font: var(--type-small);
}

.cpb-footer a {
	color: var(--forest-100);
	text-decoration: none;
}

.cpb-footer a:hover {
	color: var(--cream-100);
	text-decoration: underline;
}

.cpb-footer__contact a { color: var(--cream-100); }
.cpb-footer :focus-visible { outline-color: var(--cream-100); }

.cpb-footer__legal {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 16px;
	max-width: var(--container-max);
	margin: 64px auto 0;
	padding-top: 24px;
	border-top: 1px solid var(--border-on-inverse);
	font: 400 13px/1.55 var(--font-sans);
	color: var(--forest-200);
}

.cpb-site-footer .cpb-footer__legal p { color: var(--forest-200); }

.cpb-footer__legal .cpb-footer__credit a {
	color: var(--cream-100);
	/* Underlined so the link is distinguishable from the surrounding sentence without
	   colour alone (axe link-in-text-block / Lighthouse Accessibility 100). */
	text-decoration: underline;
	text-decoration-color: rgba(247, 244, 236, .45);
}

.cpb-footer__policies {
	display: flex;
	gap: 20px;
}

.cpb-footer__policies a { color: var(--forest-200); }

/* ==========================================================================
   11. Interior template — Services package §3.1–§3.3, inherited by About,
       Our Story and Working With Us
   ========================================================================== */

:root {
	/* Clears the 38px crisis strip + ~84px nav + 2px rail with breathing room. */
	--cpb-anchor-offset: 160px;
}

.admin-bar {
	--cpb-anchor-offset: calc(160px + var(--wp-admin--admin-bar--height, 32px));
}

.cpb-page-hero { padding-block: 80px; }

.cpb-page-hero__copy {
	display: flex;
	flex-direction: column;
	gap: 20px;
	max-width: 760px;
}

.cpb-main .cpb-h1 {
	font: 400 50px/1.2 var(--font-display);
	letter-spacing: -.01em;
	color: var(--text-heading);
}

.cpb-main .cpb-page-hero__actions { margin-top: 16px; }

/* --text-subtle is retired as a text role (round 2 ruling): stone-500 fails AA on every
   ground. Breadcrumb and review dates bind to --text-muted permanently. */
.cpb-breadcrumb {
	margin-bottom: 8px;
	font: 400 13px/1.55 var(--font-sans);
	color: var(--text-muted);
}

.cpb-breadcrumb ol {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.cpb-breadcrumb li {
	display: flex;
	align-items: center;
	gap: 8px;
}

.cpb-breadcrumb a { color: inherit; }
.cpb-breadcrumb a:hover { color: var(--text-link-hover); }

.cpb-breadcrumb [aria-current] {
	font-weight: 500;
	color: var(--wp--preset--color--stone-800);
}

.cpb-interior {
	display: grid;
	/* The content column caps so rail + gap + content never exceed --container-rail. The unit
	   stays left-anchored to the site container, so the rail lines up with the logo and with
	   the full-width bands above and below it. */
	grid-template-columns: 220px minmax(0, calc(var(--container-rail) - 220px - 64px));
	gap: 64px;
	align-items: start;
}

.cpb-interior__rail {
	position: sticky;
	top: var(--cpb-anchor-offset);
}

.cpb-toc {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.cpb-toc ul {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.cpb-toc a {
	font: var(--type-body);
	color: var(--text-link);
	text-decoration: none;
}

.cpb-toc a:hover {
	color: var(--text-link-hover);
	text-decoration: underline;
}

.cpb-interior__blocks {
	display: flex;
	flex-direction: column;
	gap: 128px;
	min-width: 0;
}

.cpb-block {
	display: flex;
	flex-direction: column;
	gap: 32px;
}

.cpb-block,
.cpb-payment-band {
	scroll-margin-top: var(--cpb-anchor-offset);
}

.cpb-textgroup {
	display: flex;
	flex-direction: column;
	gap: 20px;
	max-width: 68ch;
}

.cpb-media--16x9 { aspect-ratio: 16 / 9; }
.cpb-media--1x1 { aspect-ratio: 1; }
.cpb-media--4x3 { aspect-ratio: 4 / 3; }

/* Static map frame — a link out to directions, never an embed (Locations README §3.3). */
a.cpb-map { text-decoration: none; }
a.cpb-map:hover .cpb-media__label { color: var(--text-link-hover); }

.cpb-panel {
	gap: 20px;
	max-width: 68ch;
}

.cpb-rows {
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.cpb-rows--loose { gap: 24px; }
.cpb-rows--measure { max-width: 68ch; }

.cpb-row {
	display: flex;
	align-items: flex-start;
	gap: 16px;
}

.cpb-row__text {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

/* Who we work with — three outline cards. Not links, so they do not lift. */
.cpb-cards-3 {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 20px;
}

.cpb-soft-row {
	flex-direction: row;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 40px;
}

.cpb-soft-row {
	/* Ruling D-07: side by side while the sentence keeps a readable measure; stack once
	   it would narrow below ~45ch. flex-basis is that floor (45ch of text + the 36px icon
	   column), so the pill wraps below instead of squeezing the sentence. */
	--cpb-soft-copy-max: 58ch;
}

.cpb-soft-row .cpb-icon-line {
	flex: 1 1 calc(45ch + 36px);
	max-width: var(--cpb-soft-copy-max);
}

.cpb-soft-row .wp-block-buttons { flex: 0 0 auto; }
.cpb-soft-row--narrow { max-width: 68ch; --cpb-soft-copy-max: 48ch; }
.cpb-soft-row--story { max-width: 68ch; --cpb-soft-copy-max: 46ch; }

.cpb-icon-line {
	display: flex;
	align-items: flex-start;
	gap: 16px;
	color: var(--forest-600);
}

.cpb-icon-line::before { margin-top: 2px; }

/* Four questions to ask your plan — numerals are text, not list markers. */
.cpb-numbered {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.cpb-numbered__row {
	display: flex;
	align-items: flex-start;
	gap: 16px;
}

.cpb-numbered__num {
	flex: 0 0 20px;
	font: var(--type-label);
	line-height: 1.55;
	color: var(--text-eyebrow);
}

/* Steps on a light ground (Working With Us) — StepCard default tone, 2 × 2. */
.cpb-main .cpb-steps.cpb-steps--2 {
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 32px;
}

.cpb-steps--light .cpb-step { border-top-color: var(--border-hairline); }
.cpb-steps--light .cpb-step__num { color: var(--text-eyebrow); }
.cpb-main .cpb-steps--light .cpb-step .cpb-h3 { color: var(--text-heading); }
.cpb-steps--light .cpb-step p:last-child { color: var(--text-muted); }

/* Common questions — open on load, never an accordion. */
.cpb-qa-list {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

.cpb-qa {
	display: flex;
	flex-direction: column;
	gap: 8px;
	max-width: 68ch;
	padding-top: 20px;
	border-top: 1px solid var(--border-hairline);
}

/* Closing CTA band — the page's single forest band. */
.cpb-cta-band { padding-block: 80px; }

.cpb-cta-band__row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 48px;
}

.cpb-cta-band__copy {
	display: flex;
	flex-direction: column;
	gap: 16px;
	max-width: 46ch;
}

.cpb-cta-band a {
	color: var(--cream-100);
	text-decoration-color: rgba(247, 244, 236, .55);
}

.cpb-cta-band a:hover { color: var(--white); }
.cpb-cta-band :focus-visible { outline-color: var(--cream-100); }

/* ==========================================================================
   11b. Location pages (Aspen / Carbondale) and Our Story
   ========================================================================== */

.cpb-band-80 { padding-block: 80px; }

.cpb-split {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
	gap: 64px;
	align-items: center;
}

.cpb-split--even { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Ruling 260: a split whose media slot is hidden (one child) becomes a single column. */
.cpb-split:not(:has(> :nth-child(2))) { grid-template-columns: minmax(0, 1fr); }
.cpb-split--start { align-items: start; }

.cpb-maxch-24 { max-width: 24ch; }
.cpb-maxch-46 { max-width: 46ch; }
.cpb-actions--pt { padding-top: 8px; }
.cpb-actions--20 { gap: 20px; }

.cpb-offices a {
	color: var(--cream-100);
	text-decoration-color: rgba(247, 244, 236, .45);
}

.cpb-offices a:hover { color: var(--white); }
.cpb-offices :focus-visible,
.cpb-bg-forest :focus-visible { outline-color: var(--cream-100); }

.cpb-detail {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding-top: 20px;
	border-top: 1px solid var(--border-hairline);
}

.cpb-detail__name {
	font: var(--type-label);
	color: var(--text-heading);
}

/* Community chips — real place names, never links (Chip tone="brand"). */
.cpb-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin: 0;
	padding: 8px 0 0;
	list-style: none;
}

.cpb-chip {
	display: inline-flex;
	align-items: center;
	padding: 6px 14px;
	border: 1px solid var(--forest-200);
	border-radius: var(--radius-pill);
	background: var(--brand-soft);
	color: var(--forest-700);
	font: var(--type-small);
	letter-spacing: .04em;
}

.cpb-bg-forest .cpb-textlink--inverse a { color: var(--cream-100); }
.cpb-bg-forest .cpb-textlink--inverse a:hover { color: var(--white); }

.cpb-card--inverse {
	background: var(--forest-800);
	border-color: var(--border-on-inverse);
	color: var(--forest-100);
}

.cpb-main .cpb-card--inverse .cpb-h3 { color: var(--cream-100); }
.cpb-card--inverse .cpb-body { color: var(--forest-100); }
.cpb-card--inverse .cpb-small { color: var(--forest-200); }

.cpb-icon-line--title {
	align-items: center;
	gap: 12px;
	color: var(--cream-100);
}

.cpb-icon-line--title::before { margin-top: 0; }

/* Our Story — mission and vision as pull statements, not headings. */
.cpb-statements {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 64px;
	align-items: start;
}

.cpb-main .cpb-statement-quote {
	max-width: 32ch;
	font: 400 32px/1.25 var(--font-display);
	letter-spacing: -.01em;
	color: var(--cream-100);
}

.cpb-values--2 {
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 24px;
}

.cpb-cta-band__copy--48 { max-width: 48ch; }

/* ==========================================================================
   11c. Contact — form, states, direct-contact column; About — credentials list
   ========================================================================== */

.cpb-split--form { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }
.cpb-heading--54 { max-width: 54ch; margin-bottom: 48px; }
.cpb-measure { max-width: 68ch; }
.cpb-values--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }

.cpb-loc-card { gap: 12px; }
.cpb-loc-card .cpb-h3 { margin-top: -4px; }

/* Credentials: a definition list, not icon rows (About README §3.3). */
.cpb-dl { display: flex; flex-direction: column; gap: 20px; margin: 0; }

.cpb-dl__row {
	display: grid;
	grid-template-columns: 180px minmax(0, 1fr);
	gap: 24px;
	padding-top: 20px;
	border-top: 1px solid var(--border-hairline);
}

.cpb-dl dt { font: var(--type-label); color: var(--text-heading); }
.cpb-dl dd { margin: 0; font: var(--type-body); color: var(--text-body); }

/* --- The form ------------------------------------------------------------ */

.cpb-form {
	gap: 24px;
	scroll-margin-top: var(--cpb-anchor-offset);
}

.cpb-form__head { display: flex; flex-direction: column; gap: 12px; }
.cpb-form__note { display: flex; flex-direction: column; gap: 16px; }
.cpb-form__guidance { gap: 12px; padding: 28px; }

.cpb-field {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.cpb-label {
	font: var(--type-label);
	color: var(--text-heading);
}

.cpb-field__req { color: var(--danger-600); }

.cpb-field__hint,
.cpb-form__footnote {
	font: 400 13px/1.55 var(--font-sans);
	color: var(--text-muted);
}

.cpb-field__error {
	font: 400 13px/1.55 var(--font-sans);
	color: var(--danger-600);
}

.cpb-input {
	width: 100%;
	padding: 13px 16px;
	border: 1px solid var(--wp--preset--color--stone-400);
	border-radius: 8px;
	background: var(--white);
	color: var(--text-heading);
	font: var(--type-body);
	outline: none;
	transition:
		border-color 160ms var(--ease-out),
		box-shadow 160ms var(--ease-out);
}

.cpb-input:focus,
.cpb-input:focus-visible {
	border-color: var(--focus-ring);
	box-shadow: var(--shadow-focus);
	outline: 2px solid transparent;
}

.cpb-input[aria-invalid="true"] { border-color: var(--danger-600); }
.cpb-textarea { line-height: 1.55; resize: vertical; }

.cpb-select {
	appearance: none;
	cursor: pointer;
	padding-right: 40px;
	background-image:
		linear-gradient(45deg, transparent 50%, var(--forest-600) 50%),
		linear-gradient(135deg, var(--forest-600) 50%, transparent 50%);
	background-position: calc(100% - 22px) calc(50% + 1px), calc(100% - 16px) calc(50% + 1px);
	background-size: 6px 6px, 6px 6px;
	background-repeat: no-repeat;
}

/* Pills: a real radio, visually hidden, with the pill drawn on the sibling span. The focus
   ring MUST be drawn on that sibling or the control is invisible to keyboard users. */
.cpb-pills {
	display: flex;
	flex-direction: column;
	gap: 8px;
	margin: 0;
	padding: 0;
	border: 0;
}

.cpb-pills legend { padding: 0; margin-bottom: 8px; }
.cpb-pills__row { display: flex; flex-wrap: wrap; gap: 12px; }
.cpb-pill { display: inline-flex; align-items: center; cursor: pointer; }

.cpb-pill input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	opacity: 0;
}

.cpb-pill span {
	padding: 11px 20px;
	border: 1px solid var(--brand);
	border-radius: var(--radius-pill);
	background: var(--white);
	color: var(--brand);
	font: var(--type-button);
	font-size: 15px;
	letter-spacing: .04em;
	transition: background-color 160ms var(--ease-out), color 160ms var(--ease-out);
}

.cpb-pill input:checked + span {
	background: var(--brand);
	color: var(--cream-100);
}

.cpb-pill input:focus-visible + span,
input[type="radio"]:focus-visible + span,
input[type="checkbox"]:focus-visible + span {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

/* Error summary. No motion: no shake, no slide, no animated scroll (INP budget 0ms). */
.cpb-form__alert {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 20px;
	border-radius: var(--radius-card);
	background: var(--wp--preset--color--danger-100);
}

.cpb-form__alert:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.cpb-form__alert-title { font: var(--type-label); color: var(--danger-600); }
.cpb-form__alert ul { margin: 0; padding-left: 20px; }

.cpb-form__submit {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
}

.cpb-form__footnote { max-width: 58ch; }

/* Honeypot: off-screen, never display:none — some bots check for it. */
.cpb-form__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.cpb-form__sent-head { display: flex; align-items: center; gap: 16px; }

.cpb-well--success {
	width: 48px;
	height: 48px;
	background: var(--wp--preset--color--success-100);
	color: var(--wp--preset--color--success-600);
}

.cpb-well--success::before { width: 22px; height: 22px; }
.cpb-form__again { margin-top: 4px; }

/* ==========================================================================
   11d. Book — the booking module. Selection changes are colour and border only:
        no travel, no scale, no reflow (Book README §6).
   ========================================================================== */

.cpb-book {
	display: grid;
	grid-template-columns: minmax(0, 1.2fr) minmax(0, .8fr);
	gap: 64px;
	align-items: start;
}

.cpb-book__steps { display: flex; flex-direction: column; gap: 64px; min-width: 0; }

.cpb-book__step {
	display: flex;
	flex-direction: column;
	gap: 20px;
	margin: 0;
	padding: 0;
	border: 0;
	min-width: 0;
}

.cpb-book__legend { display: flex; flex-direction: column; gap: 8px; padding: 0; }

/* A fieldset's rendered legend sits outside the flex layout, so the step's gap skipped it in
   steps one and two. Floating it makes it an ordinary flex item (the float itself is ignored). */
fieldset.cpb-book__step > .cpb-book__legend { float: left; width: 100%; }
.cpb-book__legend .cpb-eyebrow { display: block; }
.cpb-book__patient { display: flex; flex-direction: column; gap: 12px; }
.cpb-book__patient .cpb-pill span { padding: 13px 24px; }
.cpb-book__intro { max-width: 62ch; }

.cpb-book__offices {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 20px;
}

/* Office cards: a visually hidden radio + a styled sibling (focus ring drawn on the span). */
.cpb-choice { display: flex; height: 100%; cursor: pointer; }

.cpb-choice input {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: 0;
	opacity: 0;
}

.cpb-choice__card {
	display: flex;
	flex: 1;
	flex-direction: column;
	gap: 8px;
	padding: 28px;
	border: 1px solid var(--border-hairline);
	border-radius: var(--radius-card);
	background: var(--white);
	transition: background-color 160ms var(--ease-out), border-color 160ms var(--ease-out);
}

.cpb-choice__title { display: flex; align-items: center; gap: 12px; color: var(--forest-600); }
.cpb-choice__body { font: var(--type-small); color: var(--text-muted); }

.cpb-choice input:checked + .cpb-choice__card {
	background: var(--forest-700);
	border-color: var(--forest-700);
}

.cpb-choice input:checked + .cpb-choice__card .cpb-choice__title,
.cpb-main .cpb-choice input:checked + .cpb-choice__card .cpb-h4 { color: var(--cream-100); }
.cpb-choice input:checked + .cpb-choice__card .cpb-choice__body { color: var(--forest-100); }

.cpb-choice input:focus-visible + .cpb-choice__card {
	outline: 2px solid var(--focus-ring);
	outline-offset: 2px;
}

/* Rows: a grid, not a wrapping flex row, so every action keeps its own column. */
.cpb-book__list { display: flex; flex-direction: column; gap: 16px; }

.cpb-appt {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	gap: 32px;
}

.cpb-appt__text { display: flex; flex-direction: column; gap: 8px; }
.cpb-appt__title { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.cpb-appt__action { display: flex; flex-direction: column; gap: 8px; }
.cpb-appt .cpb-chips { padding: 0; }

.cpb-chip--neutral {
	border-color: var(--border-hairline);
	background: var(--cream-200);
	color: var(--text-body);
}

.cpb-book__footnote {
	max-width: 64ch;
	font: 400 13px/1.55 var(--font-sans);
	color: var(--text-muted);
}

.cpb-book__side { gap: 12px; }
.cpb-book__phone a { font: 400 26px/1.25 var(--font-display); }
/* Heading-plus-cards bands (Book "before", Contact "next"): 20px between the heading, the cards
   and the actions. Scoped with :has() because the same wrapper classes sit on single-child bands
   and on bands whose spacing is already set. The actions keep 48px in total above them. */
.cpb-inner.cpb-reveal:has(> .cpb-heading--54) {
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.cpb-main .cpb-book__after { margin-top: 28px; }

/* The office and patient selections, without JavaScript. Where :has() is unsupported every
   variant stays visible — longer, never broken. */
@supports selector(:has(*)) {
	.cpb-book-band:has(input[name="cpbmd_book_office"][value="aspen"]:checked) [data-office="carbondale"],
	.cpb-book-band:has(input[name="cpbmd_book_office"][value="carbondale"]:checked) [data-office="aspen"],
	.cpb-book-band:has(input[name="cpbmd_book_patient"][value="new"]:checked) [data-patient="returning"],
	.cpb-book-band:has(input[name="cpbmd_book_patient"][value="returning"]:checked) [data-patient="new"],
	.cpb-book-band:has(input[name="cpbmd_book_patient"][value="returning"]:checked) [data-new-only] {
		display: none;
	}
}

/* ==========================================================================
   12. Generic page template (routes designed in later rounds)
   ========================================================================== */

.cpb-page {
	padding: 80px var(--gutter) var(--section-y);
	background: var(--cream-050);
}

.cpb-page > * {
	max-width: 720px;
	margin-inline: auto;
}

.cpb-main.cpb-page .wp-block-post-title {
	margin-bottom: 24px;
}

/* ==========================================================================
   13. Responsive — the desktop pattern set, reflowed. Mobile 390 comps will refine.
   ========================================================================== */

@media (max-width: 1100px) {
	.cpb-resources__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.cpb-nav__inner { gap: 24px; }
	.cpb-nav__list { gap: 24px; }
}

@media (max-width: 960px) {
	.cpb-nav__inner { flex-wrap: wrap; row-gap: 12px; }
	.cpb-nav__cta { margin-left: auto; }
	.cpb-nav__menu { order: 3; flex-basis: 100%; margin-left: 0; }
	.cpb-nav__list { flex-wrap: wrap; gap: 8px 28px; }

	.cpb-hero__grid,
	.cpb-services__grid,
	.cpb-provider__grid {
		grid-template-columns: minmax(0, 1fr);
		gap: 48px;
	}

	.cpb-hero__media { max-width: 520px; margin-left: 24px; }
	.cpb-portrait { max-width: 360px; }
	.cpb-services__grid > .cpb-media { max-width: 520px; }
	.cpb-main .cpb-steps { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }

	/* Ruling D-08: no mobile rail is designed, so below 960 the "On This Page" rail is
	   hidden (the anchors remain). A collapsed jump menu is post-launch, analytics-led. */
	.cpb-interior { grid-template-columns: minmax(0, 1fr); gap: 0; }
	.cpb-interior__rail { display: none; }
	.cpb-interior__blocks { gap: 96px; }
	.cpb-split,
	.cpb-split--even,
	.cpb-split--form,
	.cpb-book,
	.cpb-statements { grid-template-columns: minmax(0, 1fr); gap: 48px; }
	.cpb-loc-hero .cpb-media { max-width: 520px; }
	:root { --cpb-anchor-offset: 220px; }
	.cpb-reviews__grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 781px) {
	:root {
		--section-y: 64px;
		--section-y-tight: 48px;
	}

	.cpb-hero { padding-block: 48px; }
	.cpb-main .cpb-hero__title { font-size: 38px; }
	.cpb-h2,
	.cpb-main .cpb-h2 { font-size: 32px; }
	.cpb-main .cpb-h1 { font-size: 38px; }
	.cpb-page-hero { padding-block: 48px; }
	.cpb-cta-band,
	.cpb-band-80 { padding-block: 64px; }
	.cpb-main .cpb-statement-quote { font-size: 26px; }
	.cpb-offices__grid,
	.cpb-cards-3,
	.cpb-values--2,
	.cpb-values--3,
	.cpb-services__cards,
	.cpb-loc__inner { grid-template-columns: minmax(0, 1fr); }
	.cpb-crisis__meta { margin-left: 0; }
	.cpb-footer { padding-top: 64px; }
	.cpb-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 24px; }
	.cpb-footer__brand { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
	.cpb-nav__inner { gap: 12px 16px; }
	.cpb-nav__logo img { height: 36px; }
	.cpb-nav__list { justify-content: space-between; gap: 8px 22px; }
	.cpb-resources__grid { grid-template-columns: minmax(0, 1fr); }
	.cpb-main .cpb-steps.cpb-steps--2 { grid-template-columns: minmax(0, 1fr); }
	.cpb-dl__row { grid-template-columns: minmax(0, 1fr); gap: 4px; }
	.cpb-book__offices { grid-template-columns: minmax(0, 1fr); }
	.cpb-appt { grid-template-columns: minmax(0, 1fr); gap: 20px; }
	.cpb-appt__action { align-items: flex-start; }
	/* v1.0 as delivered: the field anchors to the bottom of the hero at a fraction of its
	   height. Held below 961 — see the interim rule under §12. Three contours drop. */
	.cpb-breath {
		top: auto;
		bottom: 0;
		width: auto;
		height: 46%;
		transform: translate(30%, 20%);
	}

	.cpb-breath [data-thin] { display: none; }
	.cpb-card--lg { padding: 28px; }
}

/* The smallest phones (320px): the tighter column gap keeps all four nav items on one row. */
@media (max-width: 350px) {
	.cpb-nav__list { column-gap: 12px; }
}

/* --------------------------------------------------------------------------
   The Breath — two departures from v1.0, both measured, both round 22.

   The requirement is "no contour crosses text" (not the 46% figure). Measured by sampling
   900 points along every visible contour and testing them against the per-line client rects
   of the hero copy, with the animation held at its widest point.

   1. 961–1099px — v1.0's width (78vw) and offset put contours through the h1 and the lead:
      51 crossing samples at 961, 20 at 1024, 9 at 1080, 0 from ~1090 up. Narrowing the field
      and pushing it further right clears it with the largest arc still visible. 1100 and above
      are v1.0 exactly as approved and are untouched.

   2. ≤960px — v1.0's field is hidden here PERMANENTLY, and the block below it (the 46%
      mobile sizing, as delivered) is dead code kept only as a record of what was tried.
      v1.0 sizes the field at 46% of the hero height, verified against a demo shell fixed at
      min-height:100svh. This hero is content-height on mobile (693px at 390), so the field's
      top landed ~255px above the hero's bottom edge and crossed the credential line at 360,
      390, 412 and 560. Clearing it by shrinking alone needed a height near 60px — a sliver,
      not the design.

      Ruling 356 REFUSED a minimum mobile hero height rather than granting it: adding height
      for a decorative graphic would push the crisis strip down the page on the device most
      crisis traffic arrives on. Ruling 384 then cleared a purpose-drawn replacement,
      CPB-2026-01-B2, which is the .cpb-band composition in §9. Do not revive v1.0 here.
   -------------------------------------------------------------------------- */
@media (min-width: 961px) and (max-width: 1099px) {
	.cpb-breath {
		width: clamp(420px, 58vw, 1180px);
		transform: translate(46%, -50%);
	}
}

/* --------------------------------------------------------------------------
   THE 961px BOUNDARY — two rules, two selectors, and BOTH are required (ruling 385).
   They are kept adjacent because 961 now appears twice: if this boundary ever moves,
   both rules move together.

     .cpb-breath  desktop field (1A)  hidden at 960 and below
     .cpb-band    mobile band   (B2)  hidden at 961 and up  — declared in §9

   Delete either one and both compositions paint: drop the first and the desktop field
   returns on every phone; drop the second and the band appears under the desktop field.
   They cannot conflict, because they govern different selectors.
   -------------------------------------------------------------------------- */
@media (max-width: 960px) {
	.cpb-breath { display: none; }
}

@media (min-width: 961px) {
	.cpb-band { display: none; }
}

/* ==========================================================================
   14. Motion — CPB-2026-01-M. Only transform and opacity animate (opacity never on text:
       ruling 286). Base layer is fully visible; every pattern lives inside reduced-motion +
       @supports guards.
   ========================================================================== */

/* P-04 — cross-document page transitions. Firefox navigates normally. Under reduced
   motion the swap is instant (no @view-transition rule applies). */
@media (prefers-reduced-motion: no-preference) {
	@view-transition {
		navigation: auto;
	}
}

/* P-03 continuity register (CONTINUITY-MAP.md) — theme-level names, live on every page. */
.cpb-nav__logo img { view-transition-name: vt-logo; }
.cpb-nav__cta { view-transition-name: vt-booking; }
.cpb-crisis { view-transition-name: vt-crisis; }

/* vt-crisis is named for continuity only and carries no animation: the new snapshot
   is shown as-is and the old one is never painted, so nothing on the strip moves. */
::view-transition-group(vt-crisis),
::view-transition-image-pair(vt-crisis),
::view-transition-new(vt-crisis) {
	animation: none;
}

::view-transition-old(vt-crisis) {
	display: none;
}

/* P-01 — The Breath (v1.0): 4-7-8 → inhale 0–21.05%, hold →57.89%, exhale →100% of 19s.
   Amplitude is differential per ring (--breath-min/--breath-max, authored on each contour);
   outer rings travel furthest. Per-phase easing is set here, never in --motion-breath. */
@keyframes cpb-breath {
	0% {
		transform: scale(var(--breath-min, .966));
		animation-timing-function: cubic-bezier(.4, 0, .5, 1);      /* inhale — 4s */
	}
	21.05% {
		transform: scale(var(--breath-max, 1));
		animation-timing-function: linear;                          /* hold — 7s, no travel */
	}
	57.89% {
		transform: scale(var(--breath-max, 1));
		animation-timing-function: cubic-bezier(.3, 0, .3, 1);      /* exhale — 8s, slow release */
	}
	100% { transform: scale(var(--breath-min, .966)); }
}

/* P-02 — scroll-driven reveal: a short rise, once. Ruling 286 (round 17): transform ONLY, no opacity.
   Any text that fades in fails contrast at some scroll position on some screen (Lighthouse caught it
   at the 412×823 fold on /book/ and /our-story/; held at 12% progress every text element in a reveal
   measured 1.16–1.41:1). Do not reintroduce opacity on anything that carries text; a fade is allowed
   only on purely decorative, text-free elements. Also drives P-06 (.cpb-seq). */
@keyframes cpb-reveal {
	from { transform: translateY(14px); }
	to { transform: none; }
}

/* P-07 — reading rail. */
@keyframes cpb-rail {
	from { transform: scaleX(0); }
	to { transform: scaleX(1); }
}

@media (prefers-reduced-motion: no-preference) {
	/* P-01 is no longer driven from here. v1.0 animates the eight contours individually
	   (see §9, .cpb-breath [data-breath]) and deliberately carries no will-change. The old
	   placeholder-frame rule was removed on lift-in; do not reinstate it. */

	@supports (animation-timeline: view()) {
		.cpb-reveal {
			animation: cpb-reveal linear both;
			animation-timeline: view();
			animation-range: entry 5% entry 78%;
		}

		/* P-06 — sequenced entry, genuine sequences only (process steps, Working With Us
		   steps). A card grid is not a sequence. animation-delay does not apply on scroll
		   timelines; stagger by offsetting the range per child, capped at four. */
		.cpb-seq > * {
			animation: cpb-reveal linear both;
			animation-timeline: view();
		}

		.cpb-seq > :nth-child(1) { animation-range: entry 5% entry 70%; }
		.cpb-seq > :nth-child(2) { animation-range: entry 11% entry 76%; }
		.cpb-seq > :nth-child(3) { animation-range: entry 17% entry 82%; }
		.cpb-seq > :nth-child(4) { animation-range: entry 23% entry 88%; }
	}

	@supports (animation-timeline: scroll()) {
		.cpb-rail {
			opacity: 1;
			animation: cpb-rail linear both;
			animation-timeline: scroll(root block);
		}
	}
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		transition-duration: 0s !important;
		animation-duration: 0s !important;
		animation-iteration-count: 1 !important;
	}

	.cpb-rail { display: none; }
	/* Travel goes; P-08 response stays (press, hover colour, focus). */
	.cpb-card--interactive:is(:hover, :focus-within, :focus-visible) { transform: none; }
}
