/*
Theme Name: PainRecoveryPro
Theme URI: https://www.painrecoverypro.com/
Author: PainRecoveryPro
Author URI: https://www.painrecoverypro.com/
Description: A spacious health-editorial block theme for independent recovery-gear buying guides. Fraunces headings over DM Sans body copy, evergreen and clay identity, and commercial furniture — comparison tables, pick cards, eligibility notes, disclosures — built from core blocks so the words stay editable.
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 7.4
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: painrecoverypro
Tags: blog, one-column, two-columns, block-patterns, full-site-editing, custom-colors, custom-menu, editor-style, featured-images, accessibility-ready
*/

/*
 * MOBILE FIRST.
 *
 * Every rule outside a media query describes the phone layout. Wider layouts
 * are added on top through `min-width` queries only, so a browser that never
 * evaluates a query still receives a complete, usable page. There is not a
 * single `max-width` query in this sheet.
 *
 * Two device bands, carried over from the approved design:
 *
 *   42.5625rem  (681px)  tablet. One column becomes two or three: the card
 *                        grid, the proof bar, the finder's three choices, and
 *                        the newsletter's field-beside-button row.
 *   56.3125rem  (901px)  desktop. The masthead nav appears, the hero splits,
 *                        the guide body gains its sticky rail, and the archive
 *                        grid goes to three columns.
 *
 * Two content breakpoints, where the content — not the device band — decides:
 *
 *   30.0625rem  (481px)  the hero callouts stop crowding the artwork, and the
 *                        pick card's spec list can afford a term column.
 *   48rem       (768px)  the breadcrumb row takes its taller padding.
 *
 * Content breakpoints are commented where they appear so a later reader does
 * not "tidy" them into the device bands and break the thing they protect.
 *
 * Fonts are self-hosted. See theme.json's `fontFace` entries and assets/fonts/.
 * There is deliberately no `@import` here: an `@import` inside a stylesheet
 * cannot start until that stylesheet has been fetched and parsed, which chains
 * the font requests behind this file. Declaring the faces in theme.json puts
 * them in the document head, and functions.php preloads the two latin files so
 * they start with the HTML rather than after it.
 */

/* ==========================================================================
   Tokens

   The palette and rhythm come from the approved design. The identity is
   evergreen and clay in an editorial health-commerce register: a dark masthead
   assembly, white reading surfaces, warm paper only as a section ground, and an
   aqua utility accent used for marks and rules rather than fills.

   Change a token here rather than hard-coding a value in a component.
   ========================================================================== */

:root {
	/* Surfaces. White is the reading surface and carries most of the page; the
	   warm paper tone is a section ground that separates white bands, not a
	   field to set body copy on. */
	--prp-canvas: #f7f5ef;
	--prp-canvas-tint: #f1f4ec;
	--prp-surface: #ffffff;
	--prp-surface-muted: #f5f5f0;
	--prp-surface-mint: #dff1e8;

	/* Brand greens */
	--prp-forest: #173e34;
	--prp-forest-deep: #102e27;
	--prp-forest-raised: #234a40;
	--prp-forest-line: #45665c;
	--prp-green: #176c58;
	--prp-green-link: #16715b;
	--prp-green-ink: #14705a;
	--prp-mint: #7fd2bb;

	/* Utility accent. Aqua marks classification and eligibility: category
	   rules, glyph strokes, tick marks. It is never body text on white — it
	   does not carry enough contrast — so the text colour for those roles
	   stays --prp-green-link. */
	--prp-aqua: #17a88f;
	--prp-aqua-soft: #d8f0e8;

	/* Accent. --prp-clay is the identity orange and is used where contrast is
	   judged as a non-text UI colour (the focus ring, rules): 3.28:1 on white,
	   past the 3:1 bar. Anything that carries white *text* uses --prp-clay-cta,
	   the lightest orange that clears 4.5:1 — the identity orange itself only
	   reaches 3.28:1 behind white and fails as a button fill. */
	--prp-clay: #e06c42;
	--prp-clay-deep: #c95a33;
	--prp-clay-rule: #df7046;
	--prp-clay-cta: #c0522c;
	--prp-clay-cta-hover: #a84620;

	/* The evergreen band: the footer's ground, its rules and its ink. These
	   were the masthead's too until the light masthead of 2026-09-13; the
	   masthead now paints from the surface, line and ink tokens directly. */
	--prp-header: #173e34;
	--prp-header-deep: #0e2c25;
	--prp-header-line: rgba(127, 210, 187, 0.22);
	--prp-header-ink: #e6f2ec;
	--prp-header-ink-muted: #a9c5bb;

	/* Text */
	--prp-ink: #172521;
	--prp-ink-heading: #163d34;
	--prp-ink-heading-alt: #1c3d35;
	--prp-ink-body: #4c5c56;
	--prp-ink-muted: #6b7973;
	--prp-ink-subtle: #74817c;
	--prp-on-dark: #eaf4ef;
	--prp-on-dark-muted: #bcd0c9;

	/* Lines */
	--prp-line: #e8ebe8;
	--prp-line-strong: #dde4df;
	--prp-line-button: #d6ded9;
	--prp-line-card: #e5e8e4;

	/* Type. Fraunces carries the display hierarchy — optical sizing on, SOFT
	   and WONK pinned at 0, so it reads authoritative rather than quirky. DM
	   Sans carries everything a reader scans rather than reads: UI, navigation,
	   labels, metadata, buttons, and the small headings inside cards. */
	--prp-font-display: "Fraunces", Georgia, "Times New Roman", "Nimbus Roman", serif;
	--prp-font-body: "DM Sans", ui-sans-serif, system-ui, -apple-system,
		BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

	/* step-0 is the floor for anything a reader actually reads: body copy, form
	   fields and labels, card copy, buttons. Nothing below 1rem carries prose.
	   The two steps under it are for metadata, eyebrows and legal lines, where
	   smaller is a deliberate signal rather than a saving. */
	--prp-step--2: 0.75rem;   /* 12px  micro labels, eyebrows */
	--prp-step--1: 0.875rem;  /* 14px  meta / captions / legal */
	--prp-step-0: 1rem;       /* 16px  body and UI floor */
	--prp-step-1: 1.125rem;   /* 18px  lede / long-form reading copy */
	--prp-step-2: 1.375rem;   /* 22px  card headings */
	--prp-step-3: clamp(1.75rem, 1.15rem + 2.1vw, 2.5rem);  /* section headings */
	--prp-step-4: clamp(2.5rem, 1.55rem + 4.1vw, 4.25rem);  /* hero */

	/* Rhythm */
	--prp-gutter: clamp(1.25rem, 5vw, 4.5rem);
	--prp-measure: 38rem;
	--prp-max: 82.5rem;

	/* Vertical rhythm. Every band on the site takes its padding from one of
	   these three, and every one is fluid: compact on a phone, where scrolling
	   is what the reader pays, and open on wide screens, where the whitespace
	   between two sections is what says they are two ideas.
	     -sm  compact utility bands: page heads, the proof bar
	     base standard content sections
	     -lg  the hero, and anything that has to carry a page on its own */
	--prp-section-sm: clamp(2.5rem, 1.9rem + 2.4vw, 3.5rem);
	--prp-section: clamp(3.25rem, 2.35rem + 3.6vw, 5.5rem);
	--prp-section-lg: clamp(4rem, 2.8rem + 5vw, 7rem);

	/* Gaps. Cards sit on the first, major layout columns on the second. */
	--prp-gap-card: clamp(1.0625rem, 0.75rem + 1.3vw, 1.875rem);
	--prp-gap-grid: clamp(1.75rem, 1.1rem + 2.6vw, 3.5rem);

	/* Air under a section heading before its content starts. */
	--prp-space-head: clamp(1.5rem, 1.1rem + 1.6vw, 2.5rem);

	--prp-radius-sm: 0.375rem;
	--prp-radius: 0.5rem;
	--prp-radius-lg: 0.75rem;
	--prp-radius-xl: 1rem;

	/* Elevation. The design separates things with hairline rules first and
	   shadow second, so these stay light. */
	--prp-shadow-card: 0 10px 22px rgba(18, 51, 43, 0.07);
	--prp-shadow-float: 0 14px 30px rgba(18, 51, 43, 0.14);
	--prp-shadow-art: 0 24px 48px rgba(18, 51, 43, 0.14);
	--prp-shadow-primary: 0 6px 16px rgba(23, 108, 88, 0.16);

	/* Focus. Dark bands re-point --prp-focus to mint, further down this sheet,
	   so the ring stays visible on evergreen. */
	--prp-focus: var(--prp-clay);

	/* Motion */
	--prp-ease: cubic-bezier(0.2, 0.8, 0.3, 1);
	--prp-duration: 200ms;

	/* The masthead's brand row: the height the lockup was approved at, and on
	   a phone the whole masthead. From the desktop step (Masthead, below) the
	   navigation row sits under it and --prp-header-nav-row is that row's
	   height; --prp-header-stuck is the two together, the whole of what stays
	   stuck. Stated as tokens because the sticky offset below derives from
	   them. */
	--prp-header-row: 4.25rem;
	--prp-header-nav-row: 0rem;
	--prp-header-stuck: calc(var(--prp-header-row) + var(--prp-header-nav-row));

	/* Distance a sticky rail or an in-page anchor keeps clear of the sticky
	   masthead: what is stuck plus 1.5rem of air. One value, so the two
	   cannot drift apart. */
	--prp-sticky-offset: calc(var(--prp-header-stuck) + 1.5rem);
}

/* ==========================================================================
   Base
   ========================================================================== */

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

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

body {
	margin: 0;
	background: var(--prp-canvas);
	color: var(--prp-ink);
	font-family: var(--prp-font-body);
	font-size: var(--prp-step-0);
	line-height: 1.55;
	font-optical-sizing: auto;
	-webkit-font-smoothing: antialiased;
}

/* Fraunces is the display voice. Tracking opens as the size drops and the
   leading loosens, so a 22px card title stays scannable while a hero line still
   sets tight. Small headings inside cards and rails opt back into
   --prp-font-body in their own components below. */
h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var(--prp-font-display);
	font-weight: 600;
	color: var(--prp-ink-heading);
	margin: 0;
}

h1 {
	letter-spacing: -0.025em;
	line-height: 1.05;
}

h2 {
	letter-spacing: -0.02em;
	line-height: 1.12;
}

h3 {
	letter-spacing: -0.01em;
	line-height: 1.25;
}

p {
	margin: 0;
}

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

img {
	height: auto;
}

a {
	color: inherit;
	text-decoration: none;
}

button {
	font: inherit;
}

:where(a, button, [tabindex], summary, input, select, textarea):focus-visible {
	outline: 3px solid var(--prp-focus);
	outline-offset: 3px;
	border-radius: 4px;
}

/* The dark band re-points the focus ring: clay on evergreen is too close in
   value to read as a ring, mint is unmistakable. */
.prp-footer {
	--prp-focus: var(--prp-mint);
}

/* ==========================================================================
   Layout primitives
   ========================================================================== */

/*
 * The content column shared by every section, and the reason theme.json sets
 * `useRootPaddingAwareAlignments` to false with zero root padding: the gutter
 * belongs to this class, applied once per band, rather than to the document.
 * Core's root-padding mechanism would add its own padding back to the children
 * of every `alignfull` group, which double-pads any band that also carries a
 * shell — so the two systems are not mixed.
 */
.prp-shell {
	width: 100%;
	max-width: var(--prp-max);
	margin-inline: auto;
	padding-inline: var(--prp-gutter);
}

/*
 * Core's flow layout writes `margin-block-start: var(--wp--style--block-gap)`
 * onto every block that follows a sibling. That is the right default for post
 * content, and wrong everywhere the design already declares its own spacing:
 * these containers space their children with a flex or grid `gap`, or the
 * children carry explicit margins drawn to the approved rhythm. Left alone,
 * core's 24px lands on top of both and every one of these components grows.
 *
 * Post content is deliberately not in this list — `.prp-prose` and the guide
 * body want core's block gap, which is what makes a paragraph an editor adds
 * sit correctly without touching CSS.
 */
/*
 * Bands sit flush against each other.
 *
 * The design separates one band from the next with a change of ground — warm
 * paper against white, sage against paper — and with the section padding inside
 * each one. Core's flow layout puts its block gap between them as well, which
 * opens a strip of the previous band's colour above every section and reads as
 * a seam.
 *
 * Two selectors, both deliberately narrow. The first is the document's own
 * children: template parts and the main element, which are always flush. The
 * second is only the full-width bands inside post content — an ordinary
 * paragraph or heading an editor adds to a page still gets core's spacing,
 * which is what keeps the templates editable without touching CSS.
 */
.wp-site-blocks > *,
.wp-block-post-content > .alignfull,
/*
 * `main` is a flow group in every template, so core's block gap opened a 24px
 * seam between each band inside it — most visibly between the breadcrumb row
 * and the head directly beneath it, where it read as an empty strip in a
 * different colour from both. The reset above already does this one level up,
 * at `.wp-site-blocks`; the bands inside `main` were simply never reached.
 * Each band states its own `padding-block`, so the gap has nothing to add.
 *
 * The class is carried for weight, not for reach. Global styles state the gap
 * as `:root :where(.is-layout-flow) > *`, and `:root` alone makes that one
 * class heavy — a bare `main > *` ties on nothing and loses on source order.
 * `main` is a `wp:group` in every template, so naming the class it already has
 * settles the cascade without inventing a selector.
 */
main.wp-block-group > *,
.prp-shell > *,
.prp-home > *,
.prp-guide > *,
.prp-header > *,
.prp-header__bar > *,
.prp-header__nav > *,
.prp-featured__text > *,
.prp-promise__body > *,
.prp-grid .wp-block-post-template > *,
.prp-card > *,
.prp-card__body > *,
.prp-section-head > *,
.prp-section-head__text > *,
.prp-page-head__inner > *,
.prp-page-head__text > *,
.prp-guide__mast-inner > *,
.prp-guide__mast-text > *,
.prp-guide__body > *,
.prp-guide__content > *,
.prp-page__body > *,
.prp-page__content > *,
.prp-meta > *,
.prp-rail > *,
.prp-panel > *,
.prp-picks > *,
.prp-pick > *,
.prp-pick__verdict > *,
.prp-pick__column > *,
.prp-faqs > *,
.prp-finder__grid > *,
.prp-finder__panel > *,
.prp-newsletter__inner > *,
.prp-newsletter__form > *,
.prp-footer__inner > *,
.prp-footer__disclosures > *,
.prp-footer__meta > *,
.prp-archive__body > *,
.prp-404__inner > *,
.prp-topics > *,
.prp-destinations > *,
.prp-note > *,
.prp-flow-reset > * {
	margin-block: 0;
}

.prp-band {
	padding-block: var(--prp-section);
}

.prp-band--sm {
	padding-block: var(--prp-section-sm);
}

.prp-band--lg {
	padding-block: var(--prp-section-lg);
}

.prp-surface {
	background: var(--prp-surface);
}

.prp-canvas {
	background: var(--prp-canvas);
}

/*
 * The tinted masthead ground, shared by the homepage hero, every page header,
 * the guide masthead and the 404. Two soft radial washes over a diagonal
 * canvas ramp: mint high on the right, a trace of clay low on the left.
 */
.prp-tinted {
	background:
		radial-gradient(
			80% 70% at 82% 10%,
			rgba(191, 216, 204, 0.38) 0%,
			rgba(191, 216, 204, 0) 62%
		),
		radial-gradient(
			60% 60% at 4% 96%,
			rgba(224, 169, 124, 0.14) 0%,
			rgba(224, 169, 124, 0) 58%
		),
		linear-gradient(135deg, var(--prp-canvas) 0%, var(--prp-canvas-tint) 100%);
}

