/* =========================================================
   FOI PRP Landing Page
   Mobile-first. Breakpoints: 768px (tablet), 1080px (desktop).
   ========================================================= */

:root {
	/* Palette — sampled from the published Figma Site */
	/*
	 * Tokens are prefixed --foiprp-, not --foi-.
	 *
	 * "FOI" is the client's own namespace: floridaortho.com's theme declares
	 * its own --foi-* custom properties on :root, including --foi-gutter:
	 * 1.5rem. Two :root declarations of the same name collide, and whichever
	 * stylesheet the page loads last wins — which is why the section gutters
	 * and the footer padding read correctly in isolation but resolved to 24px
	 * on the live site, while rules that did not depend on a token (the call
	 * underline, the footer border) applied fine.
	 *
	 * Prefixing past the collision is what fixes it; do not rename these back.
	 */
	--foiprp-ink:        #242424;
	--foiprp-ink-soft:   #5a5a5a;
	--foiprp-ink-mute:   #6f6f6f;
	--foiprp-line:       #e3ddd0;
	--foiprp-khaki:      #a0997d;
	--foiprp-paper:      #ffffff;
	--foiprp-offwhite:   #f7f7f7;

	/* Page ground. Every section in the design sits on #f7f7f7, not white —
	   confirmed on the Figma canvas and on the published reference, whose body
	   is rgb(247,247,247). --foiprp-paper stays pure white for things that are
	   genuinely raised off the page, like the mobile menu card. */
	--foiprp-page:       #f7f7f7;
	--foiprp-cream:      #f7f0d2;
	--foiprp-bronze:     #997149;
	--foiprp-bronze-dk:  #7d613e;
	--foiprp-blue:       #094a78;
	--foiprp-blue-dk:    #073a5e;

	/* Figma brand blue. Adopted piece by piece — the header pills are still on
	   the older --foiprp-blue until their spec lands. */
	--foiprp-blue-brand: #0b4577;

	/* ClickTab active fill. Deliberately darker than --foiprp-blue-brand: the
	   Figma frame specifies #083459, and the published reference renders the
	   same value. */
	--foiprp-step-active: #083459;

	/* Condition-icon hover accent. Confirmed straight from the supplied icon
	   SVGs, whose accent paths are fill="#0097DC" — the FOI logo blue. (An
	   earlier #4395D6 here was sampled off a scaled screenshot and was wrong.) */
	--foiprp-accent: #0097dc;

	/* Primary CTA ("Schedule an Appointment" / btn-alt in Figma).
	   Scoped to .foi-btn only — the header pills still use --foiprp-blue. */
	--foiprp-btn-bg:      var(--foiprp-blue-brand);
	--foiprp-btn-bg-hover:#09375e;
	/* Figma: color #FFFFFF at opacity 0.9. Applied as an rgba text colour, not
	   `opacity`, so the pill background stays fully opaque. */
	--foiprp-btn-fg:      rgba(255, 255, 255, 0.9);
	/* Ghost button ("btn" in Figma): #000000 at opacity 0.9, same rgba
	   treatment as the primary CTA's label. */
	--foiprp-btn-ghost-fg: rgba(0, 0, 0, 0.9);

	/* Type */
	--foiprp-display: "Instrument Serif", Georgia, serif;
	--foiprp-body:    "DM Sans", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
	--foiprp-alt:     "Outfit", "DM Sans", -apple-system, sans-serif;

	/* Responsive type ramp — lifted from the published reference's own compiled
	   stylesheet, which Figma Sites generates from the same frames. Its media
	   queries change ONLY font-size and letter-spacing; all layout there is
	   absolute frames, so the tablet layout below is ours, not the design's. */
	--foiprp-fs-display: 42px;   /* Joint Pain Therapy / Voices Of Recovery / FAQs */
	--foiprp-fs-heading: 32px;   /* Start Your Journey, 01/02/03, split H3s, quotes */
	--foiprp-fs-subhead: 25px;   /* hero title + lede, card heads, step labels      */
	--foiprp-fs-body:    14px;   /* prose, process note, closing copy               */
	/* 15px, not 13: the mobile frame's CTA is ~250px wide, which only lands
	   with a 15px label inside the 40px padding. */
	--foiprp-fs-btn:     15px;   /* button labels                                   */
	--foiprp-fs-caption: 12px;   /* quote attributions                              */

	/* Rhythm */
	/* Page band. The Figma canvas is 1440 with 80px padding, so the content
	   column is 1280 wide. Shell max-width 1440 + an 80px gutter reproduces
	   that exactly at 1440, and keeps the same 1280 column (centred) above it
	   rather than letting text run to a 1760px measure. */
	/* --foiprp-shell removed: the page has no content cap any more, every
	   section runs to --foiprp-gutter at every width. */
	/* Measured off the reference: every section edge sits 16px from the
	   viewport on the mobile canvas, and 80px from 768 up. */
	--foiprp-gutter:  16px;
	--foiprp-section: 56px;
	--foiprp-radius:  10px;
}

/* ---------- Reset ---------- */

.foi-prp * { box-sizing: border-box; }

.foi-prp {
	margin: 0;
	padding: 0;
	background: var(--foiprp-page);
	color: var(--foiprp-ink);
	font-family: var(--foiprp-body);
	font-size: 16px;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
	overflow-x: hidden;
}

.foi-prp img { max-width: 100%; display: block; }
.foi-prp ul, .foi-prp ol { list-style: none; margin: 0; padding: 0; }
.foi-prp a { color: inherit; text-decoration: none; }
.foi-prp button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.foi-prp h1, .foi-prp h2, .foi-prp h3, .foi-prp p, .foi-prp figure, .foi-prp blockquote { margin: 0; }