.prp-skip-link {
	position: absolute;
	left: 50%;
	top: 0;
	transform: translate(-50%, -120%);
	z-index: 100;
	background: var(--prp-forest);
	color: var(--prp-on-dark);
	padding: 0.75rem 1.25rem;
	border-radius: 0 0 var(--prp-radius) var(--prp-radius);
	font-size: var(--prp-step-0);
	font-weight: 700;
	transition: transform var(--prp-duration) var(--prp-ease);
}

.prp-skip-link:focus-visible {
	transform: translate(-50%, 0);
}

.prp-visually-hidden,
.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/*
 * Category label. The short aqua rule is the site's classification marker — it
 * says "this belongs to a recovery domain" on cards, page heads and listings
 * alike, and it is why classification never needs a pill.
 */
.prp-eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	font-size: var(--prp-step--2);
	font-weight: 700;
	color: var(--prp-green-link);
	margin: 0;
}

.prp-eyebrow::before {
	content: "";
	flex: none;
	width: 1.125rem;
	height: 2px;
	border-radius: 1px;
	background: var(--prp-aqua);
}

/* Icons carry geometry only; size, stroke weight and colour arrive here or at
   the call site, which is what lets a tick inherit the colour of the row it
   sits in. */
.prp-icon {
	flex: none;
	display: inline-block;
	vertical-align: middle;
}

/* ==========================================================================
   Actions

   Every action on this site navigates somewhere, so these are links styled as
   buttons rather than <button> elements — the correct element for keyboard and
   screen-reader users.
   ========================================================================== */

.prp-action {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	border-radius: var(--prp-radius);
	font-weight: 760;
	line-height: 1.2;
	text-decoration: none;
	transition:
		transform var(--prp-duration) var(--prp-ease),
		background-color var(--prp-duration) var(--prp-ease),
		color var(--prp-duration) var(--prp-ease);
}

.prp-action--primary,
.prp-action--secondary {
	padding: 0.875rem 1.25rem;
	font-size: var(--prp-step-0);
}

.prp-action--primary {
	background: var(--prp-green);
	color: #fff;
	box-shadow: var(--prp-shadow-primary);
}

.prp-action--secondary {
	background: var(--prp-surface);
	color: var(--prp-forest-raised);
	border: 1px solid var(--prp-line-button);
}

.prp-action--pill {
	background: var(--prp-clay-cta);
	color: #fff;
	padding: 0.6875rem 1.0625rem;
	font-size: var(--prp-step--1);
	font-weight: 700;
}

/*
 * The text action carries no padding by design — it is a link, not a button,
 * and the section head it sits in is aligned to its baseline. At 16px/1.2 its
 * box measured 19.2px tall, under the 24 CSS px WCAG 2.5.8 asks of a target
 * that is not inline in a sentence. The minimum is set on the box rather than
 * added as padding so the type, the colour and the optical alignment are
 * unchanged and only the hit area grows.
 */
.prp-action--text {
	min-height: 1.5rem;
	font-size: var(--prp-step-0);
	font-weight: 800;
	color: var(--prp-green-link);
	white-space: nowrap;
}

@media (hover: hover) {
	.prp-action--primary:hover,
	.prp-action--pill:hover {
		transform: translateY(-1px);
	}

	.prp-action--primary:hover {
		background: #135a49;
		color: #fff;
	}

	.prp-action--pill:hover {
		background: var(--prp-clay-cta-hover);
		color: #fff;
	}

	.prp-action--secondary:hover {
		color: var(--prp-green-link);
	}

	.prp-action--text:hover {
		color: var(--prp-forest);
	}
}

/* ==========================================================================
   Promo bar

   Top band of the masthead assembly, on the tinted canvas rather than on
   white, so the assembly still steps down into the page: the notice, then
   the white masthead, then the page's own ground.
   ========================================================================== */

.prp-promo {
	background: var(--prp-canvas-tint);
	color: var(--prp-ink-body);
	border-bottom: 1px solid var(--prp-line-strong);
}

.prp-promo p {
	text-align: center;
	padding-block: 0.5rem;
	font-size: var(--prp-step--2);
	font-weight: 500;
	letter-spacing: 0.04em;
	color: inherit;
}

/* ==========================================================================
   Masthead

   Two rows on white since the founder's direction of 2026-09-13, in the
   composition of the approved reference: a brand row — the "Independent
   recovery guides" line at the left, the wordmark large and centred, "Search
   guides" at the right — a hairline, and a navigation row with the section
   links centred under it. On a phone the brand row is the lockup and core's
   toggle, and the drawer that opens under the masthead carries the links and
   the search field.

   The rows arrive at the site's own desktop band, 56.3125rem (901px), not at
   a content breakpoint of their own: measured at that width the brand row's
   three parts need about 640px of the 811px between the gutters and the five
   labels about 520px, so nothing has to be squeezed or dropped.

   "Search guides" is a disclosure — a core/details block around the
   core/search block — so it works with no script at all: the summary is a
   button to the keyboard and to assistive technology, and the form it
   reveals is the same `?s=` route the search template answers. functions.php
   adds the one courtesy a native disclosure lacks, putting the caret in the
   field on open and closing on Escape; with the script blocked the summary
   still toggles the form and the form still submits.

   The masthead is sticky, on the template part's own wrapper rather than on
   the group inside it. Every template renders the part as
   `<header class="wp-block-template-part">` around `.prp-header`, and a
   sticky element can only move within its parent's box: on the inner group,
   a parent exactly the masthead's own height, it never stuck at all
   (measured 2026-09-12: 700px down the front page the masthead sat at top
   -664px). The wrapper is a direct child of `.wp-site-blocks`, the full
   height of the page, so it has the whole document to stick in.
   `header.wp-block-template-part` is unambiguous: the footer part renders as
   `<footer>`, the promo bar and the newsletter as `<div>`. Both rows stay
   stuck, and --prp-header-stuck is their height, which is what the sticky
   rails and in-page anchors keep clear of.
   ========================================================================== */

header.wp-block-template-part {
	position: sticky;
	top: 0;
	z-index: 20;
}

/*
 * Positioned rather than static, because the open drawer and the open search
 * form below are placed against this box.
 *
 * A grid on a phone: the brand row in the first track and the navigation
 * block, which is only its toggle there, in the second — so the toggle sits
 * in the brand row without leaving the block that owns it and the drawer it
 * opens. From the desktop step the grid is gone and the two rows stack.
 */
.prp-header {
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	background: var(--prp-surface);
	border-bottom: 1px solid var(--prp-line-strong);
}

/*
 * The brand row. Its own shell rather than `.prp-shell`, because on a phone
 * the gutter at its end belongs to the toggle beside it.
 *
 * The row wraps under pressure, and the pressure is text zoom: every box in
 * it is sized by its own type, so at 200% text they are twice as wide while
 * the viewport is not, and a row that cannot wrap has one way to settle
 * that, past the right edge. At 100% nothing wraps at any width the row
 * exists at.
 */
.prp-header__bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	align-content: center;
	gap: 0.5rem 1.5rem;
	width: 100%;
	max-width: var(--prp-max);
	margin-inline: auto;
	min-height: var(--prp-header-row);
	padding-block: 0.5rem;
	padding-inline: var(--prp-gutter) 0;
}

/* The navigation row: on a phone, the cell that holds the toggle. */
.prp-header__nav {
	display: flex;
	align-items: center;
	justify-content: center;
	padding-inline-end: var(--prp-gutter);
}

/*
 * The line at the row's left. Desktop furniture, like the search disclosure
 * at the row's right: on a phone the row is the lockup and the toggle.
 */
.prp-header__kicker {
	display: none;
	margin: 0;
	font-size: var(--prp-step--2);
	font-weight: 700;
	line-height: 1.2;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	text-wrap: balance;
	color: var(--prp-green-link);
}

/* Brand lockup. The base rules are shared with the footer's sign-off, which
   keeps the light wordmark and the reversed mark they describe; the masthead
   restates its own colours below them. */
.prp-brand {
	display: inline-flex;
	align-items: center;
	gap: 0.625rem;
	border-radius: 0.75rem;
	text-decoration: none;
}

.prp-brand__mark {
	flex: none;
	object-fit: contain;
	width: 2.375rem;
	height: 2.375rem;
	/* Kept without the tile it used to inset the symbol from: it is what holds
	   the P at the size the lockup was approved at, so dropping it here would
	   silently grow the mark by a quarter. */
	padding: 0.25rem;
}

/*
 * The wordmark holds one line and breaks at one place.
 *
 * `white-space: nowrap` kept the lockup intact and, on a phone at 200% text,
 * made it the widest thing on the site: 393px of unbreakable word in 335px of
 * shell, which no amount of wrapping around it can absorb. The markup carries
 * a single `<wbr>` between "PainRecovery" and "Pro", the only break
 * opportunity in the string, so normal wrapping produces the two-line lockup
 * and nothing else. At every width where the word fits, it still sets on one
 * line.
 */
.prp-brand__word {
	font-weight: 800;
	letter-spacing: -0.04em;
	font-size: 1.3125rem;
	line-height: 1;
	color: #f2f8f5;
}

.prp-brand__word em {
	font-style: normal;
	color: var(--prp-mint);
}

/*
 * The masthead's lockup: the approved mark as supplied, evergreen on the
 * white ground, and the wordmark in the display serif — the site's one
 * heading voice, so the name at the top of the page is set the way every
 * title under it is. Shrinkable, so the wordmark can take its one `<wbr>`
 * break at large text sizes instead of pushing the row wide.
 */
.prp-header .prp-brand {
	flex: 0 1 auto;
	min-width: 0;
}

.prp-header .prp-brand__word {
	font-family: var(--prp-font-display);
	font-weight: 700;
	font-size: 1.5rem;
	letter-spacing: -0.025em;
	color: var(--prp-ink);
}

.prp-header .prp-brand__word em {
	color: var(--prp-green);
}

/*
 * The search disclosure. Closed, it is the words "Search guides" at the end
 * of the brand row; open, the form is a sheet under the whole masthead, the
 * same placement the drawer uses. Hidden below the desktop step, where the
 * drawer's copy of the form is the search.
 */
.prp-header__search {
	display: none;
	flex: 1 1 0;
	text-align: end;
}

.prp-header__search > summary {
	display: inline-flex;
	align-items: center;
	min-height: 2.75rem;
	padding-inline: 0.25rem;
	border-radius: var(--prp-radius-sm);
	font-size: 0.9375rem;
	font-weight: 700;
	line-height: 1.2;
	white-space: nowrap;
	color: var(--prp-ink);
	cursor: pointer;
	list-style: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-header__search > summary::-webkit-details-marker {
	display: none;
}

.prp-header__search[open] > summary {
	color: var(--prp-green-link);
}

/* The form is the site's own search form, `.prp-search__form`, the one the
   search template renders; here it lies across the masthead's full width and
   its field sits centred at the width a query is comfortable in. */
.prp-header__search .wp-block-search {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	z-index: 1;
	max-width: none;
	margin: 0;
	padding: 1.25rem var(--prp-gutter) 1.5rem;
	background: var(--prp-surface);
	border-bottom: 1px solid var(--prp-line-strong);
	box-shadow: 0 18px 32px -20px rgba(23, 37, 33, 0.28);
}

.prp-header__search .wp-block-search__inside-wrapper {
	max-width: 34rem;
	margin-inline: auto;
}

@media (prefers-reduced-motion: no-preference) {
	.prp-header__search[open] .wp-block-search {
		animation: prp-sheet-in 180ms var(--prp-ease);
	}
}

@keyframes prp-sheet-in {
	from {
		opacity: 0;
		transform: translateY(-0.375rem);
	}

	to {
		opacity: 1;
		transform: none;
	}
}

/*
 * Navigation.
 *
 * core/navigation with `overlayMenu: "mobile"`. Core supplies the toggle, the
 * focus trap and the open/close script; everything below is presentation, so
 * the theme ships no navigation JavaScript of its own. The open drawer's
 * colours — `surface` and `ink` — are the block's own overlay attributes,
 * stated in the part: core paints them through preset classes that carry
 * `!important`, so a background restated here would only lose to them.
 */
.prp-nav {
	font-size: var(--prp-step-0);
	font-weight: 600;
	color: var(--prp-ink);
	/*
	 * Core sets `position: relative` on the navigation block so submenus can
	 * anchor to it. This menu has no submenus, and that relative position is
	 * what the open panel below would otherwise resolve `top: 100%` against,
	 * placing it under the nav's own box, part-way up the masthead, instead
	 * of under the masthead.
	 */
	position: static;
}

.prp-nav .wp-block-navigation-item__content {
	text-decoration: none;
	padding-block: 0.5rem;
	transition: color var(--prp-duration) var(--prp-ease);
}

@media (hover: hover) {
	/* Core sets `color: inherit` on the link at three classes; a hover has to
	   outrank that or it never shows. Four classes here. */
	.prp-nav .wp-block-navigation-item__content.wp-block-navigation-item__content:hover {
		color: var(--prp-green-link);
	}

	.prp-header__search > summary:hover {
		color: var(--prp-green-link);
	}
}

/*
 * One switch point, not two.
 *
 * `overlayMenu: "mobile"` collapses the list at core's own 600px, while the
 * toggle beside it would be hidden at the theme's step, so between the two
 * the masthead carried both, the inline list and the hamburger that exists to
 * replace it. The closed list is hidden here and handed back at the same step
 * that takes the toggle away, so exactly one of the two is ever on screen.
 *
 * `:not(.is-menu-open)` is what keeps the overlay working: the open panel is
 * the same element, and hiding it unconditionally would leave the toggle with
 * nothing to open.
 */
.prp-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
	display: none;
}

.prp-nav .wp-block-navigation__responsive-container-open,
.prp-nav .wp-block-navigation__responsive-container-close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.75rem;
	height: 2.75rem;
	border: 1px solid var(--prp-line-strong);
	border-radius: var(--prp-radius-sm);
	background: var(--prp-surface);
	color: var(--prp-ink);
	cursor: pointer;
}

/* In flow, at the row's end. `margin: 0` because core's flex layout on the
   navigation block hands every child a margin reset at one class, and an
   unstated margin here would tie with it. */
.prp-nav .wp-block-navigation__responsive-container-open {
	margin: 0;
}

.prp-nav .wp-block-navigation__responsive-container-close {
	border-color: transparent;
}

/*
 * The mobile panel is a sheet under the masthead, not a full-screen takeover.
 * Core's default overlay covers the page; the approved design keeps the
 * masthead visible and drops the list beneath it, so the reader never loses the
 * brand or their place. Core's own `is-menu-open` positioning is replaced
 * rather than extended: half of it would otherwise still apply.
 */
.prp-nav .wp-block-navigation__responsive-container.is-menu-open {
	/*
	 * Anchored to the masthead rather than to the viewport. `.prp-header` is
	 * positioned, so `top: 100%` puts the panel directly under it whatever sits
	 * above: with the promo bar in place a fixed offset lands 55px too high and
	 * covers the nav it belongs to, and it would be wrong again the moment
	 * that bar is edited or removed.
	 */
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	/* Core's open state sets `inset: 0` for its full-screen overlay. Left in
	   place, its `bottom: 0` pins the panel to the masthead's own lower edge
	   while `top: 100%` pins it to the same line, and the box collapses to its
	   borders. `auto` hands the height back to the content. */
	bottom: auto;
	max-height: 70dvh;
	overflow-y: auto;
	padding: 0;
	border-top: 1px solid var(--prp-line-strong);
	border-bottom: 1px solid var(--prp-line-strong);
	box-shadow: 0 18px 32px -20px rgba(23, 37, 33, 0.28);
}

/*
 * Core lays the open overlay out with the same flex alignment the desktop bar
 * uses, right-justified and sized to its content, because its own design is a
 * centred full-screen sheet. Here the panel is a full-width drawer whose rows
 * carry a hairline the width of the shell, so every level from the dialog down
 * has to be told to fill the width and start from the left.
 */
.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-close {
	width: 100%;
	max-width: var(--prp-max);
	margin-inline: auto;
	padding: 0 var(--prp-gutter);
}

.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-dialog {
	display: flex;
	flex-direction: column;
	width: 100%;
	margin: 0;
	padding: 0;
	position: static;
}

.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-content {
	width: 100%;
	flex-direction: column;
	align-items: stretch;
	justify-content: flex-start;
	/* Core reserves 56px at the top for the close button its overlay puts
	   there. The close button is a row of its own in this drawer (below), so
	   the space core was holding for an overlapping one is dead. */
	padding: 0;
	/* The column inherits the navigation block's 1.5rem block gap, which is a
	   paragraph rhythm: between the link list and the search field beneath it
	   the list's own bottom padding and the field's top padding already meet,
	   and the inherited gap opened a 60px hole between them. Measured at 390px
	   before this line, 36px after. */
	gap: 0;
}

/*
 * The drawer's own close control.
 *
 * Core's open button only opens (`actions.openMenuOnClick`); the drawer used
 * to hide core's close button and leave a touch reader with Escape, which a
 * phone has no key for, or a tap outside, which nothing on screen suggests.
 * Core's close button is shown instead: 44px square, the same hairline tile
 * as the toggle, at the head of the drawer on the right, the corner the
 * reader just tapped, and carrying core's own `aria-label="Close menu"`.
 * Static rather than core's absolute placement, so it takes a row of the
 * drawer and pushes the list down instead of overlapping it.
 *
 * While the drawer is open the masthead's toggle goes transparent and inert
 * rather than `display: none`: core returns focus to the toggle when the
 * drawer closes, and an element that is not rendered cannot take it. An
 * `opacity: 0` button still can, and it is back on screen by the time the
 * class flips. The dialog is `aria-modal`, so it is not announced meanwhile.
 */
.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-close {
	display: inline-flex;
	position: static;
	align-self: flex-end;
	flex: none;
	width: 2.75rem;
	height: 2.75rem;
	margin: 0.75rem 0 0;
	padding: 0;
	border-color: var(--prp-line-strong);
	z-index: auto;
}

.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__responsive-container-close svg {
	width: 1.25rem;
	height: 1.25rem;
}

.prp-nav:has(.wp-block-navigation__responsive-container.is-menu-open)
	.wp-block-navigation__responsive-container-open {
	opacity: 0;
	pointer-events: none;
}

.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation__container {
	display: grid;
	gap: 0.25rem;
	width: 100%;
	align-items: stretch;
	justify-content: stretch;
	padding-block: 0.75rem 1.25rem;
}

.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item {
	display: block;
}

.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-navigation-item__content {
	display: block;
	padding: 0.8125rem 0;
	font-size: 1rem;
	font-weight: 600;
	color: var(--prp-ink);
	border-bottom: 1px solid var(--prp-line);
}

/*
 * The search field, at the foot of the drawer.
 *
 * A `core/search` block sits last inside the navigation block, and core
 * renders it as a sibling of the link list rather than as an item in it,
 * which is what puts it under the list in the column the drawer lays out. It
 * is the real search form: `GET /?s=`, the same route the search template
 * answers, so it works with the overlay script blocked. The masthead's
 * disclosure carries its own copy of the form, and exactly one of the two is
 * displayed at any width; the drawer's is hidden again at the desktop step
 * below.
 *
 * Last rather than first for a reason that only shows on a phone: core's
 * overlay script focuses the first focusable element in the open drawer, and
 * with the field first that was the text input, which raises the software
 * keyboard over the drawer the reader just opened. With the links first, the
 * focus lands on "Latest" and the keyboard stays down until the reader asks
 * for it.
 */
.prp-nav
	.wp-block-navigation__responsive-container.is-menu-open
	.wp-block-search {
	width: 100%;
	max-width: none;
	margin: 0;
	padding-block: 1rem 1.25rem;
}

/*
 * The desktop rows, from the site's desktop band: the brand row opens out
 * into its three parts and the navigation row appears under it.
 */
@media (min-width: 56.3125rem) {
	:root {
		--prp-header-row: 4.5rem;
		--prp-header-nav-row: 3rem;
	}

	.prp-header {
		display: block;
	}

	.prp-header__bar {
		padding-inline: var(--prp-gutter);
	}

	/*
	 * The row's two sides share what the wordmark leaves, equally, which is
	 * what centres it: each grows from nothing, so the wordmark sits on the
	 * row's centre line at every width where both sides fit their half. The
	 * kicker may wrap so that it does: from 901px to about 935px its half is
	 * a few pixels short of its one line, and it takes two balanced lines
	 * there rather than pushing the wordmark 16px off centre (measured at
	 * 901px with the line unbreakable). Its floor is left at flex's own
	 * `min-width: auto`, its longest word: a floor of zero let it collapse to
	 * 15px at 200% text, with the words spilling over the wordmark, where
	 * the longest-word floor wraps the row instead. "Search guides" keeps
	 * its one line; it is narrower than any half the row has.
	 */
	.prp-header__kicker {
		display: block;
		flex: 1 1 0;
	}

	.prp-header__search {
		display: block;
	}

	/* The wordmark alone, large, as the reference sets it; the mark is the
	   phone lockup's. */
	.prp-header .prp-brand__mark {
		display: none;
	}

	.prp-header .prp-brand__word {
		font-size: 2.375rem;
	}

	.prp-header__nav {
		min-height: var(--prp-header-nav-row);
		padding-inline: var(--prp-gutter);
		border-top: 1px solid var(--prp-line-strong);
	}

	.prp-nav {
		font-size: 0.9375rem;
		font-weight: 700;
	}

	.prp-nav .wp-block-navigation__responsive-container-open {
		display: none;
	}

	/* The list is the navigation from here up; core's own closed-state value. */
	.prp-nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: block;
	}

	/*
	 * Inline items are sized by their own labels.
	 *
	 * Core leaves the list at the flex defaults, so `.wp-block-navigation__container`
	 * takes `flex-grow: 1` from its `:only-child` rule and every item keeps
	 * the initial `flex: 0 1 auto`. That shrink factor is a fault: when a row
	 * is a few pixels short of what the labels intrinsically need, flex takes
	 * those pixels off the two widest items, "recovery" drops to a second line
	 * and the box keeps the width it was shrunk to while the text inside it
	 * occupies half of that. So the list is content-sized rather than filling,
	 * the items are told not to shrink, and the labels are told not to break.
	 * A label is a label: one line, its own width, at every width where this
	 * list is the navigation.
	 *
	 * The row itself may wrap, whole labels at a time, with no gap between
	 * the lines because each label carries its own padding. At 100% text it
	 * never does: the five labels need about 550px of a row that is never
	 * under 800. At 200% text they need 1012px of 1009 (measured at 1024px),
	 * and a row that cannot wrap has one way to settle that, past the edge.
	 */
	.prp-nav .wp-block-navigation__container {
		flex-grow: 0;
		flex-wrap: wrap;
		justify-content: center;
		gap: 0 2.5rem;
	}

	.prp-nav .wp-block-navigation-item {
		flex: 0 0 auto;
	}

	.prp-nav .wp-block-navigation-item__content {
		white-space: nowrap;
		padding-block: 0.875rem;
		line-height: 1.2;
	}

	/* On desktop the search is the disclosure in the brand row, so the copy
	   of the form inside the navigation block is the same destination twice
	   and has to go. */
	.prp-nav .wp-block-search.prp-nav__search {
		display: none;
	}

	/* Core renders a search block inside a navigation as a sibling of the link
	   list; should a future core wrap it in a list item instead, the empty item
	   would still spend a gap in the row, so the wrapper goes with it. */
	.prp-nav .wp-block-navigation-item:has(> .prp-nav__search) {
		display: none;
	}
}

/* With room to spare the links open out. */
@media (min-width: 84rem) {
	.prp-nav .wp-block-navigation__container {
		gap: 0 3rem;
	}
}

/* ==========================================================================
   Footer
   ========================================================================== */

.prp-footer {
	background: linear-gradient(
		180deg,
		var(--prp-header) 0%,
		var(--prp-header-deep) 100%
	);
	color: var(--prp-header-ink-muted);
	font-size: var(--prp-step--1);
}

.prp-footer__inner {
	display: grid;
	gap: 1.5rem;
	/* Asymmetric on purpose: the footer needs air above it to separate it from
	   the page, but a full section step under the legal links just reads as an
	   empty band at the bottom of the screen. */
	padding-block: var(--prp-section) var(--prp-section-sm);
}

.prp-footer .prp-brand {
	margin-bottom: 0.25rem;
}

/* The footer lockup is a step smaller than the masthead's — it is a sign-off
   rather than the site's identity at the top of the page. */
.prp-footer .prp-brand__mark {
	width: 2.125rem;
	height: 2.125rem;
}

.prp-footer__disclosures {
	display: grid;
	gap: 0.625rem;
	max-width: 52rem;
	line-height: 1.6;
}

.prp-footer__disclosures p {
	color: inherit;
	font-size: inherit;
}

.prp-footer__disclosures strong {
	color: var(--prp-header-ink);
	font-weight: 700;
}

/*
 * Desktop puts the sign-off lockup beside the disclosures rather than above
 * them: two balanced columns, with the copyright and legal links still running
 * the full width underneath. Below this width the grid stays single-column, so
 * the phone layout is the one that needs no rules at all.
 */
@media (min-width: 56.3125rem) {
	.prp-footer__inner {
		grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
		column-gap: var(--prp-gap-grid);
		align-items: start;
	}

	.prp-footer__meta {
		grid-column: 1 / -1;
	}

	/* The lockup no longer has the disclosures directly under it to clear. */
	.prp-footer .prp-brand {
		margin-bottom: 0;
	}
}

.prp-footer__meta {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 0.9375rem;
	padding-top: 1.25rem;
	border-top: 1px solid var(--prp-header-line);
	font-size: var(--prp-step--2);
}

.prp-footer__meta p {
	color: inherit;
	font-size: inherit;
}