.foi-visually-hidden,
.foi-skip:not(:focus) {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

.foi-skip:focus {
	position: fixed;
	top: 8px; left: 8px;
	z-index: 999;
	background: var(--foiprp-ink);
	color: #fff;
	padding: 10px 16px;
	border-radius: 6px;
}

.foi-prp :focus-visible {
	outline: 2px solid var(--foiprp-bronze);
	outline-offset: 3px;
}

/* ---------- Layout primitives ---------- */

/* ONE column for the whole page.

   There used to be three: no cap on the header/hero/footer, 1440 on the shell,
   and 1280 on .foi-shell--narrow. Below 1281px all three collapse onto the
   gutter and agree, which is why this never showed up in testing — but from
   1281px they fan out. At 1440 the header logo sat on the 80px gutter while
   the FAQ heading sat at 160; at 1920 the page ran three different gutters at
   once (80 / 320 / 400). A cap is what creates that space, incidentally, not
   the `margin: 0 auto` — the auto margin only decides where the leftover goes.
   
   So there is no cap now. Every section starts and ends exactly one gutter
   from the viewport edge at every width, which is what the header and footer
   already did. --foiprp-gutter is the single knob: 16 / 60 / 80. */
.foi-shell {
	width: 100%;
	max-width: none;
	margin: 0 auto;
	padding-inline: var(--foiprp-gutter);
}

/* Kept as a no-op so the class can stay in the markup: the narrow band it used
   to describe is gone. Delete the class from the template when convenient. */
.foi-shell--narrow { max-width: none; }

.foi-h2 {
	font-family: var(--foiprp-display);
	font-weight: 400;
	font-size: clamp(1.9rem, 5vw, 3rem);
	line-height: 1.15;
	letter-spacing: -0.01em;
}

.foi-h3 {
	font-family: var(--foiprp-display);
	font-weight: 400;
	font-size: clamp(1.4rem, 3.4vw, 2rem);
	line-height: 1.2;
}

/* ---------- Buttons ---------- */

.foi-btn {
	display: inline-block;
	background: var(--foiprp-btn-bg);
	color: var(--foiprp-btn-fg);
	font-family: var(--foiprp-body);
	font-size: var(--foiprp-fs-btn);
	font-weight: 700;
	/* 90% of 19px = 17.1px. Without this the button inherits the global 1.6
	   line-height (30.4px) and stands 64px tall instead of ~51px. */
	line-height: 0.9;
	letter-spacing: -0.03em;
	text-align: center;
	padding: 14px 40px;
	border-radius: 999px;
	transition: background 0.18s ease;
}

.foi-btn:hover { background: var(--foiprp-btn-bg-hover); }

.foi-btn--sm { padding: 9px 18px; font-size: 0.78rem; }

/* The ghost button's Figma spec is DM Sans 300 / 90% / -0.03em. It used to
   inherit all of that from .foi-btn, until .foi-btn was pinned to 700 so the
   solid "Schedule an Appointment" CTA could be bold — which quietly dragged
   these four card buttons bold with it. The weight is stated here again so the
   two are independent: solid CTAs bold, ghost buttons light, as designed. */
.foi-btn--ghost {
	font-weight: 300;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	color: var(--foiprp-btn-ghost-fg);
	border: 0.75px solid #000000;
	border-radius: 999px;
	padding: 15px 30px;
	font-size: var(--foiprp-fs-btn);
	line-height: 0.9;
	transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

/* Hover fills with the brand blue, so the ghost resolves into the same
   treatment as the primary CTA rather than the old bronze.

   Background AND border take the same colour, so the pill is one solid shape
   with no second edge anywhere. QA BUG-012 was two separate causes stacked on
   this button: a scaled pseudo-element drawing the outline 1px inside the fill
   (now gone — the border is an ordinary border again), and the fill-in being
   animated, which is what the zero duration below addresses. */
.foi-btn--ghost:hover {
	background: var(--foiprp-btn-bg);
	border-color: var(--foiprp-btn-bg);
	color: var(--foiprp-btn-fg);

	/*
	 * Fill instantly on the way in.
	 *
	 * The border animates black -> blue while the background animates
	 * transparent -> blue. Both land on the same colour, but they start from
	 * different ones, so for the length of the transition the outline is
	 * opaque and dark while the fill is still half-transparent: a dark rim
	 * around a pale interior, which reads as a gap at the pill's edge before
	 * the background "catches up". No shared duration avoids it — the two
	 * curves simply do not meet until the end.
	 *
	 * The hover-OUT still uses the 0.18s ease from the base rule, because that
	 * direction has no mismatch to expose: the fill fades away under a border
	 * that is already the same colour. Delete this line to get the old
	 * behaviour back and see the rim for yourself.
	 */
	transition-duration: 0s;
}

/* Button text colours, hardened so a theme's global <a> colour can't win.
   (Single-class .foi-btn rules lose to theme selectors like `.entry-content a`.) */
.foi-prp a.foi-btn { color: var(--foiprp-btn-fg); }
.foi-prp a.foi-btn--ghost { color: var(--foiprp-btn-ghost-fg); }
.foi-prp a.foi-btn--ghost:hover { color: var(--foiprp-btn-fg); }

/* Button and call line travel together. Without this wrapper each was a
   separate child of the section, so the section's own flex gap (60px in the
   process block, 30px in the closing block) was added to the call line's
   margin and the spacing came out at 90px and 60px instead of 30px. */
.foi-ctastack {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 30px;
	align-self: center;
}

/* Scoped to beat `.foi-prp a.foi-call` (0,2,1), which carries the 30px
   default — the stack's own gap is what spaces these two. */
.foi-prp .foi-ctastack a.foi-call { margin-top: 0; }

/* Hero: the stack hugs the right edge with the rest of the hero copy, but the
   call line centres on the button inside it, as the design shows. 20px here
   plus the copy wrapper's 10px gap is the 30px below the sub-line. */
.foi-ctastack--hero {
	gap: 10px;
	align-self: flex-end;
	margin-top: 20px;
}

/* ---------- "Call 813-615-8825", under every Schedule button ----------

   Scoped past the reset's `.foi-prp a` colour rules. The hero sits on the
   photograph so its copy is white; the process and closing sections are on
   light grounds, so those take the ink colour. The gap to the button above is
   10px in the hero and 30px everywhere else, per the design. */
.foi-prp a.foi-call {
	display: block;
	width: fit-content;
	font-family: var(--foiprp-body);
	font-size: 17px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: -0.01em;
	/* Brand blue, matching the button above it. The hero overrides this to
	   white, since it sits on the photograph. */
	color: #0B4577;
	/* Plain, inert text by default — see the media query below. */
	text-decoration: none;
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
	pointer-events: none;
	cursor: default;
	margin-top: 30px;
}

/* Click-to-dial is switched on for TOUCH DEVICES, not for narrow windows.
   Width was the wrong test: a laptop at a small window size — or this page
   inside a preview frame at a phone preset — matched it, so the dial link went
   live on a machine with no dialer. The browser then prompted to choose an app
   and nothing happened when it was allowed, because nothing is registered.

   `hover: none` plus `pointer: coarse` is true for phones and tablets and
   false for anything driven by a mouse or trackpad, whatever the window size.
   The href stays in the markup either way, so the number is machine-readable
   and still dials if the same page is opened on a phone. */
@media ( hover: none ) and ( pointer: coarse ) {
	.foi-prp a.foi-call {
		pointer-events: auto;
		cursor: pointer;
		/* The underline is what signals "tappable" where there is no hover. */
		text-decoration: underline;
	}
}

/* Hero: white on the photograph, 10px below the button, and hard right with
   the rest of the hero copy. */
.foi-prp a.foi-call--hero { color: #ffffff; }



/* ---------- Image placeholder ---------- */

.foi-img-placeholder {
	width: 100%;
	height: 100%;
	min-height: 220px;
	display: flex;
	align-items: center;
	justify-content: center;
	background:
		repeating-linear-gradient(
			45deg,
			var(--foiprp-cream),
			var(--foiprp-cream) 12px,
			var(--foiprp-line) 12px,
			var(--foiprp-line) 24px
		);
	color: var(--foiprp-ink-soft);
	font-size: 0.72rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
}

/* =========================================================
   HEADER — transparent, overlays the hero
   ========================================================= */

.foi-header {
	position: absolute;
	left: 0; right: 0;
	z-index: 50;
	padding-block: 25px 0;
}

.foi-header__inner {
	position: relative;   /* positioning context for the mobile menu panel */
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
}

.foi-logo { display: block; flex: none; }

.foi-logo img {
	width: 150px;
	height: auto;
}

/* No burger at any width — all three Figma canvases (desktop, tablet, mobile)
   show the three nav links inline beside the logo, and so does the published
   reference at 390px. The off-canvas panel that used to live here is gone
   with it. */

.foi-header__right {
	display: flex;
	align-items: center;
}

.foi-header__utility {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}

.foi-prp .foi-lang {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 17px;
	color: var(--foiprp-ink);
}

.foi-lang svg { width: 11px; height: 11px; }

/* Scoped past `.foi-prp button` in the reset, which would otherwise
   strip the background right back off. */
.foi-prp .foi-pill {
	display: inline-block;
	background: var(--foiprp-blue);
	color: #fff;
	font-family: var(--foiprp-body);
	font-size: 17px;
	font-weight: 400;
	line-height: 1.2;
	padding: 11px 20px;
	border: 0;
	border-radius: 10px;
	cursor: pointer;
	transition: background 0.18s ease;
}

.foi-prp .foi-pill:hover { background: var(--foiprp-blue-dk); }

.foi-search { position: relative; flex: 1; min-width: 160px; }

.foi-search input {
	width: 100%;
	padding: 11px 44px 11px 20px;
	font-family: var(--foiprp-body);
	font-size: 17px;
	line-height: 1.2;
	color: var(--foiprp-ink);
	background: transparent;
	border: 1px solid var(--foiprp-line);
	border-radius: 10px;
}

.foi-search input::placeholder { color: var(--foiprp-ink-mute); }

.foi-search svg {
	position: absolute;
	right: 15px; top: 50%;
	transform: translateY(-50%);
	width: 18px; height: 18px;
	color: var(--foiprp-ink);
	pointer-events: none;
}

.foi-nav ul { display: flex; align-items: center; gap: 10px; }

/* The three header items are buttons, not plain links — same pill as the
   primary CTA so the header reads as one system with the hero. */
.foi-nav a {
	display: flex;
	align-items: center;
	gap: 6px;
	/* Design: 15px 25px padding, 45px tall, #0B4577, 7px radius — a rounded
	   rectangle, not the pill the CTA buttons use. The 15px line-height is
	   what makes 15 + 15 + 15 come out at the specified 45. */
	padding: 15px 25px;
	background: var(--foiprp-btn-bg);
	border-radius: 7px;
	font-family: var(--foiprp-body);
	font-size: 17px;
	font-weight: 700;
	line-height: 15px;
	letter-spacing: -0.01em;
	color: var(--foiprp-btn-fg);
	white-space: nowrap;
	border: 0;
	transition: background 0.18s ease;
}

.foi-prp .foi-nav a { color: var(--foiprp-btn-fg); }
.foi-nav a:hover { background: var(--foiprp-btn-bg-hover); }

.foi-nav a svg { width: 11px; height: 11px; }

/* The links no longer share the row with the wordmark below 768 — they stack
   inside the menu panel — so only the wordmark still needs trimming here. */
@media ( max-width: 379px ) {
	.foi-logo img { width: 118px; }
}

/* =========================================================
   MOBILE MENU
   =========================================================

   Below 768 the three header buttons collapse behind a burger and stack full
   width beneath the bar. From 768 up they sit inline and the burger is gone,
   so everything here is scoped to the phone range. */

.foi-burger {
	display: none;
	width: 44px;
	height: 44px;
	padding: 0;
	background: none;
	border: 0;
	cursor: pointer;
	align-items: center;
	justify-content: center;
	flex: none;
}

/* Scoped past the reset's `.foi-prp button { color: inherit }` (0,1,1), which
   a bare .foi-burger (0,1,0) loses to — the bars take currentColor, so without
   this the icon inherits the dark page ink instead of sitting white on the
   hero photograph. Both the bars and the cross come from this one value. */
.foi-prp .foi-burger { color: #ffffff; }

/* Three bars from one element: the middle is the box's own background, the
   outer two are pseudo-elements offset above and below. On open the middle
   fades out and the outer pair rotate onto the centre line to form the cross,
   which is why the icon morphs rather than swapping. */
.foi-burger__bars,
.foi-burger__bars::before,
.foi-burger__bars::after {
	display: block;
	width: 24px;
	height: 2px;
	background: currentColor;
	border-radius: 2px;
	transition: transform 0.22s ease, opacity 0.12s ease;
}

.foi-burger__bars { position: relative; }

.foi-burger__bars::before,
.foi-burger__bars::after {
	content: "";
	position: absolute;
	left: 0;
}

.foi-burger__bars::before { top: -7px; }
.foi-burger__bars::after  { top: 7px; }

.foi-burger[aria-expanded="true"] .foi-burger__bars { background: transparent; }
.foi-burger[aria-expanded="true"] .foi-burger__bars::before { transform: translateY(7px) rotate(45deg); }
.foi-burger[aria-expanded="true"] .foi-burger__bars::after  { transform: translateY(-7px) rotate(-45deg); }

@media ( prefers-reduced-motion: reduce ) {
	.foi-burger__bars,
	.foi-burger__bars::before,
	.foi-burger__bars::after { transition: none; }
}

@media ( max-width: 767px ) {

	.foi-burger { display: inline-flex; }

	/* The panel drops out of the header bar and spans the shell, so the
	   buttons can run full width the way the design shows them. */
	.foi-header__right {
		display: none;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		padding: 14px var(--foiprp-gutter) 0;
	}

	.foi-header__right.is-open { display: block; }

	.foi-nav ul {
		display: grid;
		gap: 14px;
	}

	/* Full-width buttons, same fill and radius as the inline ones. */
	.foi-prp .foi-nav a {
		justify-content: center;
		padding: 15px 25px;
	}
}

/* =========================================================
   HERO
   ========================================================= */

.foi-hero {
	position: relative;
	/* Full screen height at every size. The reference canvases are a fixed
	   839px (mobile) and 810px (desktop), but those leave a short strip of the
	   next section showing on a laptop and fall short of the fold on a large
	   monitor, so the hero takes the viewport instead.

	   min-height, not height, so it can still grow if the copy ever needs more
	   room; svh, not vh, so a phone's collapsing address bar doesn't make the
	   hero jump or hide the CTA behind browser chrome. The vh line above is the
	   fallback for browsers without svh. */
	min-height: 100vh;
	min-height: 100svh;
	display: flex;
	align-items: flex-end;
	color: #fff;
	overflow: hidden;
}

.foi-hero__media { position: absolute; inset: 0; }

.foi-hero__media img,
.foi-hero__media .foi-img-placeholder {
	width: 100%;
	height: 100%;
	object-fit: cover;
	min-height: 100%;
}

/* Hero framing, measured off the reference canvases rather than guessed.
   The photo is nearly square (ratio 1.105) while the hero box runs portrait on
   phones and 16:9 on desktop, so `cover` crops on a different axis at each end
   — and the design also sits the photo LARGER than `cover` alone would.

   Reference, 1440x810 canvas:  image drawn 1688.97 x 1528.95 at (-165.16, -159.08)
   Reference,  390x839 canvas:  image drawn 1023.36 x  926.45 at (-161.38,    0)

   `cover` gives 1440x1303.6 and 927x839 respectively, so the design is 1.1729x
   and 1.104x larger than cover. object-position sets the anchor; the scale adds
   the extra zoom about that same anchor point, which reproduces both canvases
   to within a pixel while still guaranteeing coverage at any viewport (cover
   covers, and scaling up can only cover more). */
.foi-hero__media img {
	object-position: 25.5% 0%;
	transform: scale(1.104);
	transform-origin: 25.5% 0%;
}

@media ( min-width: 1024px ) {
	.foi-hero__media img {
		object-position: 66.3% 22.1%;
		transform: scale(1.1729);
		transform-origin: 66.3% 22.1%;
	}
}

/* The design's two-layer wash over the photograph, verbatim from the hero
   frame: a radial that darkens the lower-right, and a linear that darkens the
   top band behind the header. Both multiply onto the image.

   The gradients live on this overlay rather than in the hero's own background
   because the photograph is an <img> — that is what lets the hero art be
   framed with object-position and a scale transform. background-blend-mode
   multiplies the two gradients together; mix-blend-mode then multiplies the
   result onto the photo, which is the same stack Figma reports as
   "multiply, multiply, normal".

   Figma flags its radial as using a rotation CSS cannot express. This is the
   un-rotated equivalent, which is what its own CSS panel emits. */
.foi-hero__scrim {
	position: absolute;
	inset: 0;
	background-image:
		radial-gradient(
			42.23% 77.51% at 29.11% 28.96%,
			rgba(103, 60, 27, 0) 43.27%,
			rgba(103, 60, 27, 0.675) 94.93%
		),
		linear-gradient(
			180deg,
			rgba(82, 64, 50, 0.5) 0%,
			rgba(82, 64, 50, 0.5) 5.68%,
			rgba(82, 64, 50, 0) 27.04%
		);
	background-blend-mode: multiply;
	mix-blend-mode: multiply;
	pointer-events: none;
}

/* Left deliberately: these three were the original exception to the shell cap
   and are now simply what every section does. Restating it is harmless and
   keeps the hero pinned to the gutter if a cap ever comes back above. */
.foi-hero .foi-shell,
.foi-header .foi-shell,
.foi-footer .foi-shell { max-width: none; }

.foi-hero__inner {
	position: relative;
	z-index: 1;
	width: 100%;
	padding-block: 130px 40px;
	display: grid;
	gap: 60px;
}

/* Gaps, not margins: the reset's `.foi-prp p { margin: 0 }` is (0,1,1) and
   beats any single-class margin rule here, so margin-top on .foi-hero__lede
   and .foi-hero__sub was being silently dropped. Reference gaps are 10px
   between the three text lines and 31px before the CTA. */
.foi-hero__copy {
	display: flex;
	flex-direction: column;
	/*
	 * stretch, NOT flex-end — this is a Safari bug fix, do not "tidy" it back.
	 *
	 * flex-end makes every line shrink-to-fit, which means each <p> is sized by
	 * its own intrinsic width. Both the lede and the sub contain a <br />, and
	 * WebKit gets the intrinsic width of a block with a forced break wrong: it
	 * sizes the box to the LAST segment instead of the widest one. So in Safari
	 * the lede was sized to "(PRP) Therapy" and "Platelet-Rich Plasma" then had
	 * to wrap — at the hyphen, giving "Platelet-" / "Rich Plasma" / "(PRP)
	 * Therapy". Same story in the sub: sized to "healing potential with PRP.",
	 * so "Discover your body's natural" wrapped after "your". Chrome sizes to
	 * the widest segment and looked fine, which is why it read as a Safari-only
	 * bug with "plenty of width available" — there was width, the box just
	 * wasn't asking for it.
	 *
	 * With stretch the lines are full-width blocks and the right alignment
	 * comes from text-align below, so nothing depends on intrinsic sizing and
	 * the <br /> is the only place either line can break. The CTA stack keeps
	 * its own align-self: flex-end — it has no <br />, so shrink-to-fit is
	 * safe there.
	 */
	align-items: stretch;
	/* The design's text-wrapper: three text blocks, 10px apart, right-aligned.
	   The PRP line is a two-line block of its own (its 110% leading sets the
	   space between ITS two lines — no gap is added there, because that break
	   lives inside one element). */
	gap: 10px;
	text-align: right;
}

/* The design leads with "Platelet-Rich Plasma (PRP) Therapy". That line is
   the .foi-hero__lede, which follows the h1 in the markup — the h1 stays first
   in the DOM so the document outline and SEO still see the real heading, and
   only the visual order changes. */
.foi-hero__lede { order: -1; }

/* Scoped past the shared `.foi-hero__title, .foi-hero__lede` rule below, which
   is the same specificity but later in the file. */
.foi-prp .foi-hero__lede { font-size: 32px; }

/* Hero type, straight from the design. The three lines each have their own
   size at every canvas, so they no longer ride the shared subhead token:

              lede (PRP)   title (built)   sub (Discover)
   mobile        32             25              14
   tablet        42             30              15
   desktop       45             34              19

   The two serif lines run 110% leading and -0.01em; the sans sub-line runs
   126% and -0.03em. Sizes for tablet and desktop are in the breakpoint
   blocks near the end of this file. */
.foi-hero__title,
.foi-hero__lede {
	font-family: var(--foiprp-display);
	font-weight: 400;
	font-size: 25px;
	/*
	 * Tighter than Figma's 1.1, deliberately.
	 *
	 * At an equal line-height the larger type gets the larger absolute gap —
	 * 1.1 is 3.4px of extra leading at 34px but only 2.5px at the subhead's
	 * 25px — so the headline reads looser than the subhead sitting under it
	 * even though both are "1.1". This pulls the two headline lines to the
	 * same optical spacing as the subhead's two lines.
	 *
	 * The design's 110%.
	 */
	line-height: 1.1;
}

/* Tracking is a FIXED pixel value per line, not em-relative — the design holds
   the same absolute tracking as the sizes ramp, so these do not scale with the
   breakpoints. */
.foi-prp .foi-hero__lede  { letter-spacing: -0.45px; }
.foi-prp .foi-hero__title { letter-spacing: -0.34px; }

/* Reference: Instrument Serif 25px / 27.5px / -0.01em at BOTH canvases — it
   does not ride the subhead ramp. Width-capped so it wraps to two lines the
   way the design does, rather than running the full copy width. */
.foi-hero__sub {
	/* No width cap. The reference box is 280px, but the exact figure is a trap:
	   our Instrument Serif sets a shade wider, so 280 pushes a third line while
	   anything past ~361 pulls "healing" up onto line one — and which side of
	   that window you land on shifts with the loaded font. The break is written
	   into the copy as a <br /> instead, so it holds whatever the metrics do. */
	/* Sans, not the display serif: the design sets this line apart from the
	   two serif headline lines above it by changing the face, which is what
	   separates it as supporting copy rather than a third headline. */
	font-family: var(--foiprp-body);
	font-weight: 400;
	font-size: 14px;
	line-height: 1.3;
	letter-spacing: -0.57px;
}

/* The wrapper's own 10px gap spaces the three text lines, so the sub adds
   nothing. The button sits 30px below the copy: 20px here plus that gap. */
.foi-prp .foi-hero__sub { margin-top: 0; }

.foi-hero__mark {
	justify-self: end;
	width: 132px;
	height: auto;
}

/* =========================================================
   CONDITIONS
   ========================================================= */

.foi-conditions {
	position: relative;
	z-index: 2;
	padding-block: var(--foiprp-section);
	background: var(--foiprp-page);
}

/* Heading → icon row spacing is a container gap, not a margin. */
.foi-conditions__inner {
	display: flex;
	flex-direction: column;
	gap: 48px;
}

.foi-prp .foi-conditions__title {
	text-align: center;
	max-width: 22ch;
	margin-inline: auto;
	font-size: var(--foiprp-fs-display);
	line-height: 1.1;
	color: #000;
	text-wrap: balance;
}

/* Phones: a centred wrapping row, not a fixed 3-up grid.

   The design never scales the lockup — it is 122px wide at every canvas — but
   a 3-column grid on a 358px content width gives 113px tracks, so each icon
   overflowed its own cell (the parent's justify-items:center sizes items to
   max-content, which is why the icon's own max-width:100% never bit). Two per
   row is what the mobile canvas shows, and wrap + justify-content:center gets
   that for free, with the odd seventh lockup centred on its own row. */
.foi-conditions__grid {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: flex-start;
	gap: 30px 20px;
}

.foi-conditions__grid > * { flex: 0 0 122px; max-width: 100%; }

.foi-condition {
	display: grid;
	justify-items: center;
	/* Same 11.142px the icon box uses as its own inset — one spacing value for
	   the whole lockup. Was 24px. */
	gap: 11.142px;
	text-align: center;
}

.foi-condition__icon {
	display: grid;
	place-items: center;
	width: 122px;
	max-width: 100%;
	min-width: 0;
	aspect-ratio: 1 / 1;
	/* Figma: the 122x122 box carries 11.142px of padding, so the artwork itself
	   sits in ~99.7px. box-sizing:border-box keeps the box at 122. */
	padding: 11.142px;
	color: var(--foiprp-ink);
}

/* width:122px here beat the max-width and pushed the 3-column grid ~16px past
   the viewport below 390px, so the whole page scrolled sideways. The icon is
   square, so width:100% + aspect-ratio holds the shape and lets the track
   shrink. */
.foi-condition__icon img {
	display: block;
	width: 100%;
	height: auto;
	aspect-ratio: 1 / 1;
	object-fit: contain;
}

/* Label half of the hover. The icon half needs SVG artwork — see the note in
   the conditions markup. */
@media (hover: hover) {
	.foi-condition:hover .foi-condition__label { color: var(--foiprp-accent); }

	/* Inline SVG: paint the fills directly rather than filtering the whole
	   element. `brightness(0)` produced the right colour, but a filter forces
	   the icon onto its own compositing layer, and on some devices that
	   re-rasterises these hairline rings heavy enough to look filled in — the
	   palm oval closed up into a lozenge. Setting `fill` reaches the same two
	   states with no filter and no layer.

	   The attribute selector is what makes it work without touching the files:
	   the accent paths carry fill="#0097DC" in the artwork, so they can be
	   picked out and released on hover while everything else stays black. */
	.foi-condition__icon svg path { fill: #000000; transition: fill 0.18s ease; }

	.foi-condition:hover .foi-condition__icon svg path[fill="#0097DC"] {
		fill: var(--foiprp-accent);
	}

	/* <img> artwork can't be reached from CSS, so it keeps the filter. */
	.foi-condition__icon img { filter: brightness(0); transition: filter 0.18s ease; }

	.foi-condition:hover .foi-condition__icon img { filter: none; }

	/* Route B — all-black artwork with the joint strokes as their own paths.
	   Tag those paths class="foi-icon-accent" and they pick up the blue.
	   Requires inline SVG; unreachable through an <img>. */
	.foi-condition:hover .foi-condition__icon .foi-icon-accent {
		stroke: var(--foiprp-accent);
		fill: none;
	}
}

/* Inlined SVGs have no intrinsic sizing from the <img> box, so constrain them
   the same way. */
.foi-condition__icon svg {
	display: block;
	width: 100%;
	height: 100%;
	max-height: 100%;
}

/* Matched to the label baked into the supplied icon SVGs: title case, DM Sans
   bold, ~12.6px cap-height-derived, no extra tracking. It was uppercase 10.88px
   at weight 500, which rendered "HAND & WRIST" 87px wide against the artwork's
   72px "Hand & Wrist". The SVG's own copy of the label is cropped out of the
   viewBox so this HTML text is the only one shown — it stays real text, so it
   remains selectable, translatable and screen-reader friendly. */
.foi-condition__label {
	transition: color 0.18s ease;
	font-family: var(--foiprp-body);
	font-size: 12px;
	font-weight: 700;
	line-height: 1.3;
	letter-spacing: -0.03em;
	text-align: center;
	/* Figma: #000000 at opacity 0.9, same rgba treatment as the buttons. */
	color: rgba(0, 0, 0, 0.9);
}

/* =========================================================
   START YOUR JOURNEY
   ========================================================= */

/* Vertical wash: flat #f7f7f7 for the top third, then warming to sand at the
   foot of the section. Sampled straight off the Figma canvas, which is
   perfectly uniform horizontally.

   This replaced background-image:url(journey-bg.png). That asset carried a
   green blob (its centre samples ~rgb(204,221,184)) and fully transparent
   corners, so stretching it to 100% 100% painted a green haze across the
   section and let the --foiprp-cream fill behind it show through as yellow bands
   down both edges. Neither appears in the design. A gradient also drops a
   40KB request and can't distort at any aspect ratio. */
.foi-journey {
	background-color: #f7f7f7;
	background-image: linear-gradient(
		180deg,
		#f7f7f7 0%,
		#f7f7f7 30%,
		#f4f3f0 37%,
		#f0eee6 51%,
		#eae8dc 66%,
		#e6e2d1 80%,
		#e0dcc6 94%,
		#ded9c2 100%
	);
	padding-block: 70px;
}

/* Title → cards spacing is a container gap, not a margin. */
.foi-journey__inner {
	display: flex;
	flex-direction: column;
	gap: 31px;
}

.foi-journey__title {
	font-size: var(--foiprp-fs-heading);
	color: #000;
}

/* Phones: the lockup keeps its designed 265px and centres, rather than
   stretching to the full content width. On the 402px mobile canvas that leaves
   ~68px either side — the inset the design shows. Tablet and up go back to a
   grid (2-up, then 4-up). */
.foi-journey__grid {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 20px;
}

.foi-journey__grid > .foi-card { flex: 0 1 265px; max-width: 265px; }

.foi-card {
	/* Figma "Lockup 5": 265x390, gap 60, radius 20. On the mobile canvas the
	   card runs the full content width, where the design's uneven 20/30 inset
	   reads as lopsided — so phones get a flat 20px all round. Tablet and up
	   restore the design's 20px 30px 20px 20px (see the 768 block). */
	background-image: linear-gradient(180deg, #ffffff 0%, #f0ede5 41.83%);
	border: 0;
	border-radius: 20px;
	/* The cards DO carry a drop shadow in the design — offset to the bottom
	   right, nothing on the left or top edge. Derived by sampling the falloff
	   just outside the card edge in Figma (20 luma darker at the edge, back to
	   background over ~6px) and fitting against that curve; this lands within
	   ~1.3 luma per sample. Without it the cards converge with the section
	   gradient around mid-height, where the contrast is only 1/255. */
	box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.11);
	padding: 20px;
	display: flex;
	flex-direction: column;
	/* gap:0, not 60. Figma's Lockup has TWO children, not three — the number,
	   then a group holding the copy and the button with space-between. Only
	   that one pair is 60px apart. Treating the button as a third child gave
	   the card two 60px gaps, which is where the extra height came from:
	   20 + 80 + 60 + 60 + copy + button + 20. The 60 is now a margin on the
	   copy alone, and the button is floated to the bottom of the group. */
	gap: 0;
}

/* The number and the copy+button group are the card's two children in Figma.
   display:contents dissolves the .foi-card__top wrapper so the number and the
   copy sit directly in the card's own column. */
.foi-card__top { display: contents; }



/* 60px below the number (the Lockup's only gap), then flex:1 so the copy
   absorbs the slack and the button lands at the foot of the card — the same
   result as Figma's space-between group, and it keeps the buttons aligned
   across cards with uneven copy. */
.foi-card__content { flex: 1 1 auto; margin-top: 60px; }

/* Figma "Frame 2147238603": the head/body wrapper is a column with gap: 20,
   stretched to the card's content width. Same on every canvas. */
.foi-card__content {
	display: flex;
	flex-direction: column;
	gap: 20px;
}

.foi-card__num {
	font-family: var(--foiprp-body);
	font-weight: 400;
	font-size: 80px;
	line-height: 1;
	color: #9b9b96;
}

.foi-card__head {
	font-family: var(--foiprp-display);
	font-weight: 400;
	font-size: var(--foiprp-fs-subhead);
	line-height: 1.15;
	/* Absolute px, not em — the card head ramps 25 → 30 → 34 and the design
	   holds the same tracking at every size. */
	letter-spacing: -0.34px;
	color: var(--foiprp-ink);
}

/* Figma "Paragraph": DM Sans 400 / 15px / 140% / -0.005em / #6F6F6F. The card
   is 265px wide on every canvas, so this holds at all three — the 19px base
   with a 15px override from 768 up was wrong on phones. Weight was 300 and the
   colour was the darker --foiprp-ink-soft. */
.foi-card__body {
	font-family: var(--foiprp-body);
	font-weight: 400;
	font-size: 15px;
	line-height: 1.4;
	letter-spacing: -0.005em;
	color: var(--foiprp-ink-mute);
}

/* Figma's group is `justify-content: space-between; gap: 20px` — the 20 is
   the minimum, the slack above comes from .foi-card__content's flex:1. */
.foi-card .foi-btn--ghost { align-self: flex-start; margin-top: 20px; }

/* =========================================================
   SPLIT SECTIONS (01 / 02)
   ========================================================= */

.foi-split { padding-block: var(--foiprp-section); }

/* The two split blocks read as one pair, spaced 77px apart (no divider between). */
.foi-split:not(.foi-split--reverse) { padding-bottom: 77px; }
.foi-split--reverse { padding-top: 0; }

.foi-split__inner {
	display: grid;
	gap: 26px;
	align-items: center;
}

.foi-split__media {
	width: 100%;
	max-width: 550px;
	/* Mobile radius. The desktop frame is 100px on a 550px square; at 358px on
	   a phone that reads far too round, so the mobile canvas uses 60. Restored
	   to 100 at 1280 (see the desktop block). */
	border-radius: 60px;
	overflow: hidden;
}

.foi-split__media img,
.foi-split__media .foi-img-placeholder {
	display: block;
	width: 100%;
	aspect-ratio: 1;
	object-fit: cover;
	/* The reference anchors the crop to the bottom of the frame. Both source
	   files are already 1100x1100, so this only matters if a non-square image
	   is swapped in later. */
	object-position: 50% 100%;
}

/* Heading block → prose is a container gap, not a margin. */
.foi-split__copy {
	display: flex;
	flex-direction: column;
	gap: 15px;
}

.foi-split__head {
	display: flex;
	flex-direction: column;
}

.foi-eyebrow {
	display: block;
	font-family: var(--foiprp-display);
	font-size: var(--foiprp-fs-heading);
	line-height: 1.1;
	color: #636363;
}

.foi-split__copy .foi-h3 {
	font-size: var(--foiprp-fs-heading);
	line-height: 1.1;
	color: #242424;
}

.foi-prose {
	font-family: var(--foiprp-body);
	font-weight: 400;
	font-size: var(--foiprp-fs-body);
	line-height: 1.55;
	color: #5a5a5a;
}

/* =========================================================
   03 HOW PRP THERAPY WORKS
   ========================================================= */

.foi-process { padding-block: var(--foiprp-section); }

/* Panel → CTA spacing is a container gap, not a margin (same pattern as the
   conditions and journey sections). The panel stretches; only the button is
   centred. */
.foi-process .foi-shell {
	display: flex;
	flex-direction: column;
	gap: 60px;
}

.foi-process__cta { align-self: center; }

/* Mobile panel — the design's "How it Works/Mobile": padding 30, gap 30,
   radius 30, single column. Tablet and desktop override below. */
/* Figma's panel fill is an image ("Blur.jpg") at 30% opacity — an out-of-focus
   wash whose whole tonal range is under 20 levels wide. At that amplitude the
   texture reads as a flat tint anyway, so the panel is a solid colour: one
   fewer request, no decode cost, and nothing to go stale in a CDN. The image
   ships in assets/img/process-blur.jpg if it is ever wanted back. */
.foi-process__panel {
	background-color: #f5f4ef;
	border-radius: 30px;
	padding: 30px;
	display: grid;
	gap: 30px;
}

/* Image, copy and badge share one column. On desktop it is locked to a fixed
   height (below), so a longer step never reflows the section — the figure
   absorbs the difference instead. */
.foi-process__right {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	align-items: center;
	gap: 30px;
}

.foi-process__head { margin-bottom: 28px; }

.foi-process__head .foi-h3 {
	font-size: var(--foiprp-fs-heading);
	line-height: 1.1;
	color: #000;
}

.foi-process__head .foi-eyebrow { color: #636363; }

.foi-steps { display: grid; gap: 14px; align-content: start; }

/* Scoped past `.foi-prp button` in the reset — same trap as .foi-pill above.
   As a bare `.foi-step` (0,1,0) the reset's `background:none` (0,1,1) won and
   the resting pills rendered with no fill at all. */
.foi-prp .foi-step {
	display: flex;
	align-items: center;
	gap: 4px;
	min-height: 76px;
	padding: 0 30px;
	border-radius: 19px;
	background: #e8e6e0;
	font-family: var(--foiprp-display);
	font-size: var(--foiprp-fs-subhead);
	line-height: 1.1;
	letter-spacing: -0.01em;
	transition: background 0.18s ease, color 0.18s ease;
}

/* Step tabs below the desktop breakpoint — layout only; the type is the
   design's own (25px on the phone canvas, 30px on the tablet one).

   The design uses the same wrapping, centred row on both and only the container
   width differs: mobile Tabs 298 wide (one per row), tablet Tabs 540
   (= 262 + 16 + 262, two per row with the third centred beneath). Desktop
   restores the single-column grid; see the 1280 block. */
@media ( max-width: 1279px ) {
	.foi-steps {
		display: flex;
		flex-wrap: wrap;
		justify-content: center;
		align-items: flex-start;
		align-content: flex-start;
		gap: 16px;
	}

	.foi-prp .foi-step {
		border-radius: 10px;
		padding: 0 30px;
		/* The labels are nowrap, which gives the pill a wide min-content; without
		   these two a slow webfont could widen the page instead of being clipped
		   for the moment before Instrument Serif arrives. */
		min-width: 0;
		overflow: hidden;
	}

	/* Never break these — "Ste / p 3:" is worse than any alternative. */
	.foi-prp .foi-step__pre,
	.foi-prp .foi-step__name { white-space: nowrap; }
}

/* Phone canvas: one pill per row at the design's 25px. */
@media ( max-width: 767px ) {
	.foi-prp .foi-step { flex: 1 1 100%; max-width: 262px; }

	.foi-prp .foi-step__pre,
	.foi-prp .foi-step__name { font-size: 25px; }
}

/* Tablet canvas: always two-up on the first row with the third centred beneath.
   A fixed 262 basis could not hold that at the narrow end — at a 768 viewport
   the track is 500 and 262 + 16 + 262 = 540 does not fit, so every pill dropped
   onto its own row. Half the track (capped at 262 once there is room) keeps the
   two-up shape across the band, and the 540 cap on the track stops a wide
   tablet from lining all three up and losing the design's shape. */
@media ( min-width: 768px ) and ( max-width: 1279px ) {
	.foi-steps {
		max-width: 540px;
		margin-inline: auto;
	}

	.foi-prp .foi-step {
		flex: 1 1 calc( 50% - 8px );
		max-width: 262px;
	}

	.foi-prp .foi-step__pre,
	.foi-prp .foi-step__name { font-size: 30px; }
}

/* ---------------------------------------------------------------
   Step tab colours and the hover state machine.

   Deliberately NOT dependent on JavaScript. The .is-active class (set by PHP
   for the resting state, and by JS on tap) only has to be right on first
   paint; :has() drives everything after that, so the section works with JS
   disabled entirely.
   --------------------------------------------------------------- */

.foi-step__pre,
.foi-step__name {
	font-family: var(--foiprp-display);
	font-size: var(--foiprp-fs-subhead);
	line-height: 1.1;
	letter-spacing: -0.01em;
}

/* "Step 01/02/03" prefix, resting state. Semi-transparent black rather than a
   flat grey so it stays correctly weighted against the panel fill — if the
   panel colour is retuned again, this follows it instead of drifting. */
.foi-step__pre  { color: #000000; }
.foi-step__name { color: #000000; }

.foi-prp .foi-step.is-active { background: var(--foiprp-step-active); }
.foi-step.is-active .foi-step__pre  { color: #ffffff; }
.foi-step.is-active .foi-step__name { color: #fff; }

@media (hover: hover) {

	/* 1. The hovered step lights up. */
	.foi-prp .foi-step:hover { background: var(--foiprp-step-active); }
	.foi-prp .foi-step:hover .foi-step__pre  { color: #ffffff; }
	.foi-prp .foi-step:hover .foi-step__name { color: #fff; }

	/* 2. While ANY step is hovered, the resting .is-active step stands down.
	      :not(:hover) so a hover on the resting step itself still reads blue. */
	.foi-process__panel:has( .foi-step:hover ) .foi-prp .foi-step.is-active:not(:hover),
	.foi-prp .foi-process__panel:has( .foi-step:hover ) .foi-step.is-active:not(:hover) {
		background: #e8e6e0;
	}

	.foi-process__panel:has( .foi-step:hover ) .foi-step.is-active:not(:hover) .foi-step__pre  { color: #000000; }
	.foi-process__panel:has( .foi-step:hover ) .foi-step.is-active:not(:hover) .foi-step__name { color: #000000; }

	/* 3. Same for the panel and figure: the resting pair hides the moment a
	      hover takes over. */
	.foi-process__panel:has( .foi-step:hover ) .foi-steppanel.is-active { display: none; }
	.foi-process__panel:has( .foi-step:hover ) .foi-process__fig.is-active { opacity: 0; }

	/* 4. Light up the hovered index. Higher specificity than rule 3, and later
	      in the sheet, so it always wins. */
	.foi-process__panel:has( .foi-steps > .foi-step:nth-child(1):hover ) .foi-steppanels > .foi-steppanel:nth-child(1) {
		display: flex;
	}
	.foi-process__panel:has( .foi-steps > .foi-step:nth-child(1):hover ) .foi-process__figure > .foi-process__fig:nth-child(1) {
		opacity: 1;
	}
	.foi-process__panel:has( .foi-steps > .foi-step:nth-child(2):hover ) .foi-steppanels > .foi-steppanel:nth-child(2) {
		display: flex;
	}
	.foi-process__panel:has( .foi-steps > .foi-step:nth-child(2):hover ) .foi-process__figure > .foi-process__fig:nth-child(2) {
		opacity: 1;
	}
	.foi-process__panel:has( .foi-steps > .foi-step:nth-child(3):hover ) .foi-steppanels > .foi-steppanel:nth-child(3) {
		display: flex;
	}
	.foi-process__panel:has( .foi-steps > .foi-step:nth-child(3):hover ) .foi-process__figure > .foi-process__fig:nth-child(3) {
		opacity: 1;
	}
}

/* One figure per step, stacked so the panel never reflows as they swap. The
   parent is display:grid, so placing every child in cell 1/1 overlays them;
   only .is-active is opaque. */
.foi-process__figure {
	color: var(--foiprp-ink);
	padding: 8px;
	display: grid;
	grid-template-rows: 1fr;
	width: 100%;
	/* The stacked images fill a single grid row, so the box needs an intrinsic
	   height below the desktop breakpoint (where the fixed column height
	   supplies it). Ratio is the artwork's own 770x704. */
	aspect-ratio: 770 / 704;
	/* Final backstop: whatever a theme does to the image, nothing paints
	   outside the figure. */
	overflow: hidden;
}

.foi-process__figure > * { grid-area: 1 / 1; min-height: 0; }

/* Specificity matters here, not just the values.

   Something on the page ships the common modern reset
   `.foi-prp :where(img, svg, video) { height: auto; max-width: 100% }`.
   :where() contributes NOTHING to specificity, so that rule weighs (0,1,0) —
   the .foi-prp class alone. Every other image in this stylesheet is matched as
   `.foi-hero__media img`, `.foi-split__media img`, `.foi-bleed img` etc.
   (0,1,1) and beats it. A bare `.foi-process__fig` was also (0,1,0) — a dead
   tie, resolved only by stylesheet order — so wherever the theme loaded after
   this file, `height: auto` won, the artwork kept its natural height and
   overlapped the copy.

   Matching through .foi-prp AND the figure wrapper puts these at (0,3,0), out
   of reach of that reset regardless of load order. max-height repeats the
   bound as a second line of defence. */
.foi-prp .foi-process__figure .foi-process__fig {
	width: 100%;
	height: 100%;
	max-height: 100%;
	object-fit: contain;
	opacity: 0;
	transition: opacity 0.22s ease;
}

.foi-prp .foi-process__figure .foi-process__fig.is-active { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
	.foi-process__fig { transition: none; }
}

.foi-steppanels { display: contents; }

/* Each panel carries its own body copy AND its own "Length of Visit" /
   "Results Time" block, so the pair swaps together with the step. */
.foi-steppanel {
	display: none;
	flex-direction: column;
	gap: 24px;
}

.foi-steppanel.is-active { display: flex; }

.foi-steppanel p:not( .foi-process__time ) {
	font-family: var(--foiprp-body);
	font-size: var(--foiprp-fs-body);
	line-height: 1.55;
	color: #000000;
	padding-top: 4px;
}

/* Scoped past the reset's `.foi-prp p` (0,1,1) — a bare .foi-process__time
   (0,1,0) lost its padding to it. */
.foi-prp .foi-process__time {
	display: flex;
	align-items: center;
	align-self: stretch;
	gap: 10px;
	height: 38px;
	background: #e5e1d8;
	border-radius: 5px;
	padding: 0 30px;
	font-family: var(--foiprp-body);
	/* Fixed 14px, not --foiprp-fs-caption: that token is shared with the quote
	   attributions and scales to 17px at desktop, which this badge must not
	   follow — label and value stay 14px at every width. */
	font-size: 14px;
	line-height: 1;
	color: var(--foiprp-ink);
}

/* The label — "LENGTH OF VISIT" / "RESULTS TIME", Outfit Medium. Uppercased
   here rather than in the copy so the string stays sentence case in
   content.php and screen readers announce it as a phrase, not initials. */
.foi-process__time span {
	font-family: var(--foiprp-alt);
	font-weight: 500;
	font-size: 14px;
	line-height: 1.3;
	letter-spacing: -0.03em;
	text-transform: uppercase;
	color: #000000;
}

/* The value — "45–90 minutes". Outfit Light against the label's Medium. */
.foi-process__time strong {
	font-family: var(--foiprp-alt);
	font-weight: 300;
}

/* =========================================================
   VOICES OF RECOVERY
   ========================================================= */

/* The section is a cream gradient with a 35% photographic overlay, not a flat
   fill. The old `background: var(--foiprp-cream)` painted the raw F7F0D2 on its
   own, which is why the section read as solid pale yellow. */
.foi-voices {
	position: relative;
	background-color: #f7f7f7;
	background-image: linear-gradient(
		180deg,
		#f7f7f7 0%,
		#f6f6f5 15%,
		#f5f4f1 29%,
		#f3f2ee 42%,
		#f2f1ec 56%,
		#f1efe9 69%,
		#efede5 82%,
		#edebe2 96%,
		#eceae1 100%
	);
	/* Reference frame is `padding: 0 80px` with the content carrying
	   `padding: 50px 0 0` — no bottom padding at all. What closes the section
	   is the last quote's own 40px, which is why an extra --foiprp-section here
	   left a visible dead band under the quotes. */
	padding-block: 50px 0;
	/* No overflow:hidden. The tint below is `inset: 0` so it can't escape, and
	   with the bottom padding gone the clip was cutting the quotes' scroll-in
	   translate mid-animation. */
}

/* 35% image overlay from Figma. Set --foiprp-voices-img to a url() (e.g. a
   WordPress Media URL) to enable it; until then the section is solid cream. */
.foi-voices::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: var(--foiprp-voices-img, none);
	background-size: cover;
	background-position: center;
	opacity: 0.35;
	pointer-events: none;
	z-index: 0;
}

.foi-voices > * { position: relative; z-index: 1; }

/* Scoped through .foi-prp on purpose. The reset's `.foi-prp h2 { margin: 0 }`
   is (0,1,1); a bare .foi-voices__title is (0,1,0) and lost to it, so this
   50px had never actually applied and the quotes sat flush under the title. */
.foi-prp .foi-voices__title {
	margin-bottom: 50px;
}

.foi-voices__title {
	font-family: var(--foiprp-display);
	font-weight: 400;
	font-size: var(--foiprp-fs-display);
	line-height: 1.05;
	color: #000000;
}

/* Arrow | track | arrow, on one line, as in the reference: the two arrows sit
   in the margins on the section gutter and the quote track is inset from them
   by the arrow width plus this gap. That inset is the design, not a bug — an
   earlier pass mistook it for a misaligned column and moved the arrows to a
   row of their own above the track. Do not "fix" it again. */
.foi-voices__carousel {
	display: flex;
	align-items: center;
	gap: 14px;
}

.foi-voices__grid {
	display: flex;
	gap: 20px;
	flex: 1 1 auto;
	/* The rule under the section title. It lives on the scroll container, not
	   on each quote — a border on .foi-quote sits inside the scrolling area, so
	   it slid sideways with the cards every time the arrows were used. On the
	   container it is part of the frame and stays put while the quotes move
	   beneath it. */
	border-top: 1px solid #e9e9e9;
	overflow-x: auto;
	/* Must be stated. Setting overflow-x to auto makes overflow-y compute to
	   auto as well, and the reveal animation starts each quote 50px lower via
	   translateY — which the browser counts as scrollable overflow, so the
	   track picked up 50px of vertical scroll it should never have had. The
	   quotes now slide up from behind the bottom edge instead. */
	overflow-y: hidden;
	scroll-snap-type: x mandatory;
	justify-content: safe center;
	list-style: none;
	margin: 0;
	padding: 4px 0;
	scrollbar-width: none;
}

.foi-voices__grid::-webkit-scrollbar { display: none; }

.foi-voices__grid > li {
	flex: 1 0 0;
	min-width: 265px;
	scroll-snap-align: center;
	--foiprp-reveal-y: 50px;
}

/* Phones show one quote at a time, filling the space between the two arrows —
   the mobile frame has no second quote peeking in at the edge. `flex: 0 0 100%`
   makes each slide exactly the track width, so a scroll-snap step is one whole
   quote; min-width:0 is what lets it shrink below the 265px desktop floor
   instead of spilling the next card into view. */
@media ( max-width: 767px ) {
	.foi-voices__grid > li {
		flex: 0 0 100%;
		min-width: 0;
	}
}

/* Scoped past `.foi-prp button { color: inherit }` in the reset (0,1,1),
   which a bare .foi-voices__arrow (0,1,0) loses to — the arrows were
   inheriting --foiprp-ink and rendering near-black instead of bronze. */
.foi-prp .foi-voices__arrow {
	flex: 0 0 auto;
	width: 30px;
	height: 30px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--foiprp-bronze-dk);
	cursor: pointer;
	display: grid;
	place-items: center;
}

.foi-voices__arrow svg { width: 30px; height: 30px; display: block; }
.foi-voices__arrow--next svg { transform: scaleX(-1); }

/* Reference: padding 40px 20px 40px 0, 1px #E9E9E9 rule on top. The 40px
   bottom is the section's whole bottom margin — see .foi-voices above. */
.foi-quote {
	display: grid;
	gap: 0;
	padding: 40px 20px 40px 0;
}

/* Figma sets the opening mark as a full 45px/110% line box (50px tall) with
   `margin: -20px 0` pulling it tight at both ends, so only ~10px of it takes
   up flow and the quote sits right beneath it. */
.foi-quote__mark {
	font-family: var(--foiprp-display);
	font-size: var(--foiprp-fs-heading);
	line-height: 1.1;
	color: #b9b09a;
	margin: -20px 0;
}

.foi-quote blockquote {
	font-family: var(--foiprp-display);
	font-size: var(--foiprp-fs-heading);
	line-height: 1.1;
	/* A fixed -0.45px at every width, not an em-relative value — the quote type
	   ramps 32 → 42 → 45 and the design holds the same absolute tracking. */
	letter-spacing: -0.45px;
	color: var(--foiprp-bronze-dk);
	/* Figma: 20px between the quote and its attribution. */
	margin-bottom: 20px;
}

.foi-quote figcaption {
	font-family: var(--foiprp-body);
	font-size: var(--foiprp-fs-caption);
	font-weight: 500;
	color: var(--foiprp-khaki);
}

/* =========================================================
   FULL-BLEED IMAGE
   ========================================================= */

.foi-bleed img,
.foi-bleed .foi-img-placeholder {
	width: 100%;
	height: auto;
	object-fit: cover;
	display: block;
	aspect-ratio: 780 / 1230; /* mobile crop */
}

/* =========================================================
   FAQS
   ========================================================= */

.foi-faqs { padding-block: var(--foiprp-section); }

.foi-voices,
.foi-faqs {
	border-top: 0.5px solid rgba(0, 0, 0, 0.25);
}

/* No hairline between the numbered blocks 01 (care plan) -> 02 (platelets) -> 03 (process). */
.foi-split--reverse,
.foi-process {
	border-top: none;
}

/* Scoped through .foi-prp so the margin below actually applies: the reset's
   `.foi-prp h2 { margin: 0 }` is (0,1,1) and beats a bare .foi-faqs__title at
   (0,1,0). The 40px that used to sit here was silently dropped, which is why
   the title sat flush against the first question. */
.foi-prp .foi-faqs__title {
	font-family: var(--foiprp-display);
	font-weight: 400;
	font-size: var(--foiprp-fs-display);
	line-height: 1.05;
	color: #000000;
	/* The FAQ block's auto-layout gap: title -> list -> CTA, 30px on both
	   sides. Expressed as a margin on each end rather than a flex gap because
	   .foi-shell is a plain block wrapper shared with other sections. */
	margin-bottom: 30px;
}

.foi-accordion { display: block; }

/* Native <details>, so the accordion works with JavaScript disabled. */
.foi-faq {
	border-bottom: 1px solid rgba(0, 0, 0, 0.25);
}

/* list-style:none plus the -webkit marker rule remove the native disclosure
   triangle. */
.foi-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	padding: 15px 30px 15px 0;
	cursor: pointer;
	list-style: none;
	font-family: var(--foiprp-display);
	font-weight: 400;
	/* Fixed 25px, not --foiprp-fs-subhead: that token ramps 25 → 30 → 34 across
	   the breakpoints and is shared with the hero lines, card heads and step
	   labels. The questions hold 25px at every width. */
	font-size: 25px;
	line-height: 1.2;
	/* Scoped colour: the reset's `.foi-prp summary` inherits --foiprp-ink, and the
	   design is flat black. */
	color: #000000;
}

.foi-faq__q::-webkit-details-marker { display: none; }

/* The +/- icon is two 1px bars; the vertical one collapses when open. */
.foi-faq__icon {
	position: relative;
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	color: #000000;
}

.foi-faq__icon::before,
.foi-faq__icon::after {
	content: "";
	position: absolute;
	background: currentColor;
	transition: transform 0.2s ease, opacity 0.2s ease;
}

/* Horizontal bar. */
.foi-faq__icon::before {
	left: 0;
	right: 0;
	top: 50%;
	height: 1px;
	transform: translateY(-50%);
}

/* Vertical bar — rotated away when the item is open, turning + into -. */
.foi-faq__icon::after {
	top: 0;
	bottom: 0;
	left: 50%;
	width: 1px;
	transform: translateX(-50%);
}

.foi-faq[open] .foi-faq__icon::after {
	transform: translateX(-50%) rotate(90deg);
	opacity: 0;
}

.foi-faq__a {
	padding: 0 30px 20px 0;
	font-family: var(--foiprp-body);
	font-size: var(--foiprp-fs-body);
	line-height: 1.55;
	color: var(--foiprp-ink-soft);
}

/* The class sits ON the button (`<a class="foi-btn foi-faqs__cta">`), not on a
   wrapper — so this centres the button itself rather than laying out children. */
.foi-faqs__cta {
	display: block;
	width: fit-content;
	/* Matches the 30px above the list. */
	margin: 30px auto 0;
}

@media (prefers-reduced-motion: reduce) {
	.foi-faq__icon::before,
	.foi-faq__icon::after { transition: none; }
}

/* =========================================================
   CLOSING CTA
   ========================================================= */

/* Hairline above the section, same 0.5px rule the other section boundaries
   use, and the warm wash that carries the page down into the footer. */
.foi-closing {
	background-color: var(--foiprp-page);
	background-image: linear-gradient(
		180deg,
		#f7f7f7 0%,
		#f6f5f2 22%,
		#f3f1ea 45%,
		#efece0 68%,
		#ebe7d6 86%,
		#e8e3ce 100%
	);
	border-top: 0.5px solid rgba(0, 0, 0, 0.25);
	padding-block: var(--foiprp-section);
}

.foi-closing__inner {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 30px;
}

/* No width cap and no balancing — the headline takes the full column and only
   wraps when it genuinely runs out of room. A 20ch cap was forcing it onto two
   lines even at 1440, where it fits on one. */
.foi-closing__title {
	font-family: var(--foiprp-display);
	font-weight: 400;
	font-size: var(--foiprp-fs-heading);
	line-height: 1.15;
	color: #000000;
}

/* .foi-closing__copy wraps the title and the body group; the paragraphs live
   inside .foi-closing__body. */
.foi-closing__copy {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 30px;
}

.foi-closing__body {
	display: flex;
	flex-direction: column;
	gap: 15px;
	max-width: 66ch;
}

.foi-closing__body p {
	font-family: var(--foiprp-body);
	font-size: var(--foiprp-fs-body);
	line-height: 1.55;
	color: #000000;
}

/* QA BUG-009 — FDA and informational-only disclaimers.

   Deliberately quieter than the body copy above: legal text that must be
   present and readable, but must not compete with the CTA it sits under.
   Left-aligned rather than inheriting the section's centring, because ragged
   centred text this long is hard to read. The extra top margin separates it
   from the button; .foi-closing__inner's own 30px gap alone read as if the
   disclaimer belonged to the CTA. */
/* #terms lands here — the FDA/PRP disclaimer, not the footer. The header is
   not sticky, so the only offset needed is enough breathing room that the
   first line isn't flush against the top edge on arrival. */
.foi-closing__legal {
	display: flex;
	flex-direction: column;
	gap: 14px;
	max-width: 92ch;
	margin-top: 20px;
	text-align: left;
	scroll-margin-top: 24px;
}

.foi-prp .foi-closing__legal p {
	font-family: var(--foiprp-body);
	font-size: 12px;
	line-height: 1.5;
	letter-spacing: 0;
	color: #6f6f6f;
}

/* =========================================================
   FOOTER
   ========================================================= */

.foi-footer {
	background: var(--foiprp-page);
	padding-block: 43px;
}

.foi-footer__top { display: grid; gap: 30px; }

/* align-content:start matters. .foi-footer__brand is a grid item stretched to
   the full height of the footer's top row, and auto rows in a stretched grid
   default to filling it — so the logo row grew and pushed the social icons
   ~100px below the mark instead of the 20px the reference has. */
.foi-footer__brand {
	display: grid;
	gap: 20px;
	justify-items: start;
	align-content: start;
}

.foi-footer__logolink { display: block; }

.foi-footer__logo { width: 91px; height: auto; display: block; }

.foi-social { display: flex; gap: 11px; }

/* Figma paints these vectors flat #000000, not the softened ink. */
.foi-social svg { width: 30px; height: 30px; color: #000000; }
.foi-social a:hover svg { color: var(--foiprp-blue); }

.foi-footer__cols { display: grid; gap: 30px; }

/* Scoped through .foi-prp so a theme rule at (0,1,1) — `.site-footer h2` and
   friends are common — can't take the size or the weight back. 24px at every
   width: this heading does not ride the type ramp. */
/* Measured off the reference: Instrument Serif 400 / 24px / 33.6px (140%) /
   -0.01em / #000. Scoped through .foi-prp so a theme rule at (0,1,1) —
   `.site-footer h2` and friends are common — can't take it back. 24px at every
   width: this heading does not ride the type ramp. */
.foi-prp .foi-footer__col h2 {
	font-family: var(--foiprp-display);
	font-size: 24px;
	font-weight: 400;
	line-height: 1.4;
	letter-spacing: -0.01em;
	color: #000000;
	margin-bottom: 10px;
}

.foi-footer__col ul { display: grid; gap: 8px; }

/* `ul a`, not `a`. The column heading is a link too (`<h2><a>About Us</a></h2>`),
   and a bare .foi-footer__col a matched it — so the heading's own 24px serif
   was being overwritten by 16px body type on the anchor that actually carries
   the text. The h2 still computed to 24px, which is what made this look fine
   from the outside. */
.foi-footer__col ul a {
	font-family: var(--foiprp-body);
	font-size: 16px;
	line-height: 1.4;
	color: #000000;
}

/* The heading's link inherits the heading, never its own type. */
.foi-prp .foi-footer__col h2 a {
	font: inherit;
	letter-spacing: inherit;
	color: inherit;
}

.foi-footer__col a:hover { text-decoration: underline; }

.foi-footer__bottom {
	margin-top: 43px;
	display: grid;
	gap: 43px;
}

.foi-footer__note,
.foi-footer__copy {
	font-family: var(--foiprp-body);
	font-size: 12px;
	color: #5a5a5a;
	line-height: 1.7;
}

/* The two sentences are separated by a <br /> in the copy, matching
   floridaortho.com's own footer, so no width cap is needed to place the
   break — and none is wanted, since a cap would only add a second, wrong
   break on a narrow screen. */

.foi-footer__legal {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 8px;
}

.foi-footer__legal li {
	display: flex;
	align-items: baseline;
	gap: 8px;
}

.foi-footer__legal li:not(:last-child)::after {
	content: "|";
	color: #5a5a5a;
	font-size: 12px;
}

.foi-footer__legal a {
	font-family: var(--foiprp-body);
	font-size: 12px;
	color: #5a5a5a;
}

.foi-footer__legal a:hover { text-decoration: underline; }

/* The footer's bottom bar tightens to a 20px rhythm below the desktop canvas
   — the 43px above and between the note, the legal links and the copyright is
   a desktop-only figure. */
@media ( max-width: 1279px ) {
	.foi-footer__bottom { margin-top: 20px; gap: 20px; }
}

/* Phones centre the brand lockup and everything in the bottom bar — the link
   columns stay left-aligned. From 768 up the whole footer is left-aligned, so
   this is mobile-only. */
@media ( max-width: 767px ) {
	.foi-footer__brand { justify-items: center; }

	.foi-footer__note,
	.foi-footer__copy { text-align: center; }

	.foi-footer__legal { justify-content: center; }
}

/* =========================================================
   TABLET  ≥768px
   ========================================================= */

@media (min-width: 768px) {

	:root {
		/* Tablet sits at 60px. Mobile is 16 (the base token) and desktop 80
		   (re-declared in the 1280 block), so this value governs 768-1279 only.
		   Every section takes its side padding from this token, so the splits,
		   the conditions grid, the process panel and the footer all move
		   together and stay aligned with one another. */
		--foiprp-gutter: 60px;
		--foiprp-section: 72px;

		--foiprp-fs-display: 70px;
		--foiprp-fs-heading: 42px;
		--foiprp-fs-subhead: 30px;
		--foiprp-fs-body:    15px;
		--foiprp-fs-btn:     15px;
	}

	.foi-bleed img { aspect-ratio: 1536 / 1230; } /* tablet crop */

	/* No separate tablet hero in the design — it keeps the mobile canvas. */

	.foi-hero__inner {
		grid-template-columns: 1fr;
		padding-block: 150px 40px;
		gap: 60px;
	}

	/* width:100%, not fit-content — same WebKit intrinsic-sizing bug as the
	   align-items note above: Safari measured this container from the lede's
	   last line and clamped the copy far narrower than the column. */
	.foi-hero__copy { max-width: none; width: 100%; }

	/* Hero type, tablet canvas. Scoped through .foi-prp to match the base
	   .foi-prp .foi-hero__lede rule, which would otherwise outrank these. */
	.foi-prp .foi-hero__lede  { font-size: 42px; }
	.foi-prp .foi-hero__title { font-size: 30px; }
	.foi-prp .foi-hero__sub   { font-size: 15px; }

	.foi-hero__mark { justify-content: end; }

	/* Tablet keeps the phone's centred wrap rather than a 4-column grid. In a
	   grid the seven lockups fill tracks 1-4 then 1-3, so the second row hangs
	   off the left edge instead of sitting under the middle of the first. Flex
	   centres each row on its own.

	   The band is capped at four lockups wide (4 x 122 + 3 x 16 = 536), which
	   is also the tablet canvas's own content width — so the shape stays 4 + 3
	   from 768 all the way to 1279 instead of reflowing to 6 + 1 on a wide
	   tablet. */
	.foi-conditions__grid {
		max-width: 536px;
		/* align-self, not margin-inline:auto — the grid is a flex item of the
		   column that stacks the heading above it, and the cross-axis stretch
		   pins it to the start once max-width caps its width. */
		align-self: center;
		gap: 34px 16px;
	}

	.foi-journey__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
	.foi-journey__grid > .foi-card { flex: none; max-width: none; }

	.foi-split__inner { grid-template-columns: 1fr 1fr; gap: 34px; }

	.foi-split--reverse .foi-split__media { order: 2; }

	/* The design has a dedicated tablet panel — "How it Works/Tablet", a single
	   centred column at 648 wide with `padding: 54px; gap: 30px; radius: 60px`.
	   The two-column split is desktop-only. Forcing it here squeezed the step
	   tabs into a ~264px column, which broke "Step 1:" and "Initial Visit"
	   onto separate lines and wrapped the Length-of-Visit badge. */
	.foi-process__panel {
		grid-template-columns: 1fr;
		gap: 30px;
		padding: 54px;
		border-radius: 60px;
	}


	.foi-footer__cols { grid-template-columns: repeat(3, 1fr); gap: 30px; }

	/* Tablet stacks: logo and socials on their own row, the three link columns
	   full width beneath. Putting the brand in a 200px side column left only
	   ~102px per link column at 768 — "Orthopaedic Solutions Management" broke
	   over two lines and the columns read as a cramped afterthought. The side
	   -by-side arrangement returns at >=1280, where there is room for it. */
	.foi-footer__top { grid-template-columns: 1fr; gap: 40px; }
}


/* Tablet lays the two numbered splits side by side, each with its image above
   its copy — a 2-column row rather than two full-width bands. The wrapper takes
   over the shell's gutter and rhythm so the inner shells can collapse to the
   column width; outside this range it is an inert div. */
@media ( min-width: 768px ) and ( max-width: 1279px ) {
	.foi-splits {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: 34px;
		width: 100%;
		max-width: none;
		margin-inline: auto;
		padding-inline: var(--foiprp-gutter);
		padding-block: var(--foiprp-section);
		align-items: start;
	}

	.foi-splits .foi-split,
	.foi-splits .foi-split:not( .foi-split--reverse ),
	.foi-splits .foi-split--reverse { padding-block: 0; }

	/* The shell's own max-width and gutter would double the inset inside a
	   half-width column. */
	.foi-splits .foi-shell { max-width: none; padding-inline: 0; }

	/* Image over copy in each column, and the reverse variant stops reordering —
	   both columns read image-first. */
	.foi-splits .foi-split__inner { grid-template-columns: 1fr; }
	.foi-splits .foi-split--reverse .foi-split__media { order: 0; }

	.foi-splits .foi-split__media { width: 100%; max-width: none; }
}

/* =========================================================
   DESKTOP  ≥1080px
   ========================================================= */

@media (min-width: 1280px) {

	:root {
		/* Reference section frames are `padding: 70px 80px`. FAQs (80) and the
		   closing CTA (100) override this below. */
		--foiprp-section: 70px;
		--foiprp-gutter: 80px;

		--foiprp-fs-display: 96px;
		--foiprp-fs-heading: 45px;
		--foiprp-fs-subhead: 34px;
		--foiprp-fs-body:    19px;
		--foiprp-fs-btn:     19px;
		--foiprp-fs-caption: 17px;
	}

	/* btn-alt reverts to the taller desktop variant. :not() excludes the ghost,
	   which keeps its own 15px 30px — without it this rule sits later in the
	   sheet at equal specificity and silently overrides the ghost's padding. */
	.foi-btn:not( .foi-btn--ghost ) { padding: 17px 40px 18px; }

	/* Figma frame is 51px. Padding + 0.75px borders + a 17.1px line box comes
	   to 48.6, so min-height makes up the remainder and keeps the ghost the
	   same height as btn-alt where the two sit near each other. */
	.foi-btn--ghost { min-height: 51px; }

	/* Start Your Journey cards: the four ghost CTAs sit a step below the
	   shared --foiprp-fs-btn (19px at this width), per the Figma spec.
	   Scoped to .foi-card so the hero/process/closing buttons, which read
	   from the same token, are untouched. */
	.foi-card .foi-btn--ghost { font-size: 18px; }

	.foi-bleed img { aspect-ratio: 2560 / 1230; } /* desktop crop */

	/* Three quotes across at the design's width, the rest reached with the
	   arrows — which is what the arrows are for.

	   The base rule is `flex: 1 0 0`, so every quote shares the track equally:
	   with three that lands on 360px each, but a fourth squeezed all four down
	   to their 265px floor, turning three-line quotes into nine-line ones and
	   making the section far taller. Pinning the basis to 360 keeps the column
	   at its designed width no matter how many testimonials FOI supplies, and
	   anything past the third scrolls, so adding a quote never reflows the
	   ones already there.

	   Sized off the track rather than hard-coded: the percentage resolves
	   against the grid's own width, which is the shell minus the two arrows
	   and their gaps, so three columns plus two 20px gaps always come out
	   exactly full-width even if the shell or the arrows change. */
	.foi-voices__grid > li { flex: 0 0 calc( ( 100% - 40px ) / 3 ); }

	/* Reference logo is 200px wide at desktop, 150 below it. */
	.foi-logo img { height: auto; width: 200px; }

	/* Nav at desktop: DM Sans Light 17px / 90% / -0.03em, 25px apart. */
	.foi-nav ul { gap: 25px; }

	/* The header button spec is one size at every canvas — see .foi-nav a. */

	/* The hero is 100svh at every width now — see the base rule. The old
	   desktop cap of 810px lived here. */

	.foi-hero__inner { padding-block: 190px 100px; gap: 60px; }

	/* "You're built for better. So are we." holds on one line at desktop. The
	   PRP line is NOT included: the design sets it over two lines, and the
	   break is written into the copy. */
	.foi-hero__title { white-space: nowrap; }

	/* Desktop hero type, per the revised design. The two headline lines no
	   longer share a size: "Platelet-Rich Plasma (PRP) Therapy" leads at 45px
	   and "You're built for better. So are we." supports it at 34px, with the
	   sub-line dropping to 19px. Sizes are set here only, so tablet and mobile
	   keep the existing 30/25 ramp. */
	.foi-prp .foi-hero__lede  { font-size: 45px; }
	.foi-prp .foi-hero__title { font-size: 34px; }
	.foi-prp .foi-hero__sub   { font-size: 19px; }

	.foi-hero__mark { width: 171px; }

	.foi-conditions__inner { gap: 80px; }

	/* Desktop goes back to a real 7-column grid across the full narrow band —
	   the 536 cap and the centred wrap are tablet-and-below only. */
	.foi-conditions__grid {
		display: grid;
		grid-template-columns: repeat(7, minmax(0, 1fr));
		gap: 28px 8px;
		max-width: none;
		align-self: auto;
	}
	.foi-conditions__grid > * { flex: none; }

	/* 4 x 265 + 3 x 20 = 1120, the narrow band exactly. */
	.foi-journey__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; }

	/* Journey's horizontal inset now comes from .foi-shell--narrow, like the
	   other inner-band sections; only its 70px vertical padding is its own. */

	/* Back to the design's inset from tablet up — the flat 20px is a mobile-only
	   correction (see .foi-card). */
	/* 390 is the desktop Lockup height. Below this the card sizes to its own
	   copy, which is shorter because the head and body ramp down. */
	.foi-card { padding: 20px 30px 20px 20px; min-height: 390px; }

	/* Design radius on the 550px square. Mobile keeps 60 (see .foi-split__media). */
	.foi-split__media { border-radius: 100px; }

	.foi-split__inner { gap: 60px; }

	.foi-split__media { width: 550px; max-width: none; }

	/* The desktop media is a fixed 550 inside a 610-wide grid column, so it
	   needs telling which edge to sit against — otherwise a grid item falls to
	   the start of its track and 02's image stopped 60px short of the right
	   gutter. 01 is already flush left at 80; this puts 02 flush right at 1360,
	   matching the reference. */
	.foi-split--reverse .foi-split__media { justify-self: end; }

	.foi-split__media img,
	.foi-split__media .foi-img-placeholder { width: 550px; height: 550px; }

	/* Figma: two columns, padding 69px 68px, gap 82px, radius 100. */
	.foi-process__panel {
		grid-template-columns: 1fr 1fr;
		gap: 82px;
		padding: 69px 68px;
		border-radius: 100px;
	}

	.foi-steps { display: grid; gap: 14px; align-content: start; max-width: 386px; }

	/* Figma: 482 x 533, space-between. The fixed height is the whole point —
	   it is what stops the badge moving between steps. */
	.foi-process__right {
		width: 482px;
		height: 533px;
		justify-self: end;
	}

	/* With the column height fixed, the figure gives up space to a longer step
	   instead of the section growing. */
	.foi-process__figure {
		flex: 1 1 auto;
		min-height: 0;
		aspect-ratio: auto;
	}

	.foi-process__fig { max-width: none; }

	/* Figma frame padding is 100px 80px; the 80 comes from the shell. */
	.foi-closing { padding-block: 100px; }

	/* Figma FAQ frame is `padding: 80px`. */
	.foi-faqs { padding-block: 80px; }

	/* Figma footer is `padding: 60px 0` with each row carrying its own
	   `padding: 0 80px` — the 80 comes from the shell here. */
	.foi-footer { padding-block: 60px; }


	/* Figma "Credits" row: a 153px brand column, then a 100px gap — which puts
	   the first link column at 80 + 153 + 100 = 333. */
	.foi-footer__top { grid-template-columns: 153px 1fr; gap: 100px; }
}


/* =========================================================
   SCROLL REVEAL
   ========================================================= */

/* Only hidden once JS confirms it can reveal them — no-JS shows everything. */
.foi-js .foi-reveal {
	opacity: 0;
	transform: translateY(var(--foiprp-reveal-y, 50px));
	transition: opacity 0.7s ease, transform 0.7s ease;
	will-change: opacity, transform;
}

.foi-js .foi-reveal.is-visible {
	opacity: 1;
	transform: none;
}

/* No JS, or motion turned off: show everything, no animation. */
@media (prefers-reduced-motion: reduce) {
	.foi-js .foi-reveal { opacity: 1; transform: none; transition: none; }
}

/* =========================================================
   MOTION
   ========================================================= */

@media (prefers-reduced-motion: reduce) {
	.foi-prp *,
	.foi-prp *::before,
	.foi-prp *::after {
		animation-duration: 0.001ms !important;
		transition-duration: 0.001ms !important;
	}
}