.prp-footer__meta .wp-block-navigation__container,
.prp-footer__meta ul {
	display: flex;
	flex-wrap: wrap;
	gap: 0.9375rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

/*
 * The policy links are the smallest type on the site — 12px, which is the
 * legal-line step — and inline they gave a 16px box, well under the 24 CSS px
 * WCAG 2.5.8 asks of a target that is not inline in a sentence. These are a
 * list of destinations, not words in a sentence, so the exception does not
 * cover them. The box is grown, not the type: the row is already a wrap flex
 * with a 15px gap, so 24px boxes still clear each other and the sign-off row
 * grows by 8px.
 *
 * The minimum lands on the box rather than on padding because `tools/verify.mjs`
 * asserts the footer policy nav as bare `<a href="…">Label</a>` markup — the
 * fix has to be reachable from CSS alone.
 */
.prp-footer__meta a,
.prp-footer__meta .wp-block-navigation-item__content {
	display: inline-flex;
	align-items: center;
	min-height: 1.5rem;
	color: inherit;
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-footer__meta a:hover,
.prp-footer__meta .wp-block-navigation-item__content:hover {
	color: var(--prp-mint);
}
/* ==========================================================================
   Hero

   The featured guide is the hero since the refinement of 2026-09-12: the
   page's H1 is the guide's title, the lede its excerpt, the artwork its
   photograph, and the two actions lead into it and into the library. What
   used to be a card beside a brand statement is the statement now: the site
   leads with what it has written, and the promise it makes about that
   writing moved down the page to the commitments band, where it qualifies
   the guides rather than competing with the first one.

   The photograph carries no card. It sits on the tinted ground with the
   guide masthead's own radius and shadow, so the hero reads as a masthead the
   reader has not clicked into yet, not as a product tile. The text column
   states the guide the way that masthead does, category chip, byline and
   reading time included, for the same reason. `blocks/featured-guide/render.php`
   decides which guide, and renders the site's promise in the guide's place
   while nothing is published.
   ========================================================================== */

.prp-hero {
	background:
		radial-gradient(
			90% 70% at 78% 18%,
			rgba(191, 216, 204, 0.42) 0%,
			rgba(191, 216, 204, 0) 60%
		),
		radial-gradient(
			70% 60% at 6% 92%,
			rgba(224, 169, 124, 0.16) 0%,
			rgba(224, 169, 124, 0) 58%
		),
		linear-gradient(135deg, var(--prp-canvas) 0%, var(--prp-canvas-tint) 100%);
}

.prp-hero__shell {
	padding-block: var(--prp-section);
}

.prp-featured__grid {
	display: grid;
	gap: 1.75rem;
	align-items: center;
}

.prp-featured__text {
	display: flex;
	flex-direction: column;
	gap: 1.125rem;
	max-width: 40rem;
	min-width: 0;
}

/* The classification marker every card carries, naming what this block is:
   the featured guide, not the site talking about itself. */
.prp-featured__label {
	margin: 0;
}

.prp-featured__title {
	font-size: clamp(1.875rem, 1.2rem + 2.2vw, 2.875rem);
	line-height: 1.06;
	letter-spacing: -0.025em;
	color: var(--prp-ink-heading);
	margin: 0;
	text-wrap: balance;
}

.prp-featured__title a {
	color: inherit;
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-featured__title a:hover {
	color: var(--prp-green-link);
}

.prp-featured__excerpt {
	font-size: var(--prp-step-1);
	line-height: 1.55;
	color: var(--prp-ink-body);
	max-width: 36rem;
	margin: 0;
}

/* The meta row inherits .prp-meta from the guide masthead: category chip,
   byline, reading time, aqua dots between. */
.prp-featured__meta {
	margin-top: 0.125rem;
}

.prp-featured__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: 0.5rem;
}

/*
 * The photograph. First in the one-column order because on a phone the
 * picture is what says "an article" before a word is read; beside the text
 * from the desktop step. It is a second link to the guide for the mouse
 * only: the title carries the real one, and `tabindex="-1"` with
 * `aria-hidden` keeps a keyboard or screen-reader user from meeting the
 * same destination twice.
 */
.prp-featured__media {
	display: block;
	width: 100%;
	max-width: 40rem;
	aspect-ratio: 3 / 2;
	order: -1;
	border-radius: var(--prp-radius-xl);
	overflow: hidden;
	background: linear-gradient(140deg, #e6f2ec 0%, #d5e8de 100%);
	box-shadow: var(--prp-shadow-art);
}

.prp-featured__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* While nothing is published the block is the promise alone, at the copy's
   own measure. */
.prp-featured.is-empty .prp-featured__text {
	max-width: 40rem;
}

@media (min-width: 56.3125rem) {
	.prp-hero__shell {
		padding-block: var(--prp-section-lg);
	}

	.prp-featured__grid {
		grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
		gap: var(--prp-gap-grid);
	}

	.prp-featured__text {
		max-width: none;
		padding-inline-end: 0.5rem;
	}

	.prp-featured__media {
		order: 0;
		max-width: none;
	}
}

/* ==========================================================================
   Editorial promise

   The commitments band: the site's own promise, then the four commitments
   the editorial-standards page states in full, each as one short line with
   the site's tick. The words are the approved principle leads from
   tools/content/pages.php, not a paraphrase, and the link at the foot goes
   to the page that carries the whole of each. The lede is the sentence the
   old hero opened with; it qualifies the guides above, which is where it
   earns its place.

   Evergreen since the refinement of 2026-09-12, between the white topic
   index and the sage finder. On warm paper the band and the finder beneath
   it sat within 1.2:1 of each other and read as one section; on the
   masthead's own green the promise is unmistakably a different thing from
   the tool beneath it, and the dark bands, masthead and footer, are the
   identity it belongs to. Focus rings re-point to mint, as on every dark
   band.

   The heading and the list are top-aligned, and the list is nudged so the
   cap height of its first line sits on the cap height of the heading's:
   grid `start` alone lines up two line boxes with different leading, which
   reads as the list starting a few pixels early.
   ========================================================================== */

.prp-promise {
	--prp-focus: var(--prp-mint);
	background: var(--prp-forest);
	color: var(--prp-on-dark);
}

.prp-promise__inner {
	display: grid;
	gap: 1.75rem;
	padding-block: var(--prp-section);
	align-items: start;
}

/* The section head keeps its type and loses the air beneath it: the list
   sits beside it, not under it. */
.prp-promise .prp-section-head {
	margin-bottom: 0;
}

.prp-promise .prp-section-head h2 {
	font-size: clamp(1.625rem, 1.15rem + 1.6vw, 2.125rem);
	color: #fff;
	text-wrap: balance;
}

.prp-promise .prp-section-head p {
	color: var(--prp-on-dark-muted);
	max-width: 30rem;
}

.prp-promise__body {
	display: flex;
	flex-direction: column;
	gap: 1.375rem;
}

.prp-promise__list {
	display: grid;
	gap: 0.875rem 1.5rem;
	margin: 0;
	padding: 0;
	list-style: none;
	color: var(--prp-on-dark);
	font-size: var(--prp-step-0);
	font-weight: 600;
	line-height: 1.4;
}

/* The site's tick, as a mask, so the list stays a plain core/list block an
   editor can retype. Mint on evergreen, the way the masthead's accent is. */
.prp-promise__list li {
	position: relative;
	padding-left: 1.5rem;
}

.prp-promise__list li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.3em;
	width: 0.9375rem;
	height: 0.9375rem;
	background-color: var(--prp-mint);
	-webkit-mask: var(--prp-tick) center / contain no-repeat;
	mask: var(--prp-tick) center / contain no-repeat;
}

.prp-promise__body .prp-action--text {
	align-self: flex-start;
	color: var(--prp-mint);
}

@media (hover: hover) {
	.prp-promise .prp-action--text:hover {
		color: #fff;
	}
}

/* Two columns of commitments from the tablet step; the head takes its own
   column from the desktop step, where the row has room for three. */
@media (min-width: 42.5625rem) {
	.prp-promise__list {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 56.3125rem) {
	.prp-promise__inner {
		grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
		column-gap: var(--prp-gap-grid);
		align-items: start;
	}

	/* The nudge described above: the heading's line box carries more space
	   over its capitals than the 16px list's does. */
	.prp-promise__body {
		padding-top: 0.375rem;
	}
}

/* ==========================================================================
   Section heads
   ========================================================================== */

/*
 * The finder and the newsletter keep the section head's trailing space.
 *
 * Both components in the approved prototype declare `margin-bottom: 0` here,
 * reasoning that the grid gap already separates the head from the panel — but
 * SectionHead's own `margin-bottom: var(--prp-space-head)` is emitted after
 * them and wins on source order, so the build that was approved renders with
 * the 24px still in place.
 *
 * This port matches the approved rendering rather than the defeated intent: the
 * signed-off screens have that space, and silently closing it would change a
 * band the reviewer accepted. If the intent is the one that should stand, drop
 * the space in both places at once so the two bands stay in step.
 */
.prp-section-head {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	align-items: flex-start;
	gap: 1.25rem 1.875rem;
	margin-bottom: var(--prp-space-head);
}

.prp-section-head__text {
	display: flex;
	flex-direction: column;
	gap: 0.4375rem;
}

.prp-section-head h2 {
	font-size: var(--prp-step-3);
	color: var(--prp-forest);
	margin: 0;
	text-wrap: balance;
}

.prp-section-head p {
	color: var(--prp-ink-body);
	font-size: var(--prp-step-0);
	line-height: 1.55;
	max-width: var(--prp-measure);
}

/* Scoped through the parent to outrank `.prp-section-head p` above. The
   approved design set this on a <span>, which that rule never matched; here it
   is a core/paragraph, so the eyebrow needs the extra class to win. */
.prp-section-head .prp-section-head__eyebrow {
	display: inline-block;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	font-size: 0.5625rem;
	font-weight: 800;
	color: var(--prp-green-link);
}

/* Once the heading and its action link share a line, the link settles onto the
   heading's baseline. */
@media (min-width: 42.5625rem) {
	.prp-section-head {
		align-items: flex-end;
	}
}

/* ==========================================================================
   Card grid

   The one card the whole site uses: homepage rail, guide archive, review
   archive, category archives and the related rail. Built from core/query, so
   the copy is post content and the layout is here.
   ========================================================================== */

.prp-grid .wp-block-post-template {
	display: grid;
	gap: var(--prp-gap-card);
	list-style: none;
	margin: 0;
	padding: 0;
}

.prp-card {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--prp-surface);
	border: 1px solid var(--prp-line-card);
	border-radius: var(--prp-radius-lg);
	overflow: hidden;
	height: 100%;
	transition:
		transform var(--prp-duration) var(--prp-ease),
		box-shadow var(--prp-duration) var(--prp-ease);
}

.prp-card:hover {
	transform: translateY(-3px);
	box-shadow: var(--prp-shadow-card);
}

/* A card whose guide is still being written does not lift: there is nowhere for
   the reader to go, and a hover state would promise otherwise. Keyed on the
   marker the card already carries, so the state has one source rather than a
   class that could be set without it. */
.prp-card:has(.prp-flag):hover {
	transform: none;
	box-shadow: none;
}

.prp-card:focus-within {
	box-shadow: var(--prp-shadow-card);
}

/* Stretched link: the whole card is clickable, and the link's accessible name
   is the title rather than every word in the card. */
.prp-card .wp-block-post-title a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.prp-card .wp-block-post-featured-image {
	position: relative;
	background: linear-gradient(140deg, #e6f2ec 0%, #d5e8de 100%);
	/* The 4:3 photos cover-crop to this band; the focal points come from the
	   image manifest and are applied per slot below. */
	height: 8.5rem;
	overflow: hidden;
	margin: 0;
}

.prp-card .wp-block-post-featured-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The lead card of the homepage rail carries a taller band while the rail is a
   single column, which is the one width where it is genuinely the feature. From
   the tablet band up the three cards share a row and therefore a height — see
   the note on that override below. */
.prp-grid--feature .wp-block-post-template > *:first-child .wp-block-post-featured-image {
	height: 9.25rem;
}

.prp-card__body {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	padding: 1.25rem 1.3125rem 1.375rem;
	flex: 1;
}

.prp-card .wp-block-post-terms {
	display: inline-flex;
	align-items: center;
	gap: 0.5rem;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	font-size: var(--prp-step--2);
	font-weight: 700;
	color: var(--prp-green-link);
}

.prp-card .wp-block-post-terms::before {
	content: "";
	flex: none;
	width: 1.125rem;
	height: 2px;
	border-radius: 1px;
	background: var(--prp-aqua);
}

.prp-card .wp-block-post-terms a {
	color: inherit;
	text-decoration: none;
}

.prp-card .wp-block-post-title {
	font-family: var(--prp-font-body);
	font-size: 1.0625rem;
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: -0.01em;
	color: var(--prp-ink-heading-alt);
	margin: 0;
}

.prp-card .wp-block-post-title a {
	color: inherit;
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-card .wp-block-post-title a:hover {
	color: var(--prp-green-link);
}

.prp-card .wp-block-post-excerpt__excerpt {
	color: var(--prp-ink-body);
	font-size: var(--prp-step-0);
	line-height: 1.55;
	margin: 0;
}

.prp-card .wp-block-post-excerpt__more-text {
	margin: 0;
}

.prp-card__more,
.prp-card .wp-block-post-excerpt__more-link {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	margin-top: auto;
	padding-top: 0.75rem;
	font-size: var(--prp-step-0);
	font-weight: 800;
	color: var(--prp-green-link);
	text-decoration: none;
}

/* "In production" marker. Sits over the media band where there is one, and in
   the copy where there is not — a decorative panel in the shape of a photograph
   reads as an image that failed to load, so entries without approved
   photography render with no media band at all. */
.prp-flag {
	position: absolute;
	left: 0.75rem;
	top: 0.75rem;
	z-index: 2;
	padding: 0.25rem 0.5rem;
	border-radius: 999px;
	background: rgba(255, 255, 255, 0.92);
	border: 1px solid var(--prp-line-card);
	color: var(--prp-ink-muted);
	font-size: var(--prp-step--2);
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.prp-flag--inline {
	position: static;
	align-self: flex-start;
	background: var(--prp-surface);
}

.prp-card__planned {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	margin-top: auto;
	padding-top: 0.75rem;
}

.prp-card__note {
	color: var(--prp-ink-body);
	font-size: var(--prp-step-0);
	line-height: 1.5;
	margin: 0;
}

.prp-card__planned .prp-card__more {
	margin-top: 0;
	padding-top: 0;
	align-self: flex-start;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-card__planned .prp-card__more:hover {
	color: var(--prp-forest);
}

/*
 * From the tablet band up the cards share one row, so they share one media
 * height — including the lead card. Height rather than aspect-ratio on purpose:
 * the columns are not equal widths at desktop (1.45fr 1fr 1fr), so a shared
 * ratio would reproduce the mismatch it is meant to remove. The image fills the
 * band with object-fit: cover and its own focal point, so a taller card crops
 * rather than stretches.
 */
@media (min-width: 42.5625rem) {
	.prp-grid--even .wp-block-post-template {
		grid-template-columns: repeat(2, 1fr);
	}

	/* Three columns from the first tablet width up, so the three-card rail
	   never renders a 1 + 2 row. `--three` is the same three columns kept
	   equal at every width: the homepage's latest-guides rail, the three
	   newest eligible guides with the featured one among them and no lead
	   card of its own. Should the library ever hold fewer than three, the
	   columns stay three and a card stays a card's width, rather than
	   stretching into banners that would shrink back the day the next guide
	   arrives. */
	.prp-grid--feature .wp-block-post-template,
	.prp-grid--three .wp-block-post-template {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}

	.prp-card .wp-block-post-featured-image,
	.prp-grid--feature .wp-block-post-template > *:first-child .wp-block-post-featured-image {
		height: 9.75rem;
	}
}

/* Cards get materially wider here; the band grows with them so a 480px card
   does not carry a letterbox strip. Still one height for all three. */
@media (min-width: 56.3125rem) {
	.prp-grid--feature .wp-block-post-template {
		grid-template-columns: 1.45fr 1fr 1fr;
	}

	.prp-grid--even .wp-block-post-template {
		grid-template-columns: repeat(3, 1fr);
	}

	.prp-card .wp-block-post-featured-image,
	.prp-grid--feature .wp-block-post-template > *:first-child .wp-block-post-featured-image {
		height: 11rem;
	}
}

/* Focal points, from the approved image manifest. Each says what has to survive
   the crop when the slot's box is a different shape from the photograph. The
   classes land on the <img> itself (see wp_get_attachment_image_attributes in
   functions.php), because the element that crops is the one that has to be
   told where to crop from. */
img.prp-focus-knee {
	object-position: 50% 6%;
}

img.prp-focus-rotator {
	object-position: 50% 14%;
}

/* ==========================================================================
   Starting points

   The homepage's task-first routes into the library, as an index rather than
   a grid of cards: a situation on the left, in the reader's own terms, and
   on the right the jobs the library can do for it today, each a row that
   leads to one guide, to the finder or to the library. Rendered by
   blocks/starting-points, which also decides which rows and which situations
   exist: a planned guide's row is absent until the guide is published, and a
   situation with no live row is absent with it, so the index has to read as
   complete with three rows and with eight. Hairlines between situations do
   that; a card grid never did, because a grid with a hole in it reads as a
   grid that lost something.
   ========================================================================== */

/* White under the tinted hero, with a hairline to say where one ends and the
   other begins. */
.prp-starts-band {
	border-top: 1px solid var(--prp-line-strong);
}

/* Anything a homepage anchor can land on has to clear the sticky masthead, as
   the guide and page anchors already do: `#gear-finder` is where the masthead
   pill, the hero's second action and the finder's own starting-point row all
   jump to. */
.prp-home [id] {
	scroll-margin-top: var(--prp-sticky-offset);
}

.prp-starts {
	border-top: 1px solid var(--prp-line-strong);
}

.prp-starts__group {
	display: grid;
	gap: 0.875rem 2.5rem;
	padding-block: 1.625rem 1.75rem;
	border-bottom: 1px solid var(--prp-line-strong);
}

.prp-starts__situation {
	display: flex;
	flex-direction: column;
	gap: 0.375rem;
}

.prp-starts__heading {
	font-family: var(--prp-font-display);
	font-size: var(--prp-step-2);
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: -0.015em;
	color: var(--prp-forest);
	margin: 0;
}

.prp-starts__lead {
	font-size: var(--prp-step-0);
	line-height: 1.5;
	color: var(--prp-ink-body);
	max-width: 24rem;
	margin: 0;
}

.prp-starts__tasks {
	display: grid;
	gap: 0.125rem;
	margin: 0;
	padding: 0;
	list-style: none;
}

/* A row: the task and the guide's own words on the left, the reading time and
   the arrow on the right. The hit area bleeds past the text column by its own
   padding so the highlight sits around the words rather than inset from them. */
.prp-start {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	align-items: center;
	gap: 0.25rem 1rem;
	padding: 0.8125rem 0.875rem;
	margin-inline: -0.875rem;
	border-radius: var(--prp-radius-lg);
	color: var(--prp-ink-body);
	text-decoration: none;
	transition: background-color var(--prp-duration) var(--prp-ease);
}

.prp-start:hover {
	background: var(--prp-canvas);
}

.prp-start__text {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	min-width: 0;
}

.prp-start__task {
	font-size: 1.0625rem;
	font-weight: 750;
	line-height: 1.3;
	letter-spacing: -0.01em;
	color: var(--prp-ink-heading-alt);
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-start:hover .prp-start__task {
	color: var(--prp-green-link);
}

.prp-start__note {
	font-size: var(--prp-step--1);
	line-height: 1.5;
	color: var(--prp-ink-body);
}

.prp-start__end {
	display: inline-flex;
	align-items: center;
	gap: 0.75rem;
	color: var(--prp-green-link);
}

.prp-start__meta {
	font-size: var(--prp-step--1);
	font-weight: 600;
	color: var(--prp-ink-muted);
	white-space: nowrap;
}

.prp-start__arrow {
	display: grid;
	place-items: center;
	transition: transform var(--prp-duration) var(--prp-ease);
}

.prp-start:hover .prp-start__arrow {
	transform: translateX(3px);
}

@media (min-width: 56.3125rem) {
	.prp-starts__group {
		grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
		column-gap: var(--prp-gap-grid);
		padding-block: 2rem 2.125rem;
	}

	.prp-start {
		padding: 0.875rem 1rem;
		margin-inline: -1rem;
	}
}

/* ==========================================================================
   Explore by topic

   Rendered whole by blocks/topic-index, band, section head and grid, so that
   when no topic holds a published guide nothing renders at all. A topic panel
   is the category's glyph and name, its own approved description, the guides
   behind it and a route into its archive. Listing the guides is what makes a
   two-topic band read as the index of a small library rather than as a grid
   missing four cards: the head says how many topics and guides there are,
   and each panel shows what it holds. White, under a hairline, so the band
   reads apart from the warm-paper latest-guides rail above it. Columns: the
   balanced grid below, which seats two panels abreast and grows a topic at a
   time as guides publish.
   ========================================================================== */

.prp-explore {
	background: var(--prp-surface);
	border-top: 1px solid var(--prp-line-strong);
}

/* The count, on the section head's action side: what the band holds, stated
   so a short band reads as a true count. */
.prp-section-head .prp-explore__count {
	font-size: var(--prp-step--1);
	font-weight: 650;
	color: var(--prp-ink-body);
	white-space: nowrap;
	margin: 0;
}

.prp-explore__grid {
	display: grid;
	gap: var(--prp-gap-card);
	margin: 0;
	padding: 0;
	list-style: none;
}

.prp-explore__item {
	display: grid;
	min-width: 0;
}

.prp-topic {
	display: flex;
	flex-direction: column;
	gap: 0.875rem;
	height: 100%;
	padding: 1.375rem 1.375rem 1.5rem;
	border: 1px solid var(--prp-line-card);
	border-radius: var(--prp-radius-lg);
	background: var(--prp-surface);
}

.prp-topic__head {
	display: flex;
	align-items: center;
	gap: 0.75rem;
}

.prp-topic__glyph {
	display: grid;
	place-items: center;
	flex: none;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 0.75rem;
	color: var(--prp-green);
	background: linear-gradient(140deg, #eaf5ef 0%, #dceee5 100%);
}

.prp-topic__name {
	flex: 1 1 auto;
	min-width: 0;
	font-family: var(--prp-font-display);
	font-size: var(--prp-step-2);
	font-weight: 600;
	line-height: 1.2;
	letter-spacing: -0.015em;
	color: var(--prp-forest);
	margin: 0;
}

.prp-topic__name a {
	color: inherit;
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-topic__name a:hover {
	color: var(--prp-green-link);
}

/* The count is metadata: small, bold, and in the link green the category
   rules use, on white where that colour clears AA. */
.prp-topic__count {
	flex: none;
	text-transform: uppercase;
	letter-spacing: 0.09em;
	font-size: var(--prp-step--2);
	font-weight: 700;
	color: var(--prp-green-link);
}

.prp-topic__desc {
	font-size: var(--prp-step-0);
	line-height: 1.55;
	color: var(--prp-ink-body);
	margin: 0;
}

/* The guides behind the topic, as a ruled list; each row is the whole guide
   at its card title.

   The list is the panel's one stretching part, and its rows share the
   stretch. Two panels sit abreast at equal height while holding different
   counts, and whatever height the taller list needs the shorter one takes
   as taller rows rather than as a blank under its last rule: the top rule,
   the bottom rule and the Browse link beneath it then land on the same lines
   in both panels, with the same air between, instead of one panel's link
   sitting a row's height below its list. */
.prp-topic__guides {
	flex: 1 1 auto;
	display: grid;
	grid-auto-rows: minmax(0, 1fr);
	list-style: none;
	margin: 0.125rem 0 0;
	padding: 0;
	border-top: 1px solid var(--prp-line);
}

.prp-topic__guides li {
	display: grid;
	border-bottom: 1px solid var(--prp-line);
}

.prp-topic__guide {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	min-height: 2.75rem;
	padding: 0.6875rem 0;
	font-size: var(--prp-step-0);
	font-weight: 650;
	line-height: 1.35;
	color: var(--prp-ink-heading-alt);
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-topic__guide .prp-icon {
	color: var(--prp-green-link);
	transition: transform var(--prp-duration) var(--prp-ease);
}

.prp-topic__guide:hover {
	color: var(--prp-green-link);
}

.prp-topic__guide:hover .prp-icon {
	transform: translateX(3px);
}

.prp-topic__all {
	margin-top: auto;
	align-self: flex-start;
}

/* ==========================================================================
   Balanced grids

   The topic index is a grid whose panel count is decided by what is
   published (the starting points were one too, until they became an index),
   so the same rules have to look placed at one panel and at eight. `auto-fit` did not: at 1440px it left a fourth
   track empty behind three cards, and at five cards it stranded two under
   three. Measured 2026-09-12, and the reason for the arithmetic below.

   Tablet: two abreast, and an odd last card takes the whole row rather than
   sitting beside a hole.

   From 64rem — a content step, not the device band: at the 901px desktop
   step a three-abreast card is 250px wide and a task line wraps to three
   lines, so the two-abreast tablet layout holds until the shell can give
   three cards 290px each — six tracks, every card spanning two, so three sit
   abreast. The count decides the final row. Two cards, or one more than a multiple of
   three from four up, would leave a lone card or a 3 + 1; instead the last
   two — or the last four — span three tracks each, so the final row is two
   wider cards (or two rows of two), which reads as chosen rather than as
   what was left. A single card is a single column at the card's own measure.
   Counted with `:has()` on the list, the way the library card already keys
   its hover state.
   ========================================================================== */

@media (min-width: 42.5625rem) {
	.prp-grid-balanced {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.prp-grid-balanced > :last-child:nth-child(odd):not(:only-child) {
		grid-column: 1 / -1;
	}
}

@media (min-width: 64rem) {
	.prp-grid-balanced {
		grid-template-columns: repeat(6, minmax(0, 1fr));
	}

	.prp-grid-balanced > * {
		grid-column: span 2;
	}

	.prp-grid-balanced:has(> :only-child) {
		grid-template-columns: minmax(0, 26rem);
	}

	.prp-grid-balanced > :only-child {
		grid-column: auto;
	}

	/* Two cards, five, eight: the last two span three. */
	.prp-grid-balanced:has(> :nth-child(3n + 2):last-child) > :nth-last-child(-n + 2) {
		grid-column: span 3;
	}

	/* Four cards, seven: the last four span three, in two rows of two. */
	.prp-grid-balanced:has(> :nth-child(3n + 1):last-child):not(:has(> :only-child)) > :nth-last-child(-n + 4) {
		grid-column: span 3;
	}
}

/* ==========================================================================
   Gear finder
   ========================================================================== */

/*
 * Muted sage-gray. The finder sits directly above the mailing-list band's warm
 * paper, and a pale mint would be only 1.07:1 against it — a hue change with
 * almost no change in value, which makes the two bands read as one. Sage
 * separates on value as well as temperature (1.20:1 from the paper below,
 * 1.31:1 against the white choice cards) while staying a desaturated member of
 * the evergreen family, so no fourth hue enters the palette. A pale blue
 * separated as well but reads clinical in a health context and fights the warm
 * interior photography in the guide rail above.
 */
.prp-finder {
	background: linear-gradient(160deg, #e8eee7 0%, #dde3dc 55%, #d8dfd7 100%);
	color: var(--prp-ink);
	border-block: 1px solid #c9d2c7;
	padding-block: var(--prp-section);
}

.prp-finder__grid {
	display: grid;
	gap: var(--prp-gap-grid);
	align-items: center;
}



.prp-finder__panel {
	display: grid;
	gap: 0.9375rem;
}

.prp-finder__steps {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.5625rem;
	border: 0;
	margin: 0;
	padding: 0;
	min-inline-size: 0;
}

/*
 * Grid rather than block. The row already stretches the label, but a block
 * label passes none of that height on, so the face keeps its own content
 * height and the shortest card sits short of the row whenever another card's
 * choice wraps. As a lone grid item the face stretches to the label instead,
 * which is what makes the three cards the same height in any row they share —
 * at any wrap, in any active state, and with no height fixed in advance.
 */
.prp-finder__step {
	display: grid;
	cursor: pointer;
}

.prp-finder__step input {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
	font: inherit;
}

.prp-finder__face {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 1.0625rem;
	min-height: 6.75rem;
	padding: 1rem;
	border: 1px solid #ccd5cb;
	border-radius: 0.75rem;
	background: var(--prp-surface);
	color: var(--prp-ink-body);
	transition:
		background-color var(--prp-duration) var(--prp-ease),
		color var(--prp-duration) var(--prp-ease),
		border-color var(--prp-duration) var(--prp-ease);
}

.prp-finder__meta {
	font-size: var(--prp-step--2);
	color: var(--prp-ink-muted);
	letter-spacing: 0.06em;
}

.prp-finder__face strong {
	font-size: var(--prp-step-0);
	font-weight: 700;
	color: var(--prp-ink-heading-alt);
}

.prp-finder__step input:checked + .prp-finder__face {
	background: var(--prp-forest);
	border-color: var(--prp-forest);
	color: var(--prp-on-dark-muted);
}

.prp-finder__step input:checked + .prp-finder__face strong {
	color: #fff;
}

.prp-finder__step input:checked + .prp-finder__face .prp-finder__meta {
	color: var(--prp-mint);
}

.prp-finder__step input:focus-visible + .prp-finder__face {
	outline: 3px solid var(--prp-focus);
	outline-offset: 3px;
}

.prp-finder__step:hover .prp-finder__face {
	border-color: var(--prp-green-link);
}

.prp-finder__result {
	color: var(--prp-ink-body);
	font-size: var(--prp-step-0);
	line-height: 1.5;
	min-height: 1.5rem;
}

/*
 * The sage ground is darker than the white and warm-paper surfaces the green
 * link colour was judged against, and it pulls --prp-green-link down to 4.36:1
 * — just under AA for both of these. --prp-forest is the same family a step
 * deeper and clears it at 8.4:1, so the finder keeps its green without the two
 * smallest pieces of type on it failing.
 */
.prp-finder__result-label {
	color: var(--prp-forest);
}

.prp-finder__result-label {
	font-weight: 700;
}

.prp-finder__note {
	color: var(--prp-ink-body);
	font-size: var(--prp-step--1);
	line-height: 1.5;
}

@media (min-width: 42.5625rem) {
	.prp-finder__steps {
		grid-template-columns: repeat(3, 1fr);
	}
}

@media (min-width: 56.3125rem) {
	.prp-finder__grid {
		grid-template-columns: 0.8fr 1.2fr;
	}
}

/* ==========================================================================
   Newsletter

   Warm paper between whatever the page ended on and the dark footer. On the
   homepage that breaks up a sage finder and a dark footer; elsewhere the
   hairline does the separating.
   ========================================================================== */

.prp-newsletter {
	background: var(--prp-canvas);
	border-top: 1px solid var(--prp-line-strong);
	padding-block: var(--prp-section);
}

.prp-newsletter__inner {
	display: grid;
	gap: var(--prp-gap-grid);
	align-items: start;
}



.prp-newsletter__form {
	display: grid;
	gap: 0.875rem;
}

.prp-newsletter__field {
	display: grid;
	gap: 0.4375rem;
}

/*
 * One control row. The input's padding and border made it 53px tall and the
 * button's made it 47px, so the two met on their bottom edge and nowhere else.
 * A shared minimum height lines them up on both edges at every width, and it is
 * comfortably above the 44px pointer target either way.
 */
.prp-newsletter__form input,
.prp-newsletter__form button {
	min-height: 3.3125rem;
}

.prp-newsletter__form label {
	font-size: var(--prp-step-0);
	font-weight: 700;
	color: var(--prp-ink-heading-alt);
}

.prp-newsletter__form input {
	width: 100%;
	min-width: 0;
	font: inherit;
	font-size: var(--prp-step-0);
	color: var(--prp-ink);
	background: var(--prp-surface);
	border: 1px solid var(--prp-line-button);
	border-radius: var(--prp-radius);
	padding: 0.8125rem 0.9375rem;
	transition: border-color var(--prp-duration) var(--prp-ease);
}

.prp-newsletter__form input::placeholder {
	color: var(--prp-ink-subtle);
}

.prp-newsletter__form input:hover {
	border-color: var(--prp-green-link);
}

.prp-newsletter__form input:focus-visible {
	outline: 3px solid var(--prp-focus);
	outline-offset: 2px;
	border-color: var(--prp-green-link);
}

.prp-newsletter__form input[aria-invalid="true"] {
	border-color: var(--prp-clay-cta);
}

.prp-newsletter__form button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 0.5rem;
	align-self: start;
	padding: 0.875rem 1.25rem;
	border: 0;
	border-radius: var(--prp-radius);
	background: var(--prp-green);
	color: #fff;
	font-size: var(--prp-step-0);
	font-weight: 700;
	line-height: 1.2;
	cursor: pointer;
	box-shadow: var(--prp-shadow-primary);
	transition:
		transform var(--prp-duration) var(--prp-ease),
		background-color var(--prp-duration) var(--prp-ease);
}

@media (hover: hover) {
	.prp-newsletter__form button:hover {
		transform: translateY(-1px);
		background: #135a49;
	}
}

.prp-newsletter__status {
	font-size: var(--prp-step-0);
	line-height: 1.5;
	font-weight: 650;
}

.prp-newsletter__status[data-tone="idle"] {
	display: none;
}

.prp-newsletter__status[data-tone="success"] {
	color: var(--prp-green-link);
}

.prp-newsletter__status[data-tone="error"] {
	color: var(--prp-clay-cta-hover);
}

.prp-newsletter__status .prp-icon {
	display: none;
	vertical-align: -0.15em;
	margin-right: 0.25rem;
}

.prp-newsletter__status[data-tone="success"] .prp-icon {
	display: inline-block;
}

/* --prp-ink-muted only reaches 4.18:1 on the warm ground, short of AA for text
   this small; the body ink clears it at 6.4:1 and still reads as secondary. */
.prp-newsletter__note {
	font-size: var(--prp-step--1);
	line-height: 1.55;
	color: var(--prp-ink-body);
	max-width: 34rem;
}

/* Field and button share a line once there is room for the button to sit beside
   a usable input rather than squeezing it. */
@media (min-width: 42.5625rem) {
	.prp-newsletter__form {
		grid-template-columns: minmax(0, 1fr) auto;
		align-items: end;
	}

	.prp-newsletter__form button {
		align-self: end;
	}

	.prp-newsletter__status,
	.prp-newsletter__note {
		grid-column: 1 / -1;
	}
}

@media (min-width: 56.3125rem) {
	.prp-newsletter__inner {
		grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
		align-items: center;
	}
}

/* ==========================================================================
   Breadcrumbs

   Full-width white row between the masthead and the page head, sharing the
   standard shell measure.
   ========================================================================== */

.prp-breadcrumbs {
	background: var(--prp-surface);
	border-bottom: 1px solid var(--prp-line);
	padding-block: 0.8125rem;
	font-size: var(--prp-step--1);
	line-height: 1.4;
}

.prp-breadcrumbs__trail {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	gap: 0.375rem;
	margin: 0;
	padding: 0;
	list-style: none;
	width: 100%;
	min-width: 0;
	overflow: hidden;
}

.prp-breadcrumbs__item {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	flex: 0 0 auto;
	min-width: 0;
}

.prp-breadcrumbs__item.is-current {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
}

.prp-breadcrumbs__sep {
	flex: none;
	color: var(--prp-ink-muted);
	opacity: 0.65;
}

/*
 * 14px/1.4 gave the crumb links a 19.6px box, under the 24 CSS px WCAG 2.5.8
 * asks of a target that is not inline in a sentence. The row is a flex line
 * with `align-items: center`, so a minimum height on the link grows the hit
 * area symmetrically and moves no text: the trail keeps its baseline and the
 * row grows by the difference, which its own padding absorbs.
 */
.prp-breadcrumbs a {
	display: inline-flex;
	align-items: center;
	min-height: 1.5rem;
	color: var(--prp-green-link);
	font-weight: 600;
	white-space: nowrap;
	flex-shrink: 0;
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-breadcrumbs a:hover {
	color: var(--prp-forest);
}

.prp-breadcrumbs__current {
	color: var(--prp-ink-heading-alt);
	font-weight: 650;
	display: block;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	min-width: 0;
}

/* Content breakpoint: the row takes its taller padding once the trail has room
   to sit on one line without the current page truncating. */
@media (min-width: 48rem) {
	.prp-breadcrumbs {
		padding-block: 1.0625rem;
	}
}

/* ==========================================================================
   Page head
   ========================================================================== */

.prp-page-head {
	border-bottom: 1px solid var(--prp-line);
}

.prp-page-head__inner {
	display: grid;
	gap: 1.25rem;
	/*
	 * Asymmetric: the breadcrumb band directly above already opens the page,
	 * so a full section step under it read as a hole between the trail and the
	 * title. The space below the deck is what separates the head from the body
	 * and keeps its own step.
	 */
	padding-block: var(--prp-space-head) var(--prp-section-sm);
}

.prp-page-head__text {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
	max-width: 46rem;
}

.prp-page-head__text.is-wide {
	max-width: 58rem;
}

/*
 * A watermark for informational and legal heads, drawn from the theme's own
 * shipped Tabler set — the `shield-check` already used for the editorial
 * standards link — and inlined the way `--prp-tick` and the chevrons are. No
 * new asset, no logo artwork, nothing redrawn: the path is the file's own,
 * carrying a colour and a stroke opacity in place of `currentColor`.
 *
 * It starts at the tablet step because a phone head has no room beside the
 * title for anything to sit, and listing heads (`is-wide`) are left plain — the
 * mark reads as a claim the page is making, and an archive makes none.
 */
@media (min-width: 48rem) {
	.prp-page-head__inner {
		background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="%23173e34" stroke-opacity="0.07" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><path d="M11.46 20.846a12 12 0 0 1 -7.96 -14.846a12 12 0 0 0 8.5 -3a12 12 0 0 0 8.5 3a12 12 0 0 1 -.09 7.06"/><path d="M15 19l2 2l4 -4"/></svg>');
		background-repeat: no-repeat;
		background-position: right 0 center;
		background-size: 11rem 11rem;
	}

	.prp-page-head__inner:has(.prp-page-head__text.is-wide) {
		background-image: none;
	}
}

.prp-page-head h1 {
	font-size: var(--prp-step-3);
	line-height: 1.06;
	color: var(--prp-forest);
}

.prp-page-head__deck {
	font-size: var(--prp-step-1);
	line-height: 1.5;
	color: var(--prp-ink-body);
}

.prp-page-head__count {
	font-size: var(--prp-step--1);
	font-weight: 700;
	/* 4.1:1 on the tinted head as --prp-ink-muted; see the note on .prp-meta. */
	color: var(--prp-ink-body);
}

.prp-page-head__reviewed {
	display: inline-flex;
	align-items: center;
	gap: 0.4375rem;
	font-size: var(--prp-step--1);
	color: var(--prp-ink-muted);
}

/* ==========================================================================
   Archive filters

   Links to real routes, not JavaScript filters over a hidden list: every filter
   state is a page that can be linked, shared and indexed, it works with
   JavaScript off, and the current filter is announced by aria-current rather
   than implied by colour.
   ========================================================================== */

.prp-filters {
	position: relative;
	padding-block: 0.25rem;
	overflow: hidden;
	/*
	 * Pulled out by the room the rail reserves for a focus ring, so the chips
	 * still start on the band's own edge. A scroll container clips at its
	 * scrollport, and the ring is 6px wide — without the room the first chip's
	 * ring was cut off the moment it was tabbed to.
	 */
	margin-inline: -0.5rem;
}

/*
 * Scroll fades, one per edge.
 *
 * Each is keyed on a class the view script sets from the rail's own scroll
 * position, so the left fade appears only once something has been scrolled past
 * and the right one disappears at the end of the row — an edge that fades when
 * there is nothing behind it is a promise of more that never arrives.
 *
 * Wide and soft rather than narrow and abrupt: a short hard ramp reads as a
 * clipped chip, which is the thing the fade exists to explain. `pointer-events`
 * stay off so neither edge can eat a tap, and `z-index: 1` keeps them under the
 * focused chip, which lifts itself to 2.
 */
.prp-filters::before,
.prp-filters::after {
	content: "";
	position: absolute;
	inset-block: 0.25rem auto;
	width: clamp(3rem, 12vw, 5.5rem);
	height: calc(100% - 0.5rem);
	pointer-events: none;
	opacity: 0;
	z-index: 1;
	transition: opacity var(--prp-duration) var(--prp-ease);
}

/*
 * Anchored to the scrollport, not to the band.
 *
 * The rail's own `padding-inline` scrolls with its content, so a chip can sit
 * inside it — and while the fades were inset by that same amount to sit on the
 * band's edge, they left an 8px strip at each end that nothing covered. A chip
 * scrolled into it showed as a sliver outside the fade that was supposed to be
 * explaining it. The 8px each fade now extends past the band is a ramp to
 * transparent over the same canvas colour, so it costs nothing to look at.
 */
.prp-filters::before {
	left: 0;
	background: linear-gradient(
		to right,
		var(--prp-canvas) 0%,
		rgba(247, 245, 239, 0.94) 18%,
		rgba(247, 245, 239, 0.78) 36%,
		rgba(247, 245, 239, 0.5) 56%,
		rgba(247, 245, 239, 0.2) 78%,
		rgba(247, 245, 239, 0) 100%
	);
}

.prp-filters::after {
	right: 0;
	background: linear-gradient(
		to left,
		var(--prp-canvas) 0%,
		rgba(247, 245, 239, 0.94) 18%,
		rgba(247, 245, 239, 0.78) 36%,
		rgba(247, 245, 239, 0.5) 56%,
		rgba(247, 245, 239, 0.2) 78%,
		rgba(247, 245, 239, 0) 100%
	);
}

.prp-filters.has-overflow-start::before,
.prp-filters.has-overflow-end::after {
	opacity: 1;
}

.prp-filters__rail {
	display: flex;
	flex-wrap: nowrap;
	gap: 0.5rem;
	width: 100%;
	margin: 0;
	padding: 0;
	padding-inline: 0.5rem;
	list-style: none;
	overflow-x: auto;
	overflow-y: hidden;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: none;
	-ms-overflow-style: none;
	white-space: nowrap;
	scroll-snap-type: x proximity;
	/*
	 * The snapport has to start where the chips start. Without this the rail's
	 * own inline padding sits outside it, so the first chip's snap position is
	 * 4px in — and a page whose active chip is the first one opens with that
	 * chip already shaved, with nothing on screen to say why.
	 */
	scroll-padding-inline: 0.5rem;
}

.prp-filters__rail::-webkit-scrollbar {
	display: none;
}

.prp-filters__rail li {
	flex: 0 0 auto;
}

/*
 * From the desktop step the rail stops being a scroller and becomes rows.
 *
 * The chips need 1354px and the band is 1176px at its widest, so there is no
 * width at which they fit on one line — a horizontal scroller here hides two
 * of eight filters behind a gesture with no scrollbar, on a pointer device that
 * has no obvious way to perform it. Wrapping shows all eight and costs one row.
 *
 * Both axes have to be stated: with one axis visible and the other hidden, CSS
 * computes the visible one to `auto` and the rail is still a scroll container.
 *
 * Below this width the scroller stays, with the fade the view script turns on
 * only when there is genuinely more to reach — the behaviour a touch device
 * already handles well.
 */
@media (min-width: 56.3125rem) {
	.prp-filters {
		overflow: visible;
	}

	.prp-filters__rail {
		flex-wrap: wrap;
		overflow: visible;
		white-space: normal;
		scroll-snap-type: none;
	}

	/* Rows cannot scroll, so neither edge has anything to explain. */
	.prp-filters::before,
	.prp-filters::after {
		content: none;
	}
}

.prp-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.4375rem;
	min-height: 2.75rem;
	padding: 0.5rem 0.875rem;
	border-radius: 999px;
	border: 1px solid var(--prp-line-button);
	background: var(--prp-surface);
	color: var(--prp-ink-body);
	font-size: var(--prp-step--1);
	font-weight: 700;
	white-space: nowrap;
	text-decoration: none;
	scroll-snap-align: start;
	transition:
		background-color var(--prp-duration) var(--prp-ease),
		border-color var(--prp-duration) var(--prp-ease),
		color var(--prp-duration) var(--prp-ease);
}

.prp-chip:hover {
	border-color: #bcd3c8;
	color: var(--prp-green-link);
}

.prp-chip.is-active {
	background: var(--prp-forest);
	border-color: var(--prp-forest);
	color: #fff;
}

.prp-chip.is-active:hover {
	color: #fff;
}

.prp-chip:focus-visible {
	outline: 3px solid var(--prp-focus);
	outline-offset: 3px;
	border-radius: 999px;
	position: relative;
	z-index: 2;
}

/* ==========================================================================
   Archive body
   ========================================================================== */

.prp-archive__body {
	display: flex;
	flex-direction: column;
	gap: var(--prp-gap-grid);
	/* Asymmetric: the page head above already supplies the air, so a full
	   section step on top would stack two of them and read as a gap rather than
	   a separation. */
	padding-block: var(--prp-section-sm) var(--prp-section);
}

/*
 * The empty state.
 *
 * This is the only thing a reader sees where the library will be, and today it
 * is what the whole site is: nothing is published, and the sentence says so.
 * A dashed rectangle is the browser's idea of a missing slot, not a design —
 * it reads as something that failed to load rather than as the site telling
 * the truth about itself, which is the one impression this build cannot
 * afford. So the state is stated rather than outlined: the muted ground and
 * the hairline the note component already uses, at the content measure, with
 * the sentence promoted from body size to the reading step and left-aligned
 * with everything else on the page.
 *
 * It is deliberately *not* .prp-note. A note is an aside about something that
 * is there; this is the region reporting that it is empty, and where the two
 * appear on the same page (the /guides/ archive) the muted ground and the
 * larger type are what separate them.
 *
 * Contrast, re-measured for the ground this now sits on. The paragraph began
 * rendering on 2026-08-27, when every library entry moved to draft and the
 * archives became empty, and measuring it then found --prp-ink-muted (#6b7973)
 * at **4.18 : 1** on --prp-canvas (#f7f5ef) — under the 4.5 : 1 WCAG AA floor
 * for 16px regular text. It moved to --prp-ink-body (#4c5c56), **6.48 : 1** on
 * the same band. On --prp-surface-muted (#f5f5f0) that ink measures
 * **6.49 : 1** and --prp-ink-heading-alt (#1c3d35) measures **10.90 : 1**;
 * the heading ink is used because this sentence is a statement the page is
 * making, not a caption under one. Same contrast rule as §11 item 3 of
 * docs/project-decisions.md, one step further in the same family.
 */
.prp-empty {
	max-width: var(--prp-measure);
	padding: 2rem 1.5rem;
	border: 1px solid var(--prp-line-card);
	border-radius: var(--prp-radius-lg);
	background: var(--prp-surface-muted);
	text-align: left;
	color: var(--prp-ink-heading-alt);
	font-size: var(--prp-step-1);
	font-weight: 550;
	line-height: 1.5;
	text-wrap: pretty;
}

.prp-pagination {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 0.75rem;
	padding-top: 0.5rem;
	font-size: var(--prp-step--1);
	font-weight: 700;
}

.prp-pagination a {
	color: var(--prp-green-link);
	text-decoration: none;
}

.prp-pagination .page-numbers.current {
	color: var(--prp-forest);
}

/* ==========================================================================
   Prose

   Body copy keeps its measure even when the column around it is wider. At the
   18px reading size this lands around 68 characters a line.
   ========================================================================== */

.prp-prose > * {
	max-width: var(--prp-measure);
}

.prp-prose p {
	font-size: var(--prp-step-1);
	line-height: 1.65;
	color: var(--prp-ink-body);
}

.prp-prose h2 {
	font-size: var(--prp-step-2);
	line-height: 1.25;
	color: var(--prp-forest);
	margin-top: 2.25rem;
	margin-bottom: 0.9375rem;
	max-width: none;
}

.prp-prose h3 {
	font-family: var(--prp-font-body);
	font-size: var(--prp-step-1);
	font-weight: 750;
	color: var(--prp-ink-heading-alt);
	margin-top: 1.75rem;
	margin-bottom: 0.625rem;
}

.prp-prose > *:first-child {
	margin-top: 0;
}

.prp-prose ul,
.prp-prose ol {
	display: flex;
	flex-direction: column;
	gap: 0.6875rem;
	padding: 0;
	margin: 0;
	list-style: none;
}

.prp-prose ul li {
	position: relative;
	padding-left: 1.4375rem;
	font-size: var(--prp-step-1);
	line-height: 1.6;
	color: var(--prp-ink-body);
}

/* The tick is the same mark the design uses everywhere a list item is a thing
   the reader gets, drawn as a background so the list stays a plain core/list
   block and remains editable. */
.prp-prose ul li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.5em;
	width: 0.9375rem;
	height: 0.9375rem;
	background-color: var(--prp-green);
	-webkit-mask: var(--prp-tick) center / contain no-repeat;
	mask: var(--prp-tick) center / contain no-repeat;
}

/* The printable checklist. The rule above draws a completed-looking tick, which
   is the wrong mark for a list a reader is meant to work through on paper, so
   the box replaces it rather than sitting beside it. Nothing is ever pre-ticked:
   every box in every editorial master is empty, and the record gate asserts it.
   Drawn here rather than typed into the copy so the list stays a plain
   core/list block an editor can extend without retyping a character. */
.prp-prose ul.is-style-prp-checklist li::before {
	top: 0.35em;
	width: 0.875rem;
	height: 0.875rem;
	border: 1.5px solid var(--prp-line-strong);
	border-radius: 3px;
	background-color: var(--prp-surface);
	-webkit-mask: none;
	mask: none;
}

@media print {
	.prp-prose ul.is-style-prp-checklist li::before {
		border-color: #767676;
		background-color: #fff;
	}
}

.prp-prose ol {
	counter-reset: prp-step;
}

/* The step is a hanging indent, not a two-column grid.

   A grid held while every step was one uninterrupted run of text and broke the
   moment one was not. Grid makes an item of each element child and of each
   contiguous run of text, so `<strong>Lead.</strong> Body copy` is two items,
   and auto-placement drops the second into the 1.75rem counter track: the copy
   rendered in a 28px column with the rest of the row left blank. Anonymous text
   items cannot be selected, so no `grid-column` on a child can correct it.

   The indent is the shape `.prp-prose ul li` above already uses, and it holds
   however many elements and text runs a step is written with. The copy starts
   where it did — 1.75rem of disc plus the 0.625rem that was the grid gap. */
.prp-prose ol li {
	position: relative;
	padding-left: 2.375rem;
	font-size: var(--prp-step-1);
	line-height: 1.6;
	color: var(--prp-ink-body);
}

.prp-prose ol li::before {
	counter-increment: prp-step;
	content: counter(prp-step);
	position: absolute;
	left: 0;
	top: 0;
	display: grid;
	place-items: center;
	width: 1.75rem;
	height: 1.75rem;
	border-radius: 50%;
	background: var(--prp-surface-mint);
	color: var(--prp-green-ink);
	font-size: var(--prp-step--1);
	font-weight: 800;
}

.prp-prose a {
	color: var(--prp-green-link);
	text-decoration: underline;
	text-underline-offset: 0.2em;
	text-decoration-thickness: 1px;
}

.prp-prose a:hover {
	color: var(--prp-forest);
}

/* ==========================================================================
   Notes

   Standing notices: eligibility qualifiers, the non-medical-advice line, and
   site-status caveats. Three tones, one shape — the site makes the same three
   kinds of promise everywhere, and they should look the same everywhere.
   ========================================================================== */

.prp-note {
	display: flex;
	align-items: flex-start;
	gap: 0.75rem;
	padding: 0.9375rem 1.0625rem;
	border-radius: var(--prp-radius-lg);
	border: 1px solid var(--prp-line-card);
	background: var(--prp-surface-muted);
	font-size: var(--prp-step-0);
	line-height: 1.6;
	color: var(--prp-ink-body);
	max-width: none;
}

.prp-note p {
	font-size: inherit;
	line-height: inherit;
	color: inherit;
	margin: 0;
	max-width: none;
}

.prp-note strong {
	color: var(--prp-ink-heading-alt);
	font-weight: 750;
}

.prp-note__glyph {
	flex: none;
	display: grid;
	place-items: center;
	width: 1.875rem;
	height: 1.875rem;
	border-radius: 0.5625rem;
	background: var(--prp-surface);
	border: 1px solid var(--prp-line-card);
	color: var(--prp-green);
}

/*
 * The site-status note is the lightest of the three tones: it reports on the
 * commercial state of the site rather than warning about eligibility or care,
 * so it sits on the plain surface instead of the muted one. The glyph tile takes
 * the muted ground the note gave up, which keeps the icon legible against it.
 */
.prp-note--info {
	background: var(--prp-surface);
}

.prp-note--info .prp-note__glyph {
	background: var(--prp-surface-muted);
}

.prp-note--eligibility {
	background: var(--prp-surface-mint);
	border-color: #c3e3d5;
}

.prp-note--eligibility .prp-note__glyph {
	border-color: #c3e3d5;
	color: var(--prp-green-ink);
}

.prp-note--medical {
	background: #fdf3ee;
	border-color: #f3ddd0;
}

.prp-note--medical .prp-note__glyph {
	border-color: #f3ddd0;
	color: var(--prp-clay-deep);
}

/* ==========================================================================
   Guide masthead and body
   ========================================================================== */

.prp-guide__mast-inner {
	display: grid;
	gap: 1.75rem;
	padding-block: var(--prp-section-sm);
	align-items: center;
}

.prp-guide__mast-text {
	display: flex;
	flex-direction: column;
	gap: 0.9375rem;
	max-width: 42rem;
}

.prp-guide__category,
.prp-featured__category {
	display: inline-flex;
	align-items: center;
	gap: 0.4375rem;
	align-self: flex-start;
	padding: 0.3125rem 0.6875rem;
	border-radius: 999px;
	background: var(--prp-surface);
	border: 1px solid var(--prp-line-button);
	color: var(--prp-green-ink);
	font-size: var(--prp-step--1);
	font-weight: 750;
	text-decoration: none;
	transition:
		border-color var(--prp-duration) var(--prp-ease),
		color var(--prp-duration) var(--prp-ease);
}

.prp-guide__category:hover,
.prp-featured__category:hover {
	border-color: #bcd3c8;
	color: var(--prp-forest);
}

.prp-guide__mast-text .wp-block-post-title {
	font-size: var(--prp-step-3);
	line-height: 1.05;
	color: var(--prp-forest);
	margin: 0;
}

.prp-guide__deck {
	font-size: var(--prp-step-1);
	line-height: 1.55;
	color: var(--prp-ink-body);
	max-width: 36rem;
	margin: 0;
}

.prp-guide__mast-note {
	max-width: 36rem;
}

/* The lede under a section heading sits at the body size rather than the
   reading size: it introduces a run of cards, so it is furniture for the
   section rather than prose to settle into. */
.prp-guide__section-lede {
	font-size: var(--prp-step-0);
	line-height: 1.65;
	color: var(--prp-ink-body);
	max-width: 44rem;
	margin-bottom: 1.25rem;
}

/*
 * The masthead photograph never draws wider than it does at desktop.
 *
 * Between the tablet and desktop breakpoints the masthead is still one column,
 * so without a cap the photograph takes the whole shell: measured at 768px it
 * drew 691 x 461 and pushed the masthead from 506px tall to 967px — taller than
 * the text it is supposed to accompany, and wider than that text's own 42rem
 * measure. It stopped being the companion to a title and became a billboard.
 *
 * 30rem is not a new number: the art column at desktop tops out at 476.42px
 * (0.425 of an 82.5rem shell less the grid gap), so this is that same slot
 * rounded up. The photograph is therefore the same physical size on a tablet as
 * on a desktop and only its position changes — beside the text above 56.3125rem,
 * under it below. The cap never binds at desktop, where the column is already
 * narrower than it, so this is one rule rather than a breakpoint's worth.
 *
 * Left-aligned rather than centred: a grid item narrower than its track starts
 * at the track's inline start, which is the same edge the title and the deck
 * begin at.
 */
.prp-guide__mast-art {
	max-width: 30rem;
}

.prp-guide__mast-art figure,
.prp-guide__mast-art .wp-block-post-featured-image {
	border-radius: var(--prp-radius-xl);
	overflow: hidden;
	box-shadow: var(--prp-shadow-art);
	margin: 0;
}

/* Byline row: who wrote it, when it was last reviewed, how long it takes to
   read, and a link to the standards the guide is written against. */
/* --prp-ink-muted reaches only 4.1:1 at this size on the tinted masthead,
   short of AA; the body ink clears it at 6.4:1 and still reads as secondary
   beside the title. Same judgement the approved design makes for the note under
   the mailing-list form. */
.prp-meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.5rem 1.125rem;
	font-size: var(--prp-step--1);
	color: var(--prp-ink-body);
}

.prp-meta__item {
	display: inline-flex;
	align-items: center;
	gap: 0.4375rem;
}

.prp-meta__item p,
.prp-meta__item .wp-block-post-date,
.prp-meta__item .wp-block-post-author-name {
	font-size: inherit;
	color: inherit;
	margin: 0;
}

.prp-meta__dot {
	width: 0.3125rem;
	height: 0.3125rem;
	border-radius: 50%;
	background: var(--prp-aqua);
}

.prp-meta__standards {
	color: var(--prp-green-link);
	font-weight: 700;
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-meta__standards:hover {
	color: var(--prp-forest);
}

.prp-guide__body {
	display: grid;
	gap: var(--prp-gap-grid);
	/* Asymmetric: the masthead above already supplies the air, so a full
	   section step on top would stack two of them and read as a gap. */
	padding-block: var(--prp-section-sm) var(--prp-section);
	align-items: start;
}

.prp-guide__content {
	display: flex;
	flex-direction: column;
	gap: 2.5rem;
	min-width: 0;
	/* Wider than the site's default reading measure: the comparison table and
	   the pick cards need the room. */
	max-width: 58rem;

	/*
	 * The column is the measure in a guide.
	 *
	 * Holding the copy to the global 38rem inside a column drawn at 58rem left
	 * every paragraph and list ~200px short of the heading above it and of the
	 * note directly below — both of which span the column — which reads as a
	 * ragged column rather than as a measure. It is the same correction
	 * `.prp-page__content` already makes further down, and the width the editor
	 * canvas has drawn this article at since assets/css/editor.css restated the
	 * token for posts; the front end was the one surface still disagreeing.
	 *
	 * Stated as the token so every element that honours it moves together —
	 * prose, FAQ answers — without restating a selector, and scoped to this
	 * column so the masthead above and the rail beside it keep the 38rem the
	 * root declares.
	 */
	--prp-measure: 58rem;
}

/*
 * The article inside the column.
 *
 * The guide body is the post-content block now — the rail beside it belongs to
 * templates/single.html, so a writer edits the article and nothing else. That
 * makes post content a single flex item rather than a stack of them, so the
 * rhythm the column's `gap` used to supply is restated here, and core's
 * constrained layout is stopped from capping a section a second time inside a
 * column that already has a width.
 */
.prp-guide__content > .wp-block-post-content > * {
	margin-block: 0;
	max-width: none;
}

.prp-guide__content > .wp-block-post-content > * + * {
	margin-block-start: 2.5rem;
}

/* Anything an in-page anchor can land on has to clear the sticky masthead. */
.prp-guide__content [id],
.prp-page__content [id],
.prp-pick {
	scroll-margin-top: var(--prp-sticky-offset);
}

.prp-guide__update {
	margin-top: 1.125rem;
	padding: 0.875rem 1rem;
	border-left: 3px solid var(--prp-clay-rule);
	background: var(--prp-surface-muted);
	border-radius: 0 var(--prp-radius) var(--prp-radius) 0;
	font-size: var(--prp-step--1);
	line-height: 1.6;
	color: var(--prp-ink-body);
	max-width: none;
}

.prp-guide__update strong {
	color: var(--prp-ink-heading-alt);
	font-weight: 750;
}

.prp-link-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.5rem 1.25rem;
	font-size: var(--prp-step-0);
	font-weight: 800;
	max-width: none;
}

.prp-link-actions a {
	color: var(--prp-green-link);
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-link-actions a:hover {
	color: var(--prp-forest);
}

.prp-related {
	background: var(--prp-surface);
	border-top: 1px solid var(--prp-line);
	padding-block: var(--prp-section);
}

/* ==========================================================================
   Side rail

   Takeaways first, then the section index. On narrow screens the rail moves
   above the body rather than disappearing — the takeaways are the most useful
   part of the page on a phone.
   ========================================================================== */

.prp-rail {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	order: -1;
}

.prp-panel,
.is-style-prp-panel {
	border: 1px solid var(--prp-line-card);
	border-radius: var(--prp-radius-lg);
	padding: 1.25rem 1.3125rem;
	background: var(--prp-surface);
}

.prp-panel--takeaways {
	background: linear-gradient(160deg, #f2f9f5 0%, #e8f4ee 100%);
	border-color: #d5e8de;
}

.prp-panel h2,
.is-style-prp-panel h2,
.prp-panel__title {
	font-family: var(--prp-font-body);
	font-size: var(--prp-step--1);
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--prp-green-ink);
	margin: 0 0 0.875rem;
}

.prp-panel ul,
.is-style-prp-panel ul {
	display: flex;
	flex-direction: column;
	gap: 0.6875rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.prp-panel ul li,
.is-style-prp-panel ul li {
	font-size: var(--prp-step-0);
	line-height: 1.55;
	color: var(--prp-ink-body);
}

/* Only the summary panels tick their items. An index is a list of places to go,
   not a list of things the reader gets, so the ticks would be claiming
   something the section index does not mean. */
.prp-panel:not(.prp-panel--plain):not(.prp-panel--toc) ul li {
	position: relative;
	padding-left: 1.375rem;
}

.prp-panel:not(.prp-panel--plain):not(.prp-panel--toc) ul li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.45em;
	width: 0.9375rem;
	height: 0.9375rem;
	background-color: var(--prp-green);
	-webkit-mask: var(--prp-tick) center / contain no-repeat;
	mask: var(--prp-tick) center / contain no-repeat;
}

.prp-panel--toc ol {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
	counter-reset: prp-toc;
	list-style: none;
	padding: 0;
	margin: 0;
}

.prp-panel--toc a {
	display: grid;
	grid-template-columns: 1.5rem 1fr;
	gap: 0.5rem;
	padding: 0.5rem 0;
	font-size: var(--prp-step-0);
	font-weight: 650;
	color: var(--prp-ink-body);
	text-decoration: none;
	border-bottom: 1px solid var(--prp-line);
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-panel--toc li:last-child a {
	border-bottom: 0;
}

.prp-panel--toc a::before {
	counter-increment: prp-toc;
	content: counter(prp-toc, decimal-leading-zero);
	color: var(--prp-ink-subtle);
	font-weight: 800;
	font-size: var(--prp-step--2);
	letter-spacing: 0.06em;
	padding-top: 0.125rem;
}

.prp-panel--toc a:hover {
	color: var(--prp-green-link);
}

/* An unnumbered index, used on the informational pages where the sections are
   not a sequence to be followed in order. */
.prp-panel--plain a {
	display: block;
	padding: 0.375rem 0;
	font-weight: 650;
	color: var(--prp-ink-body);
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-panel--plain a:hover {
	color: var(--prp-green-link);
}

/* Subheadings, where a section index is set deep enough to list them. The
   indent is the only thing that says a level-3 entry sits under the level-2
   above it, since the list itself stays flat. */
.prp-section-index__item.is-level-3 a {
	padding-left: 0.875rem;
}

.prp-section-index__item.is-level-4 a {
	padding-left: 1.75rem;
}

@media (min-width: 56.3125rem) {
	.prp-guide__mast-inner {
		grid-template-columns: 1.15fr 0.85fr;
		gap: var(--prp-gap-grid);
	}

	.prp-guide__body {
		grid-template-columns: 19.5rem minmax(0, 1fr);
	}

	.prp-rail {
		order: 0;
		position: sticky;
		top: var(--prp-sticky-offset);
	}
}

/* ==========================================================================
   Standard page
   ========================================================================== */

.prp-page__body {
	display: grid;
	gap: var(--prp-gap-grid);
	padding-block: var(--prp-section-sm) var(--prp-section);
	align-items: start;
}

.prp-page__content {
	display: flex;
	flex-direction: column;
	gap: 2.25rem;
	max-width: 44rem;
	/*
	 * The column is the measure on a page.
	 *
	 * A guide's column is wider than its copy on purpose — the article runs
	 * beside a rail and holds tables and cards, so the reading width is set
	 * inside it. A page's column is already the reading width, capped at 44rem
	 * here, and everything that is not a paragraph — its headings, its notes,
	 * its panels — spans that cap. Leaving the paragraphs and lists at 38rem
	 * left them 96px short of the heading directly above them and of the note
	 * directly below, which reads as a ragged column rather than a measure.
	 *
	 * Stated as the token so every element that honours it moves together, and
	 * scoped to this column so `.prp-guide__content` keeps its own.
	 */
	--prp-measure: 44rem;
}

/*
 * The page body inside the column.
 *
 * The sections are the post-content block now — the column and the rail beside
 * it belong to templates/page-standard.html, so an editor writes the page and
 * nothing else. That makes post content a single flex item rather than a stack
 * of them, so the rhythm the column's `gap` used to supply is restated here, and
 * core's constrained layout is stopped from capping a section a second time
 * inside a column that already has a width.
 */
.prp-page__content > .wp-block-post-content > * {
	margin-block: 0;
	max-width: none;
}

.prp-page__content > .wp-block-post-content > * + * {
	margin-block-start: 2.25rem;
}

@media (min-width: 56.3125rem) {
	.prp-page__body {
		/*
		 * The column is sized to what it holds rather than to whatever is left
		 * over. As `minmax(0, 1fr)` it took the whole band and then capped its
		 * own content at 44rem, so ~113px of empty track sat between the prose
		 * and the rail on top of the grid gap — and the copy inside stops at
		 * `--prp-measure` again, which pushed the visible gap wider still.
		 * Capping the track instead leaves the gap at the design token.
		 *
		 * The rail takes whatever is left over rather than the band trailing it.
		 * Two fixed tracks in a wider band left 113px of empty grid after the
		 * rail, which reads as the gutter being the thing that is oversized. A
		 * flexible rail only grows once the prose has reached its cap — grid
		 * maximizes the non-flexible track first — so the copy measure is
		 * unchanged and only the surplus moves.
		 */
		grid-template-columns: minmax(0, 44rem) minmax(19rem, 1fr);
	}

	/* The rail sits second on this template: the body is the page, and the
	   summary is a companion to it rather than an index in front of it. */
	.prp-page__body .prp-rail {
		order: 0;
	}
}

/* ==========================================================================
   Comparison table

   A real <table> with a caption, column headers and a row header per pick — the
   comparison is tabular data, and turning it into styled divs would strip
   exactly the structure a screen reader uses to read a cell in context. The
   scroll container is focusable and labelled so it can be scrolled from the
   keyboard on narrow screens instead of being clipped.
   ========================================================================== */

.prp-scroller,
.is-style-prp-scroller {
	overflow-x: auto;
	border: 1px solid var(--prp-line-card);
	border-radius: var(--prp-radius-lg);
	background: var(--prp-surface);
	max-width: none;
}

.prp-scroller:focus-visible,
.is-style-prp-scroller:focus-visible {
	outline: 3px solid var(--prp-focus);
	outline-offset: 2px;
}

.prp-scroller table,
.is-style-prp-scroller table {
	width: 100%;
	min-width: 44rem;
	border-collapse: collapse;
	font-size: var(--prp-step--1);
	margin: 0;
}

/* The scroll belongs to the labelled container, not to the figure inside it.
   Core ships `.wp-block-table { overflow-x: auto }`, so without this the inner
   figure is the element that actually scrolls while the outer element — the one
   carrying `role="region"` and `tabindex="0"` — never overflows and cannot be
   scrolled from the keyboard at all. Returning the figure to `visible` lets the
   table's own `min-width` overflow the container that is focusable, which is
   what makes a keyboard user's focus stop useful. See F-1 in
   docs/launch-articles-2026-09-01.md. */
.prp-scroller .wp-block-table,
.is-style-prp-scroller .wp-block-table {
	margin: 0;
	overflow: visible;
}

.prp-scroller caption,
.prp-scroller figcaption,
.is-style-prp-scroller caption,
.is-style-prp-scroller figcaption {
	text-align: left;
	padding: 1rem 1.125rem;
	color: var(--prp-ink-muted);
	line-height: 1.55;
	border-bottom: 1px solid var(--prp-line);
	font-size: var(--prp-step--1);
	caption-side: top;
}

.prp-scroller th,
.prp-scroller td,
.is-style-prp-scroller th,
.is-style-prp-scroller td {
	text-align: left;
	padding: 0.8125rem 1.125rem;
	vertical-align: top;
	border: 0;
	border-bottom: 1px solid var(--prp-line);
}

.prp-scroller thead th,
.is-style-prp-scroller thead th {
	background: var(--prp-surface-muted);
	color: var(--prp-ink-heading-alt);
	font-size: var(--prp-step--2);
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	white-space: nowrap;
}

.prp-scroller tbody th,
.is-style-prp-scroller tbody th {
	color: var(--prp-ink-heading-alt);
	font-weight: 750;
	width: 11rem;
}

/* Eligibility wording is the longest cell in the table and the one that must
   stay readable: give it room before the other columns take it. */
.prp-scroller th:nth-child(4),
.prp-scroller td:nth-child(4),
.is-style-prp-scroller th:nth-child(4),
.is-style-prp-scroller td:nth-child(4) {
	min-width: 11rem;
}

.prp-scroller td,
.is-style-prp-scroller td {
	color: var(--prp-ink-body);
	line-height: 1.5;
}

.prp-scroller tbody tr:last-child th,
.prp-scroller tbody tr:last-child td,
.is-style-prp-scroller tbody tr:last-child th,
.is-style-prp-scroller tbody tr:last-child td {
	border-bottom: 0;
}

.prp-scroller tbody tr:hover,
.is-style-prp-scroller tbody tr:hover {
	background: #fbfcfb;
}

/* Not a pill: these labels wrap in a narrow column, and a pill radius on three
   lines of text reads as a mistake. */
.prp-scroller td mark,
.is-style-prp-scroller td mark,
.prp-eligibility {
	display: inline-block;
	padding: 0.25rem 0.5rem;
	border-radius: var(--prp-radius-sm);
	line-height: 1.4;
	background: var(--prp-surface-mint);
	color: var(--prp-green-ink);
	font-weight: 700;
}

/* ==========================================================================
   Pick card

   Deliberately category-level: no brand name, no price, no star rating and no
   outbound merchant link, because none of those exist yet. The layout is the
   real one — price slot, merchant row and CTA are present and clearly marked as
   pending, so filling them in later is a content change rather than a redesign.
   ========================================================================== */

.prp-picks {
	display: flex;
	flex-direction: column;
	gap: 1.125rem;
	max-width: none;
}

.prp-pick {
	display: flex;
	flex-direction: column;
	gap: 1rem;
	padding: 1.375rem 1.4375rem 1.5rem;
	border: 1px solid var(--prp-line-card);
	border-radius: var(--prp-radius-lg);
	background: var(--prp-surface);
	max-width: none;
}

.prp-pick > * {
	max-width: none;
}

.prp-pick__head {
	display: grid;
	grid-template-columns: auto 1fr;
	align-items: start;
	gap: 0.5rem 0.875rem;
}

.prp-pick__rank {
	display: grid;
	place-items: center;
	width: 2.25rem;
	height: 2.25rem;
	border-radius: 0.75rem;
	background: var(--prp-forest);
	color: var(--prp-mint);
	font-size: var(--prp-step--1);
	font-weight: 800;
	letter-spacing: 0.04em;
}

.prp-pick__head h3 {
	font-family: var(--prp-font-body);
	font-size: var(--prp-step-2);
	font-weight: 750;
	line-height: 1.2;
	letter-spacing: -0.02em;
	color: var(--prp-ink-heading-alt);
	margin: 0;
}

.prp-pick__role {
	margin-top: 0.25rem;
	font-size: var(--prp-step--1);
	color: var(--prp-ink-muted);
}

.prp-pick__tier {
	grid-column: 2;
	justify-self: start;
	padding: 0.25rem 0.625rem;
	border-radius: 999px;
	border: 1px solid var(--prp-line-button);
	background: var(--prp-surface-muted);
	color: var(--prp-ink-body);
	font-size: var(--prp-step--2);
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}

.prp-pick__summary {
	font-size: var(--prp-step-0);
	line-height: 1.65;
	color: var(--prp-ink-body);
}

.prp-pick__specs {
	display: grid;
	gap: 0.0625rem;
	margin: 0;
	border: 1px solid var(--prp-line);
	border-radius: var(--prp-radius);
	overflow: hidden;
	background: var(--prp-line);
}

.prp-pick__spec {
	display: grid;
	grid-template-columns: 1fr;
	gap: 0.125rem;
	padding: 0.625rem 0.875rem;
	background: var(--prp-surface-muted);
}

.prp-pick__spec dt {
	font-size: var(--prp-step-0);
	font-weight: 800;
	color: var(--prp-ink-heading-alt);
}

.prp-pick__spec dd {
	margin: 0;
	font-size: var(--prp-step-0);
	color: var(--prp-ink-body);
	line-height: 1.55;
}

.prp-pick__verdict {
	display: grid;
	gap: 0.875rem;
}

.prp-pick__column h4 {
	font-family: var(--prp-font-body);
	font-size: var(--prp-step--2);
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--prp-ink-muted);
	margin: 0 0 0.5rem;
}

.prp-pick__column ul {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.prp-pick__column li {
	position: relative;
	padding-left: 1.375rem;
	font-size: var(--prp-step-0);
	line-height: 1.5;
	color: var(--prp-ink-body);
}

.prp-pick__column li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0.4em;
	width: 0.9375rem;
	height: 0.9375rem;
}

.prp-pick__column--pros li::before {
	background-color: var(--prp-green);
	-webkit-mask: var(--prp-tick) center / contain no-repeat;
	mask: var(--prp-tick) center / contain no-repeat;
}

.prp-pick__column--cons li::before {
	background-color: var(--prp-clay-deep);
	-webkit-mask: var(--prp-minus) center / contain no-repeat;
	mask: var(--prp-minus) center / contain no-repeat;
}

.prp-pick__fit {
	font-size: var(--prp-step-0);
	color: var(--prp-ink-body);
}

.prp-pick__fit strong {
	color: var(--prp-ink-heading-alt);
	font-weight: 750;
}

.prp-pick__commerce {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.75rem 1.25rem;
	padding-top: 1rem;
	border-top: 1px dashed var(--prp-line-strong);
}

.prp-pick__price {
	display: flex;
	flex-direction: column;
	gap: 0.125rem;
}

.prp-pick__price-label {
	font-size: var(--prp-step--2);
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	/* --prp-ink-subtle is 4.06:1 on white, which 12px text cannot carry. */
	color: var(--prp-ink-body);
}

.prp-pick__price-value {
	font-size: var(--prp-step-0);
	font-weight: 750;
	color: var(--prp-ink-muted);
}

.prp-pick__merchants {
	display: flex;
	flex-wrap: wrap;
	gap: 0.375rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.prp-pick__merchants li {
	padding: 0.3125rem 0.625rem;
	border-radius: 999px;
	border: 1px dashed var(--prp-line-button);
	color: var(--prp-ink-body);
	font-size: var(--prp-step--1);
	font-weight: 700;
}

.prp-pick__cta {
	display: inline-flex;
	align-items: center;
	gap: 0.375rem;
	margin-left: auto;
	font-size: var(--prp-step-0);
	font-weight: 800;
	color: var(--prp-green-link);
	text-decoration: none;
	transition: color var(--prp-duration) var(--prp-ease);
}

.prp-pick__cta:hover {
	color: var(--prp-forest);
}

/* Content breakpoint, not a device band: 481px is where the 9rem term column
   stops squeezing its definition. */
@media (min-width: 30.0625rem) {
	.prp-pick__spec {
		grid-template-columns: 9rem 1fr;
		gap: 0.75rem;
	}
}

@media (min-width: 42.5625rem) {
	.prp-pick__verdict {
		grid-template-columns: 1fr 1fr;
		gap: 1.5rem;
	}
}

/* ==========================================================================
   FAQ

   core/details: keyboard operable, expandable without script, and searchable by
   the browser's own find-in-page in modern engines.
   ========================================================================== */

.prp-faqs {
	display: flex;
	flex-direction: column;
	gap: 0.625rem;
	max-width: none;
}

.prp-faqs .wp-block-details {
	border: 1px solid var(--prp-line-card);
	border-radius: var(--prp-radius-lg);
	background: var(--prp-surface);
	overflow: hidden;
	margin: 0;
	padding: 0;
	max-width: none;
}

.prp-faqs summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	padding: 1rem 1.125rem;
	cursor: pointer;
	list-style: none;
	font-family: var(--prp-font-body);
	font-size: var(--prp-step-0);
	font-weight: 750;
	line-height: 1.4;
	letter-spacing: -0.01em;
	color: var(--prp-ink-heading-alt);
}

/* Replace the platform disclosure triangle with the site's own chevron. */
.prp-faqs summary::-webkit-details-marker,
.prp-faqs summary::marker {
	display: none;
	content: "";
}

.prp-faqs summary::after {
	content: "";
	flex: none;
	width: 1.125rem;
	height: 1.125rem;
	background-color: var(--prp-green);
	-webkit-mask: var(--prp-chevron-down) center / contain no-repeat;
	mask: var(--prp-chevron-down) center / contain no-repeat;
	transition: transform var(--prp-duration) var(--prp-ease);
}

.prp-faqs .wp-block-details[open] summary::after {
	transform: rotate(180deg);
}

.prp-faqs .wp-block-details[open] summary {
	border-bottom: 1px solid var(--prp-line);
}

.prp-faqs summary:focus-visible {
	outline: 3px solid var(--prp-focus);
	outline-offset: -3px;
	border-radius: var(--prp-radius-lg);
}

.prp-faqs .wp-block-details > *:not(summary) {
	padding-inline: 1.125rem;
	max-width: var(--prp-measure);
}

.prp-faqs .wp-block-details > *:not(summary):first-of-type {
	padding-top: 0.9375rem;
}

.prp-faqs .wp-block-details > *:not(summary):last-child {
	padding-bottom: 1.125rem;
}

.prp-faqs .wp-block-details p {
	font-size: var(--prp-step-0);
	line-height: 1.65;
	color: var(--prp-ink-body);
	margin: 0;
}

@media (hover: hover) {
	.prp-faqs summary:hover {
		color: var(--prp-green-link);
	}
}

/* ==========================================================================
   404

   A 404 is a navigation problem, so the page is mostly navigation: the routes
   that exist, the topics the library is organised by, and the guides someone
   mistyping a recovery URL most likely wanted.
   ========================================================================== */

.prp-404__inner {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1.125rem;
	padding-block: var(--prp-section-lg);
	max-width: 52rem;
}

.prp-404__code {
	font-family: var(--prp-font-display);
	font-weight: 700;
	font-size: clamp(3.5rem, 2rem + 7vw, 6rem);
	line-height: 0.95;
	letter-spacing: -0.03em;
	color: var(--prp-mint);
	text-shadow: 0 1px 0 rgba(23, 62, 52, 0.08);
}

.prp-404__inner h1 {
	font-size: var(--prp-step-3);
	line-height: 1.05;
	color: var(--prp-forest);
}

.prp-404__lede {
	font-size: var(--prp-step-1);
	line-height: 1.55;
	color: var(--prp-ink-body);
	max-width: 34rem;
}

.prp-404__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 0.75rem;
	margin-top: 0.375rem;
}

.prp-destinations {
	width: 100%;
	margin-top: 1rem;
}

.prp-destinations ul {
	display: grid;
	gap: 0.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.prp-destinations a {
	display: flex;
	flex-direction: column;
	gap: 0.25rem;
	padding: 0.9375rem 1.0625rem;
	border: 1px solid var(--prp-line-card);
	border-radius: var(--prp-radius-lg);
	background: var(--prp-surface);
	text-decoration: none;
	transition:
		transform var(--prp-duration) var(--prp-ease),
		box-shadow var(--prp-duration) var(--prp-ease);
}

.prp-destinations a:hover {
	transform: translateY(-2px);
	box-shadow: var(--prp-shadow-card);
}

.prp-destinations strong {
	display: inline-flex;
	align-items: center;
	gap: 0.4375rem;
	font-size: var(--prp-step-0);
	font-weight: 800;
	color: var(--prp-green-link);
}

.prp-destinations small {
	font-size: var(--prp-step--1);
	color: var(--prp-ink-muted);
}

.prp-topics {
	width: 100%;
	margin-top: 0.5rem;
}

.prp-topics__title {
	font-family: var(--prp-font-body);
	font-size: var(--prp-step--1);
	font-weight: 800;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--prp-green-ink);
	margin-bottom: 0.75rem;
}

.prp-suggested {
	background: var(--prp-surface);
	padding-block: var(--prp-section);
}

@media (min-width: 42.5625rem) {
	.prp-destinations ul {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* ==========================================================================
   Search
   ========================================================================== */

.prp-search__form {
	display: flex;
	flex-wrap: wrap;
	gap: 0.625rem;
	max-width: 34rem;
}

.prp-search__form .wp-block-search__input {
	flex: 1 1 12rem;
	min-width: 0;
	font: inherit;
	font-size: var(--prp-step-0);
	color: var(--prp-ink);
	background: var(--prp-surface);
	border: 1px solid var(--prp-line-button);
	border-radius: var(--prp-radius);
	padding: 0.8125rem 0.9375rem;
}

.prp-search__form .wp-block-search__button {
	margin: 0;
	border: 0;
	border-radius: var(--prp-radius);
	background: var(--prp-green);
	color: #fff;
	font-weight: 700;
	padding: 0.875rem 1.25rem;
	cursor: pointer;
}

/* Core spaces the field from its button with a margin on the button, which
   the reset above removes; the space is restated on the row that holds them,
   so the two rounded boxes never touch. Measured before this rule: 0px
   between them on the search template. */
.prp-search__form .wp-block-search__inside-wrapper {
	gap: 0.625rem;
}

/* ==========================================================================
   Icon masks

   Three glyphs are drawn as CSS masks rather than inline SVG: the tick on list
   items, the minus on tradeoff rows, and the FAQ chevron. All three sit on
   list items and summaries that are plain core blocks, and keeping them in CSS
   is what lets those blocks stay editable — an inline <svg> inside a list item
   would have to be authored into the content and would be lost the first time
   an editor retyped the line.
   ========================================================================== */

:root {
	--prp-tick: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12l5 5l10 -10"/></svg>');
	--prp-minus: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12l14 0"/></svg>');
	--prp-chevron-down: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6l6 -6"/></svg>');
}

/* ==========================================================================
   Motion and print
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

@media print {
	.prp-promo,
	.prp-header,
	.prp-newsletter,
	.prp-filters,
	.prp-finder {
		display: none;
	}

	header.wp-block-template-part {
		position: static;
	}

	body {
		background: #fff;
	}
}
