/**
 * PropFirmGrade component layer.
 *
 * Chrome anatomy taken from the resolved "PropFirm Deals Dashboard (World
 * Accent)" document: the sticky header with its world glow, the segmented
 * vertical switcher, the primary and secondary navigations, the hero, the
 * three-column footer and the phone tab bar.
 *
 * Breakpoints match the design exactly:
 *   >= 1080px  desktop: switcher + both navigations inline, no burger
 *   761-1079   tablet:  20px gutter, burger, full-width switcher band, tab bar
 *   <= 760px   phone:   12px gutter, everything above plus phone type scale
 *
 * Nothing here needs JavaScript. The mobile menu is a checkbox read through
 * :has(); the search field expands on :focus-within; submenus open on
 * :hover and :focus-within, which is core's own CSS-only behaviour.
 */

/* =========================================================================
   Sticky header

   --hdr-h is a contract, not a guess: the secondary navigation sticks to it.
   The header's height is therefore pinned per tier rather than left to flex.
     >= 1080px  one row   14 + 46 + 14 + 1
     1080-1499  two rows  ONLY while the account pair is rendered — it is
                flex-basis 100% below 1500px and breaks to its own line. The
                pair is withheld for the MVP ('account-auth' in Unbuilt.php),
                so the tier is keyed on its presence rather than assumed:
                assume it and the subnav sticks 60px below a one-row header.
     <= 1079px  logo row + the full-bleed switcher band
   ========================================================================= */

:root {
	--hdr-h: 75px;
}

@media (min-width: 1080px) and (max-width: 1499px) {
	:root:has(.pfg-header .pfg-auth) {
		--hdr-h: 135px;
	}
}

@media (max-width: 1079px) {
	:root {
		--hdr-h: 140px;
		/* The LOGO ROW alone: 14px of header padding plus the 44px search/burger
		   row, plus the switcher band's 12px top margin. It is a contract for the
		   same reason --hdr-h is — the mobile drawer and its scrim hang from it,
		   and they must cover the switcher band rather than start below it. */
		--hdr-row-h: 70px;
	}
}

.pfg-header {
	position: sticky;
	top: 0;
	z-index: 50;
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 14px;
	padding: 14px max(var(--gutter), 50% - 880px);
	background: var(--header-bg);
	-webkit-backdrop-filter: blur(14px);
	backdrop-filter: blur(14px);
	border-bottom: 1px solid var(--border-1);
}

/* Two decorative glows welded to the header's bottom edge: a hairline sweep
   and the bloom that spills onto the page below. Both world-tinted. */
.pfg-header::before,
.pfg-header::after {
	content: "";
	position: absolute;
	pointer-events: none;
	transition: background 850ms ease;
}

.pfg-header::before {
	left: 0;
	right: 0;
	bottom: -1px;
	height: 3px;
	filter: blur(2px);
	background: linear-gradient(
		90deg,
		transparent 0%,
		rgba(var(--world-rgb), 0.12) 30%,
		rgba(var(--world-rgb), 0.26) 50%,
		rgba(var(--world-rgb), 0.12) 70%,
		transparent 100%
	);
}

.pfg-header::after {
	left: -4%;
	right: -4%;
	bottom: -190px;
	height: 190px;
	filter: blur(6px);
	background: radial-gradient(
		58% 120% at 50% 0%,
		rgba(var(--world-rgb), 0.30),
		rgba(var(--world-rgb), 0.10) 45%,
		transparent 72%
	);
}

/* ---- Wordmark ---- */

.pfg-lockup {
	order: -3;
	display: inline-flex;
	align-items: center;
	flex: 0 0 auto;
	margin-right: 4px;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	text-decoration: none;
}

.pfg-lockup svg {
	display: block;
	height: 24px;
	width: auto;
}

.pfg-lockup:hover {
	color: var(--wp--preset--color--text-1, #F2F3F8);
	filter: brightness(1.15);
}

/* =========================================================================
   Vertical switcher: a solid world chip

   RESOLVED 2026-08-27. The owner's boss picked "02 Solid chip" out of eleven
   rendered candidates, after eight iterations of this control. The reference
   was the cookie-consent Accept button — solid #E6FF00 with dark ink on it,
   no transparency and no mixing — and the chip now wears exactly that: the
   live world's own colour at full strength, labelled in that world's ink.

   THE HISTORY BELOW IS KEPT BECAUSE IT RULES THINGS OUT. Everything before
   this was drawn and measured; without the figures somebody re-derives them
   and proposes a ninth.

   The measurement that bounds the whole problem, made on the fourth pass and
   still the reason nothing quiet can work here. Every neutral, against the
   header it sits in:

     recess, the original track fill, vs the header   1.02:1
     border-1, the original hairline                  1.15:1
     border-strong, the brightest hairline we have    1.48:1
     surface-chip, brightest surface token            1.34:1

   `--recess` is rgb(13,15,22) at 60% over a header already rgb(16,18,25), so
   the track can never be more than ~2/255 darker than its surroundings, and
   NOTHING in the neutral palette clears 1.5:1. A version working greys alone
   cannot be seen. Then:

     - FOURTH PASS, 2026-08-26. Four rendered candidates; the owner picked a
       neutral chip carrying visibility with one 2px accent rule along its
       bottom edge carrying identity. The three it beat were rejected as too
       faint, then too loud — the loud one being three saturated accent
       pills, which were legible and looked cheap.
     - 6e7cd66 (#85) replaced that with a TINTED chip: a 16% tint of the
       world's colour ringed at 40%, the toplist rank badge's ratios exactly,
       so the two controls would agree instead of each inventing a strength.
       Right in kind, too quiet in degree. (It also left this banner's title
       reading "a neutral raised chip with one accent rule" for a day, over
       rules that no longer did that. Titles go stale silently; the figures
       below do not.)
     - A gallery of eleven, 2026-08-27, drawn to settle it. The near miss was
       an EQUALISED TINT: each world's chip hand-mixed to land on the same
       contrast against the track rather than the same alpha. It fixes the
       fairness problem below, and the three chips come out muted olive, plum
       and teal — further from the brand colours than anything else on the
       board.
     - THIS. Solid, and the tint taken out entirely.

   CONTRAST IS NOT EQUAL ACROSS THE WORLDS. That is a property of the choice
   and the trade that was accepted, not a defect to fix by re-tinting — the
   equalised tint above is what fixing it looks like, and it was rejected.
   Measured 2026-08-27 from the engine's computed values on a rendered header,
   chip against the header behind it and label ink against the chip:

     futures   chip on header 16.63:1   ink on chip 16.38:1
     forex     chip on header  4.74:1   ink on chip  4.80:1
     crypto    chip on header 12.81:1   ink on chip  9.97:1

   The second column is the one that governs legibility, and every world
   clears AA on it. The first column simply reports that #E6FF00 is a
   brighter colour than #B14BFF: futures is about 3.5x as emphatic as forex
   at the same setting. Nothing here can change that without changing the
   brand accents.

   THE COLOUR IS NEVER A HEX HERE. Position comes from :nth-child, colour
   from `--v-*` / `--v-*-ink` in base.css, and the markup order from one
   array in blocks/vertical-switcher/render.php. ORDER IS LOAD-BEARING and
   assertions in test-blocks.php pin the three together, because reordering
   that array alone would light the wrong cell.

   NO JAVASCRIPT. `:has()` reads active and hover, so this is a
   server-rendered control that behaves with scripting off, as the FSE rules
   require of public product content. Hovering slides the chip and recolours
   it to the world you would land in; leaving returns it to the live one.

   THE SLIDE IS A HOVER AFFORDANCE ONLY. These are links to three separate
   pages: on click the document navigates and any transition is discarded.
   ========================================================================= */

.pfg-segwrap {
	display: contents;
}

.pfg-seg {
	order: -2;
	flex: 0 0 auto;
	position: relative;
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	align-items: stretch;
	height: 46px;
	padding: 4px;
	margin-right: 10px;
	border-radius: var(--wp--custom--radius--md, 14px);
	background: var(--wp--preset--color--surface-3, #171B26);
	border: 1px solid var(--border-2);
	box-sizing: border-box;
	transition: border-color 220ms ease;
}

.pfg-seg:hover,
.pfg-seg:focus-within {
	border-color: var(--border-strong);
}

/* The chip. Absolutely positioned so it is not a grid item, sized to exactly
   one column, and moved in whole multiples of its own width so the arithmetic
   cannot drift as label lengths change.

   NO BORDER AND NO ALPHA. The tinted version needed a 40% ring to hold an
   edge against the track; a solid fill is its own edge, and a ring on top of
   it would only be a second, dimmer outline of the same shape. */
.pfg-seg::before {
	content: "";
	position: absolute;
	z-index: 0;
	top: 4px;
	bottom: 4px;
	left: 4px;
	width: calc((100% - 8px) / 3);
	box-sizing: border-box;
	border-radius: var(--wp--custom--radius--sm, 11px);
	background: var(--pfg-seg-world, transparent);
	border: 0;
	transform: translateX(var(--pfg-seg-x, 0));
	transition:
		transform 300ms cubic-bezier(0.22, 1, 0.36, 1),
		background-color 220ms ease;
}

/* Nothing selected (on /firms/, /methodology/) means no chip at all, rather
   than a chip in some neutral default pretending to be a selection. */
.pfg-seg:not(:has(> .pfg-seg__link.is-active)):not(:has(> .pfg-seg__link:is(:hover, :focus-visible)))::before {
	background: transparent;
}

/* Where the chip rests: the live vertical. On /firms/ and /methodology/ no
   segment is active, none of these properties is set, and the chip stays fully
   transparent — the control shows no selection rather than inventing one. */
.pfg-seg:has(> .pfg-seg__link:nth-child(1).is-active) {
	--pfg-seg-x: 0%;
	--pfg-seg-world: var(--v-futures);
	--pfg-seg-ink: var(--v-futures-ink);
}

.pfg-seg:has(> .pfg-seg__link:nth-child(2).is-active) {
	--pfg-seg-x: 100%;
	--pfg-seg-world: var(--v-forex);
	--pfg-seg-ink: var(--v-forex-ink);
}

.pfg-seg:has(> .pfg-seg__link:nth-child(3).is-active) {
	--pfg-seg-x: 200%;
	--pfg-seg-world: var(--v-crypto);
	--pfg-seg-ink: var(--v-crypto-ink);
}

/* Hover and keyboard focus PREVIEW another world. These must stay after the
   resting rules: when cell 1 is live and cell 3 is hovered both match, and the
   later declaration has to win. Source order is the mechanism — do not sort. */
.pfg-seg:has(> .pfg-seg__link:nth-child(1):is(:hover, :focus-visible)) {
	--pfg-seg-x: 0%;
	--pfg-seg-world: var(--v-futures);
	--pfg-seg-ink: var(--v-futures-ink);
}

.pfg-seg:has(> .pfg-seg__link:nth-child(2):is(:hover, :focus-visible)) {
	--pfg-seg-x: 100%;
	--pfg-seg-world: var(--v-forex);
	--pfg-seg-ink: var(--v-forex-ink);
}

.pfg-seg:has(> .pfg-seg__link:nth-child(3):is(:hover, :focus-visible)) {
	--pfg-seg-x: 200%;
	--pfg-seg-world: var(--v-crypto);
	--pfg-seg-ink: var(--v-crypto-ink);
}

.pfg-seg__link {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--wp--custom--radius--sm, 11px);
	padding: 0 clamp(16px, 1.3vw, 24px);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--ui-sm, clamp(13.5px, 0.78vw, 16px));
	/* ONE WEIGHT, ALWAYS — this is a layout fix, not a style choice.
	   The grid sizes to its widest cell and the track is `flex: 0 0 auto`, so
	   its width is intrinsic. Bolding the selected label therefore resized the
	   whole control: measured at 240.30px with "Futures" bold and 229.75px with
	   "Crypto" bold, so every hover shoved the header sideways by 10.55px. The
	   owner reported it as the switcher "jumping". Selection is carried by the
	   chip and the label colour, neither of which changes a text metric.
	   Re-measured 2026-08-27 on the solid chip, at 1440 with Manrope loaded:
	   271.28px at rest, 271.28px with each of the three cells hovered, and
	   271.28px again after the pointer leaves — fifteen reads across the three
	   hubs, all identical. The width does not move. */
	font-weight: 600;
	color: var(--wp--preset--color--text-3, #979CAD);
	white-space: nowrap;
	text-decoration: none;
	transition: color 200ms ease;
}

/* Whichever cell the chip is under reads in that world's INK — dark type on a
   full-strength fill, the cookie-consent Accept button's relationship. The
   tinted version could use the accent itself as the label because the fill
   behind it was only 16%; on a solid fill the accent would be invisible on
   itself. */
.pfg-seg__link.is-active,
.pfg-seg__link:hover,
.pfg-seg__link:focus-visible {
	color: var(--pfg-seg-ink, var(--wp--preset--color--text-1, #F2F3F8));
}

/* ...and the cell the chip has LEFT stops being the bright one, or the preview
   reads as two selections at once. WITH A SOLID CHIP THIS IS NO LONGER
   COSMETIC: the departed label would keep wearing ink, and ink is dark by
   construction, so it would be near-black text on the dark track. */
.pfg-seg:has(> .pfg-seg__link:is(:hover, :focus-visible)) > .pfg-seg__link.is-active:not(:hover):not(:focus-visible) {
	color: var(--wp--preset--color--text-3, #979CAD);
}

/* FOCUS. Two problems at once, both created by going solid.

   The global :focus-visible sets border-radius:4px, which squares a pill.
   Take the pill's own radius back; the global rule is left alone.

   And the global ring is `0 0 0 1px var(--acc)`, where --acc under
   data-accent="world" IS the world's colour — and each link carries its own
   data-world, so the ring on a focused cell is always the same colour as the
   chip that focus just slid underneath it. Accent on accent is no ring at all.
   Drop the shadow ring and draw the outline in the chip's ink instead, which
   is the one colour measured to read on that fill (4.80:1 at worst, above).
   Inset by 3px so it lands inside the chip rather than straddling its edge. */
.pfg-seg__link:focus-visible {
	border-radius: var(--wp--custom--radius--sm, 11px);
	box-shadow: none;
	outline: 2px solid var(--pfg-seg-ink, var(--acc));
	outline-offset: -3px;
}

/* A moving block is the one thing here that motion sensitivity cares about.
   The chip still moves — it just arrives at once. */
@media (prefers-reduced-motion: reduce) {
	.pfg-seg::before {
		transition: none;
	}
}

/* Without :has() there is no chip at all and the live world would be marked by
   nothing but a slightly brighter label — and since that label is now INK, it
   would be near-black on the dark track: unreadable, not merely undecorated.
   Give those browsers a static solid chip on the active cell. A fallback for a
   real failure mode. */
@supports not selector(:has(*)) {
	.pfg-seg__link.is-active {
		background: var(--world);
		color: var(--world-ink);
	}

	/* --pfg-seg-ink is never set in here, so the rule above falls back to --acc
	   — correct on a bare cell, invisible on the one cell that does have a
	   chip. Name the ink for that cell. */
	.pfg-seg__link.is-active:focus-visible {
		outline-color: var(--world-ink);
	}
}

/* =========================================================================
   Navigation panel: primary menu + account buttons.
   Desktop it dissolves so its children sit directly in the header flex row.
   Mobile it becomes the menu panel under the header.
   ========================================================================= */

.pfg-navpanel {
	display: contents;
}

/* The panel is a flow container, so core hands its second child a block-gap
   margin. Once the panel dissolves into the header that margin lands on a flex
   item and silently makes the header taller than --hdr-h claims, which drags
   the sticky sub-navigation up behind it. Zero it. */
.pfg-navpanel > * {
	margin-block: 0;
}

/* flex-basis 0, not auto. A wrapping flex container places items by their
   BASE size and only shrinks within a line, so an auto-basis menu forces the
   utility cluster onto a third row instead of giving up its own width. */
.pfg-auth {
	order: 2;
	display: flex;
	align-items: center;
	gap: 6px;
	flex-wrap: nowrap;
	flex: 0 0 100%;
	justify-content: flex-start;
}

@media (min-width: 1500px) {
	.pfg-auth {
		flex: 0 0 auto;
	}
}

.pfg-auth .wp-block-button__link {
	display: inline-flex;
	align-items: center;
	height: 46px;
	line-height: 1;
	white-space: nowrap;
}

/* Ghost: the design's Log in is text only, no chrome at all. */
.wp-block-button.is-style-pfg-ghost > .wp-block-button__link,
.wp-block-button.is-style-pfg-ghost > .wp-block-button__link:hover {
	background: transparent;
	color: var(--wp--preset--color--text-2, #C6CBDD);
	font-weight: 400;
	border-radius: var(--wp--custom--radius--md, 14px);
	padding: 0 16px;
}

.wp-block-button.is-style-pfg-ghost > .wp-block-button__link:hover {
	color: var(--wp--preset--color--text-1, #F2F3F8);
	background: var(--hover-wash);
}

/* Internal link: the in-content route out of a page, in the site's primary-CTA
   language.

   ONE SIGNAL FOR "THIS NAVIGATES". A solid accent fill with an ink foreground
   already means exactly that everywhere else on the site — "Read review" on a
   toplist row, the coupon and affiliate CTAs, the consent Accept — and the
   design's own primary grammar is the same three things: border:0, an accent
   background, weight 800 (its secondaries are 700 and wear a hairline instead).
   So an in-content link that matters wears it too, rather than inventing a
   fourth button shape.

   WHY A NAMED STYLE AND NOT A SELECTOR ON ONE TEMPLATE. Since the hub bodies
   moved into post content, "Browse all reviewed firms" is a button an editor
   placed and can move, duplicate or put on another page. A rule keyed to the
   hub template would not follow it there. This is selectable in the editor's
   Styles panel as "Internal link", so the next one gets the same treatment by
   being chosen, not by being matched.

   THE ACCENT IS NEVER A LITERAL. --acc-fill / --on-acc / --acc-fill-hover are
   re-derived by [data-accent="world"] per vertical, so this is yellow on
   futures, teal on crypto and violet on forex without this sheet naming any of
   them. All three clear AA on their own fill (16.38 / 9.97 / 4.80:1).

   GEOMETRY IS NOT RESTATED. Radius, padding, size and weight come from
   theme.json's `elements.button`, which is the one place button geometry lives;
   only what MAKES this style a style is declared here. `border: 0` is, because
   the style it replaces (core's Outline) puts a 2px ring on the same element. */
.wp-block-button.is-style-pfg-cta > .wp-block-button__link {
	border: 0;
	background: var(--acc-fill);
	color: var(--on-acc);
	text-decoration: none;
}

.wp-block-button.is-style-pfg-cta > .wp-block-button__link:hover,
.wp-block-button.is-style-pfg-cta > .wp-block-button__link:focus {
	background: var(--acc-fill-hover);
	color: var(--on-acc);
}

/* The global :focus-visible squares every focused control to `border-radius: 4px`
   (a known theme-wide defect, logged on PR #61 and NOT fixed here). On a button
   that is now a solid pill that would be loud, so the radius is restated
   locally. The ring itself is untouched — this only stops the change from
   making the existing defect more visible than it already is. */
.wp-block-button.is-style-pfg-cta > .wp-block-button__link:focus-visible {
	border-radius: 999px;
}

/* =========================================================================
   Utility cluster: search + settings
   ========================================================================= */

.pfg-util {
	margin-left: auto;
	display: flex;
	align-items: center;
	gap: 10px;
	flex: 0 0 auto;
}

/* Search is a circle that grows into a field on focus. No script: the whole
   expansion is :focus-within, and the form submits normally either way. */
.pfg-search {
	flex: 0 0 auto;
	margin: 0;
}

.pfg-search .wp-block-search__inside-wrapper {
	box-sizing: border-box;
	position: relative;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 1px solid var(--border-2);
	border-radius: 999px;
	background: var(--wp--preset--color--surface-header-btn, #151823);
	overflow: hidden;
	transition: width 240ms cubic-bezier(0.16, 1, 0.3, 1);
}

.pfg-search:hover .wp-block-search__inside-wrapper,
.pfg-search .wp-block-search__inside-wrapper:focus-within {
	width: min(280px, 42vw);
}

.pfg-search .wp-block-search__input {
	height: 42px;
	min-width: 0;
	padding: 0 44px 0 16px;
	border: 0;
	background: transparent;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--ui-sm, 15px);
}

.pfg-search .wp-block-search__input::placeholder {
	color: var(--wp--preset--color--text-4, #838A9D);
}

.pfg-search .wp-block-search__input:focus {
	outline: none;
	box-shadow: none;
}

.pfg-search .wp-block-search__inside-wrapper:focus-within {
	box-shadow: var(--focus-ring);
}

.pfg-search .wp-block-search__button {
	position: absolute;
	top: 0;
	right: 0;
	width: 42px;
	height: 42px;
	margin: 0;
	padding: 0;
	display: grid;
	place-items: center;
	border: 0;
	border-radius: 999px;
	background: transparent;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	cursor: pointer;
}

.pfg-search .wp-block-search__button svg {
	width: 18px;
	height: 18px;
	fill: currentColor;
}

.pfg-settings {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	gap: 10px;
	height: 46px;
	padding: 0 15px;
	border-radius: var(--wp--custom--radius--md, 14px);
	border: 1px solid var(--border-2);
	background: var(--wp--preset--color--surface-header-btn, #151823);
	color: var(--wp--preset--color--text-1, #F2F3F8);
	font-size: var(--wp--preset--font-size--ui, clamp(14px, 0.81vw, 17px));
	text-decoration: none;
	white-space: nowrap;
	flex: 0 0 auto;
}

.pfg-settings:hover {
	color: var(--wp--preset--color--text-1, #F2F3F8);
	border-color: var(--border-strong);
}

.pfg-settings svg {
	color: var(--wp--preset--color--text-3, #979CAD);
	flex: 0 0 17px;
}

/* =========================================================================
   No-JS mobile menu: a checkbox styled as the burger, read through :has()
   ========================================================================= */

.pfg-burger {
	display: none;
	order: 10;
	flex: 0 0 42px;
	width: 42px;
	height: 42px;
	margin: 0;
	padding: 0;
	border: 1px solid var(--border-2);
	border-radius: 999px;
	background-color: var(--wp--preset--color--surface-header-btn, #151823);
	background-repeat: no-repeat;
	background-position: center;
	background-size: 17px 17px;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F2F3F8' stroke-width='1.8' stroke-linecap='round'%3E%3Cpath d='M4 6h16M4 12h16M4 18h16'/%3E%3C/svg%3E");
	-webkit-appearance: none;
	appearance: none;
	cursor: pointer;
}

.pfg-burger:checked {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F2F3F8' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M18 6L6 18M6 6l12 12'/%3E%3C/svg%3E");
	border-color: var(--acc-border);
}

.pfg-navscrim {
	display: none;
}

/* =========================================================================
   Secondary navigation: its own sticky rail under the header
   ========================================================================= */

/* The site-blocks flow gap would leave a 26px hole between the header and the
   rail, which the sticky offset then paints over. The chrome owns its own
   spacing through padding. */
.pfg-header,
.pfg-subnav-bar,
.pfg-main,
.pfg-footer,
footer:has(> .pfg-footer__inner) {
	margin-block-start: 0;
}

/* --pfg-subnav-h, published for the same reason --hdr-h and --pfg-tabbar-h
   are: this bar sticks BENEATH the header, so anything clearing the top of
   the viewport has to clear both. `scroll-padding-top` in base.css is the
   reader. Measured at 53px from 320px to 1600px — it does not wrap, which is
   why one constant is honest here where the cookie bar needs a ladder. */
:root:has(.pfg-subnav-bar) {
	--pfg-subnav-h: 53px;
}

.pfg-subnav-bar {
	position: sticky;
	top: var(--hdr-h, 73px);
	z-index: 49;
	background: var(--wp--preset--color--bg-page, #101219);
	border-bottom: 1px solid var(--border-1);
	padding: 0 max(var(--gutter), 50% - 880px);
}

.pfg-subnav__list {
	display: flex;
	margin: 0;
	padding: 0;
	list-style: none;
	gap: clamp(14px, 1.9vw, 32px);
	height: 52px;
	align-items: stretch;
	flex-wrap: nowrap;
	overflow-x: auto;
	overscroll-behavior-inline: contain;
	scrollbar-width: none;
	-webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 30px), transparent);
	mask-image: linear-gradient(90deg, #000 calc(100% - 30px), transparent);
}

.pfg-subnav__list::-webkit-scrollbar {
	display: none;
}

.pfg-subnav__item {
	flex: 0 0 auto;
}

.pfg-subnav__link {
	position: relative;
	display: inline-flex;
	align-items: center;
	height: 52px;
	padding: 0 2px;
	font-weight: 600;
	white-space: nowrap;
	color: var(--wp--preset--color--text-3, #979CAD);
	transition: color 150ms ease;
}

.pfg-subnav__link::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 2px;
	border-radius: 2px 2px 0 0;
	background: transparent;
	transition: background 150ms ease;
}

.pfg-subnav__link:hover {
	color: var(--wp--preset--color--text-1, #F2F3F8);
}

.pfg-subnav__link.is-section {
	color: var(--wp--preset--color--text-2, #C7CBD9);
}

.pfg-subnav__link.is-section::after {
	height: 1px;
	background: rgba(var(--acc-rgb), 0.45);
}

.pfg-subnav__link[aria-current="page"] {
	color: var(--wp--preset--color--text-1, #F2F3F8);
	font-weight: 700;
}

.pfg-subnav__link[aria-current="page"]::after {
	background: var(--acc);
}

/* =========================================================================
   Hero
   ========================================================================= */

.pfg-hero {
	position: relative;
	z-index: 1;
	padding-bottom: clamp(6px, 1vw, 12px);
}

/* The hatch canvas is the hero's first child and the head its second, so
   core's flow rule hands the head a spacing-30 margin the design never asked
   for: the hatch is a backdrop, not a row. The front page's panel hero is
   excluded — its head is pushed to the bottom of a flex column on purpose
   (base.css, .pfg-hero--panel). */
.pfg-hero:not(.pfg-hero--panel) > .pfg-hero__head {
	margin-block-start: 0;
}

.pfg-hero__title {
	position: relative;
	z-index: 1;
	display: flex;
	flex-direction: column;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(32px, 4.2vw, 58px);
	font-weight: 500;
	letter-spacing: -0.025em;
	line-height: 1.04;
	text-wrap: balance;
}

/* The wrapper carries core's is-layout-flow classes, whose global rule gives
   every child after the first a margin-block-start of spacing-30. The ticker
   line is that second child; the only gap wanted between the headline and the
   firm name is line-height, so the flow margin is zeroed for the whole stack. */
.pfg-hero__title > * {
	margin-block-start: 0;
}

/*
 * Pinned on the CLASS, not the element. The lead is an <h1> when the hero owns
 * the page's heading and a <p> when it does not (data#409), and a phrase must
 * not change size or position because of which tag it happens to wear. The
 * wrapper already supplies font, size, weight, letter-spacing and line-height;
 * this is the one property that came from the element.
 */
.pfg-hero__lead {
	margin: 0;

	/*
	 * TYPE ON THE CLASS, so a heading tag looks exactly like the paragraph
	 * (owner, 2026-09-17: the element is now the editor's choice). theme.json's
	 * element rules for h1-h4 match on the tag and would otherwise override the
	 * wrapper's inherited size and weight the moment the tag changes.
	 */
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	line-height: inherit;
	letter-spacing: inherit;
	text-transform: inherit;

	/*
	 * COLOUR ON THE CLASS TOO, for the same reason the margin is. It used to
	 * come from the `h1` rule below, which stopped matching the day the lead
	 * became a <p> — so the phrase would have quietly inherited the body
	 * colour instead of the heading one. The element changed; the design did
	 * not.
	 */
	color: var(--wp--preset--color--text-1, #F2F3F8);
}

/*
 * WITH NO ROTATING WORDS, THE LINE TAKES THE ACCENT (owner, 2026-09-15).
 *
 * The hero is two lines: a static phrase in text-1 and the rotating words in
 * `--acc`, the accent that follows the active vertical. Where an editor types
 * no words there is no second line, and a lone white phrase loses the colour
 * the hero is built around — so the phrase itself becomes the accent.
 *
 * Keyed on the ABSENCE of the ticker, not on an attribute: the block already
 * renders no `.pfg-hero__ticker` at all when the word list is empty, so the
 * DOM states the condition and nothing needs to be kept in step. `:has()` is
 * the house pattern here (review-tabs, toplist, nav).
 */
.pfg-hero__title:not(:has(.pfg-hero__ticker)) .pfg-hero__lead {
	color: var(--acc);
}

.pfg-hero__title h1,
.pfg-hero h1 {
	margin: 0;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	letter-spacing: inherit;
	line-height: inherit;
	color: var(--wp--preset--color--text-1, #F2F3F8);
}

/* The rotating firm-name line. Lane B's propfirmgrade/grade-ticker drops in
   here; until it does the slot carries the static fallback word, which is
   also what the ticker renders with scripting off. */
.pfg-hero__ticker {
	color: var(--acc);
	line-height: 1.3;
	min-height: 1.3em;
}

.pfg-hero__ticker p,
.pfg-hero__ticker > * {
	margin: 0;
	font-family: inherit;
	font-size: inherit;
	font-weight: inherit;
	letter-spacing: inherit;
	line-height: inherit;
	color: inherit;
}

.pfg-hero__sub {
	position: relative;
	z-index: 1;
	max-width: var(--wp--custom--layout--reading-max, 62ch);
	margin: 0;
	font-size: clamp(14px, 1.3vw, 17px);
	line-height: 1.65;
	color: var(--wp--preset--color--text-body, #A6ACC0);
}

.pfg-hero__stats {
	position: relative;
	z-index: 1;
	display: flex;
	gap: clamp(18px, 2.5vw, 40px);
	flex-wrap: wrap;
}

.pfg-stat {
	display: flex;
	flex-direction: column;
	gap: 3px;
}

.pfg-stat__n {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(22px, 2.2vw, 31px);
	line-height: 1;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	font-variant-numeric: tabular-nums;
	margin: 0;
}

.pfg-stat__l {
	font-size: 10.5px;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--text-label, #828BA6);
	margin: 0;
}

/*
 * "Firms on record · 15 reviewed" (#343). Each part holds together, so a
 * narrow row breaks at the middle dot and never inside "15 reviewed".
 */
.pfg-stat__part {
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
}

/* =========================================================================
   Coupon motif + featured deal card
   ========================================================================= */

.pfg-featured {
	/*
	 * BORDER-BOX, or this card is wider than every other block on the page.
	 *
	 * WordPress sets `box-sizing: border-box` on `.wp-block-group`, so every
	 * panel that happens to be a group inherits it. This is a custom block
	 * wrapper, not a group, so it kept the browser default — and with
	 * `max-width: 1760px` from the constrained layout applying to its CONTENT,
	 * its padding and border were added on top: 1760 + 2 x 33 = 1826, sticking
	 * out 33px each side of everything above and below it.
	 *
	 * Invisible below ~1828px viewport, where the container never reaches its
	 * max-width and the overflow has nowhere to happen. `review-offer-bar`
	 * carries the same fix for the same reason.
	 */
	box-sizing: border-box;
	background: var(--hero-grad);
	border: 1px solid rgba(255, 255, 255, 0.07);
	border-radius: var(--wp--custom--radius--hero, 22px);
	padding: var(--wp--preset--spacing--50);
}

/* SCOPED to .pfg-featured: this is the featured-deal card's own coupon
   anatomy (flex pill + .pfg-coupon__cta). The plugin's shared coupon
   component (assets/css/coupon.css — grid pill + .pfg-coupon__btn) uses the
   same block class, and an unscoped rule here silently rewrote its layout
   inside toplist rows. */
.pfg-featured .pfg-coupon {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	border: 1.5px dashed rgba(var(--acc-rgb), 0.5);
	border-radius: 999px;
	padding: 5px 5px 5px 18px;
	max-width: 380px;
}

.pfg-featured .pfg-coupon__code {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--ui-sm, 15px);
	font-weight: 800;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	white-space: nowrap;
}

/* .pfg-coupon__cta is the plugin's (assets/css/coupon.css). The theme used
   to restate it here for the old static featured-deal pattern — unscoped, and
   with a `:hover` selector whose specificity outranked the plugin's base rule
   only while hovered, so every coupon CTA on the site snapped from 46px to
   40px under the pointer and back on leave. The pattern is gone; the rule is
   gone with it. Hover is the pill's own filter, as coupon.css says. */

.pfg-chip {
	display: inline-flex;
	align-items: center;
	height: 24px;
	padding: 0 9px;
	border-radius: 8px;
	background: var(--wp--preset--color--surface-chip, #262C3B);
	color: var(--wp--preset--color--text-2, #C6CBDD);
	font-size: 12.5px;
	font-weight: 600;
	white-space: nowrap;
}

/* =========================================================================
   Section panels
   ========================================================================= */

.pfg-panel {
	background: var(--wp--preset--color--surface-1, #14171E);
	border: 1px solid rgba(255, 255, 255, 0.055);
	border-radius: 24px;
	padding: 18px;
}

.pfg-panel__head {
	display: flex;
	align-items: center;
	gap: 10px 14px;
	flex-wrap: wrap;
	padding: 2px 6px 16px;
}

.pfg-panel__head h2 {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--h-4, 18px);
	font-weight: 700;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	margin: 0;
	letter-spacing: 0;
}

.pfg-panel__meta {
	font-size: var(--wp--preset--font-size--small, 14px);
	color: var(--wp--preset--color--text-3, #979CAD);
}

.pfg-panel__link {
	margin-left: auto;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	height: 38px;
	padding: 0 15px;
	border-radius: 11px;
	border: 1px solid rgba(255, 255, 255, 0.12);
	color: var(--wp--preset--color--text-1, #F2F3F8);
	font-size: clamp(13px, 0.75vw, 15.5px);
	font-weight: 700;
	text-decoration: none;
	white-space: nowrap;
}

.pfg-panel__link:hover {
	border-color: rgba(255, 255, 255, 0.3);
	color: var(--wp--preset--color--text-1, #F2F3F8);
}

/* -------------------------------------------------------------------------
   Front-page editorial body

   post_content, rendered between the ranking and the trust strip. Same problem
   as the hub intro below: <main> is 1760px so the toplist keeps its width, and
   prose at 1760px is unreadable.

   CENTRED, changed 2026-08-18 by the owner. It was capped with a left margin of
   zero so paragraphs lined up with the headings above them rather than sitting
   "centred 290px to their right" — that was this block's original reasoning and
   it is reversed here deliberately, not by accident.

   What changed the answer is the width of what sits above. The ranking is now
   full-bleed to 1760px, so a 62ch column pinned to its left edge does not read
   as aligned with anything: it reads as a narrow column abandoned on one side
   of a very wide page, with roughly 1100px of empty dark to its right. Every
   other prose page on the site — /about/, /contact/, the legal pages, all of
   them page.html — centres the same column, so the front page was the only
   place the treatment differed.

   The trade is real and it is the one the old comment named: the first line of
   prose no longer starts at the same x as the section heading above it.

   Headings are styled here because this is the one block on the page whose
   contents nobody controls — a content manager will add h2s and lists, and
   they should look like the rest of the site without anyone editing CSS.
   ------------------------------------------------------------------------- */

.pfg-home-copy {
	margin-top: clamp(28px, 3vw, 48px);
	/* ONE COLUMN, COMPUTED ONCE, exactly as .pfg-hub-body does it. The
	   registered <length> (@property further down) resolves 75ch HERE,
	   against this wrapper's body font, and inherits as one pixel value; the
	   inset below centres that one column rather than each box on its own
	   width. See the next rule for what capping at a raw 75ch per block did. */
	--pfg-document-col: var(--wp--custom--layout--document-max, 75ch);
	--pfg-col-margin: calc((100% - min(var(--pfg-document-col), 100%)) / 2);
}

.pfg-home-copy > .wp-block-post-content > * {
	/* The DOCUMENT measure (owner decision 2026-08-24, second ruling): the
	   copy section is long-form prose and reads at the same 75ch column as
	   every page.html document. Only standfirsts beside product UI (the
	   hero sub, section ledes, the teaser sub) stay at the narrower
	   reading measure. */
	/* CAPPED PER BLOCK, NOT ON THE WRAPPER (propfirmgrade-data#535, 2026-09-17).
	   This capped `.pfg-home-copy > *`, and the one direct child is the
	   post-content wrapper itself, so EVERYTHING an editor put in page 55 was
	   held to 75ch with no way out: the homepage teaser, pasted into content
	   so its heading could be edited, came out narrow and the paste was
	   reverted. The hubs already cap each block and exempt the ones that
	   hold a table or a toplist ("WIDTH FOLLOWS CONTENT, NOT CLASS NAME",
	   further down); the front page now does exactly the same. Prose reads
	   at the same measure as before, one block at a time. */
	/* ONE LEFT EDGE, NOT ONE PER BLOCK (2026-09-17, the same day). The cap
	   above was first written as a raw `75ch` with `margin-inline: auto`,
	   and `ch` resolves against each element's OWN font size: at 2000px the
	   30px h2 got a 1476px box starting at x=262, the 21px h3s a 1081px box
	   at x=460, the firm-summary card 826px at x=587, and the 17px paragraphs
	   778px at x=611. Four left edges in one section. The column now comes
	   from the wrapper (above) and the inset is the hubs' explicit one, so
	   every capped block starts on one edge. That column is 75ch of the
	   wrapper's body font, which is the width the old wrapper cap gave
	   (663px at 1440, 768px at 2000) and the width the hub bodies read at;
	   the per-block cap had quietly widened paragraphs past it (692px at
	   1440, 778px at 2000), so "the same measure as before" above is true
	   again rather than approximately. The firm-summary
	   card sits IN that column, as it does in a hub body: it holds no table
	   or toplist, so the escape hatch below does not take it. */
	max-width: var(--pfg-document-col);
	margin-inline: var(--pfg-col-margin);
}

/* The same escape hatch the hubs have, for the same reason: a block that holds
   a toplist or a table earns the container; prose in a panel does not, and an
   author can still say so with alignwide or alignfull. `pfg-toplist` is the
   block's own row classes, present in every render of it. */
.pfg-home-copy > .wp-block-post-content > .alignwide,
.pfg-home-copy > .wp-block-post-content > .alignfull,
.pfg-home-copy > .wp-block-post-content > table,
.pfg-home-copy > .wp-block-post-content > [class*="pfg-toplist"],
.pfg-home-copy > .wp-block-post-content > :has(table),
.pfg-home-copy > .wp-block-post-content > :has([class*="pfg-toplist"]) {
	max-width: none;
	margin-inline: 0;
}

/* WHEN THE TEASER OPENS THE CONTENT IT TAKES THE PATTERN'S SLOT. The copy
   group's top margin was the gap between the pattern's teaser and the first
   paragraph. With the teaser inside the content that gap belongs AFTER the
   teaser, not above it, or the teaser sits 28 to 48px lower than the pattern
   drew it. Measured against the pattern render before this rule existed. */
.pfg-home-copy:has(> .wp-block-post-content > .pfg-teaser:first-child) {
	/* The block gap, not 0: the pattern's teaser sat one layout gap under the
	   hero (26px, main's constrained-layout gap). Zero put the pasted teaser
	   26px higher than the pattern drew it; measured at 1440 and 375. */
	margin-top: var(--wp--style--block-gap, 26px);
}
.pfg-home-copy > .wp-block-post-content > .pfg-teaser:first-child + * {
	margin-top: clamp(28px, 3vw, 48px);
}

/* The same ramp serves page.html's post content (top level only, so a
   paragraph nested inside a product block keeps that block's type): plain
   pages are edited in the same canvas, and editor.css already previews
   this ramp at the content root for both. */
/* PROSE ONLY IN THE HUB BODY, not headings. A hub body paragraph is new — the
   hubs had no body prose at all before 2026-08-26 — so giving it the shared
   prose ramp adds a treatment rather than changing one. Its HEADINGS are not
   new: the section heading moved out of the template into the content, and
   theme.json's h2 element style plus the 26px section gap is exactly what it
   had there. The document heading rhythm (28-42px over, 12px under) is
   page.html's, and applying it here would re-space markup that only changed
   owner. */
.pfg-home-copy .wp-block-post-content > p,
.pfg-home-copy .wp-block-post-content > ul li,
.pfg-home-copy .wp-block-post-content > ol li,
.pfg-page-body .wp-block-post-content > p,
.pfg-page-body .wp-block-post-content > ul li,
.pfg-page-body .wp-block-post-content > ol li,
.pfg-hub-body .wp-block-post-content > p,
.pfg-hub-body .wp-block-post-content > ul li,
.pfg-hub-body .wp-block-post-content > ol li {
	font-size: clamp(15px, 1.05vw, 17px);
	line-height: 1.7;
	color: var(--wp--preset--color--text-body, #A6ACC0);
}

/* A LINK IN PROSE IS UNDERLINED, because colour alone is not a distinction.
   
   axe-core, 2026-08-28, six nodes across three templates: an in-prose link is
   accent yellow #E6FF00 on body text #A6ACC0 — 2.01:1 where WCAG 1.4.1 Use of
   Color requires 3:1 between link and surrounding text when colour is the only
   cue. A reader who cannot separate those two hues cannot find the link at all.

   THE UNDERLINE IS THE FIX RATHER THAN A DARKER ACCENT. Raising the link's
   contrast against the prose would mean inventing a second accent, and the
   design rules put the accent family on the price, the grade seal, the CTA, the
   coupon pill, the active pill and a market dot — not on a fourth colour
   invented to satisfy a ratio. An underline adds no colour and settles it.

   SCOPED TO PROSE ONLY. Chrome links — nav, footer, cards, rows — are
   distinguished by position, box and hover already, and underlining them would
   be a design change nobody asked for. This selector is the same reading-column
   set as the rule above it, so the two cannot drift apart. */
.pfg-home-copy .wp-block-post-content > p a,
.pfg-home-copy .wp-block-post-content > ul li a,
.pfg-home-copy .wp-block-post-content > ol li a,
.pfg-page-body .wp-block-post-content > p a,
.pfg-page-body .wp-block-post-content > ul li a,
.pfg-page-body .wp-block-post-content > ol li a,
.pfg-hub-body .wp-block-post-content > p a,
.pfg-hub-body .wp-block-post-content > ul li a,
.pfg-hub-body .wp-block-post-content > ol li a,
/* The right-of-reply disclosure is prose a reader is meant to act on — it
   carries the corrections@ address — and it sits in the review template rather
   than in post content, so the reading-column selectors above miss it. Found
   by re-running axe after the first fix instead of assuming three templates
   covered every prose surface. */
.pfg-disclosure a {
	text-decoration: underline;
	text-underline-offset: 2px;
	text-decoration-thickness: 1px;
}

.pfg-home-copy .wp-block-post-content > h2,
.pfg-page-body .wp-block-post-content > h2 {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(22px, 2vw, 30px);
	line-height: 1.2;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	/* Block axis only: the inline axis belongs to the column centring
	   (auto margins from the reading-column rules further down). */
	margin-block: clamp(28px, 2.6vw, 42px) 12px;
}

.pfg-home-copy .wp-block-post-content > h3,
.pfg-page-body .wp-block-post-content > h3 {
	font-size: clamp(17px, 1.3vw, 21px);
	color: var(--wp--preset--color--text-1, #F2F3F8);
	margin-block: clamp(20px, 2vw, 30px) 8px;
}

.pfg-home-copy .wp-block-post-content > p a,
.pfg-home-copy .wp-block-post-content > ul a,
.pfg-home-copy .wp-block-post-content > ol a,
.pfg-page-body .wp-block-post-content > p a,
.pfg-page-body .wp-block-post-content > ul a,
.pfg-page-body .wp-block-post-content > ol a,
.pfg-hub-body .wp-block-post-content > p a,
.pfg-hub-body .wp-block-post-content > ul a,
.pfg-hub-body .wp-block-post-content > ol a {
	color: var(--acc, #a79fff);
}

/* -------------------------------------------------------------------------
   Plain-page editorial tables

   Commissioned text pages now carry core/table blocks (the data repo's
   authoring guide), and core's blocks/table/style.css enqueues after theme
   styles with the full-grid look: `td { border: 1px solid; padding: .5em;
   vertical-align: middle }` and a 3px rule on the THEAD element. The house
   table idiom (design CSS 142–146, same language as the review article and
   the challenge-table block) is hairline ROW separators only, no vertical
   cell borders, no outer grid box, small uppercase muted thead labels,
   tabular numerals, top alignment.

   The three-class compound is load-bearing: it outweighs core's (0,1,1)
   cell rules so the cascade does not depend on enqueue order.

   TWO SCOPES ON PURPOSE. `.pfg-page-body` is page.html. `.pfg-rv-article`
   is here because page-methodology.html reuses the article wrapper WITHOUT
   any review block on the page, so the plugin's copy of this idiom (in the
   review-context block, plugin lane) never enqueues there — its weights
   table rendered the core grid. On a firm review both copies apply with
   identical declarations, and the theme's higher (0,3,1) wins ties
   deterministically. Keep the two copies in step.
   ------------------------------------------------------------------------- */

.pfg-page-body .wp-block-post-content .wp-block-table,
.pfg-rv-article .wp-block-post-content .wp-block-table {
	overflow-x: auto;
	max-width: 100%;
}

.pfg-page-body .wp-block-post-content .wp-block-table table,
.pfg-rv-article .wp-block-post-content .wp-block-table table {
	width: 100%;
	border-collapse: collapse;
	font-size: clamp(13px, 0.78vw, 15px);
	line-height: 1.55;
	color: var(--wp--preset--color--text-2, #C6CBDD);
}

.pfg-page-body .wp-block-post-content .wp-block-table td,
.pfg-page-body .wp-block-post-content .wp-block-table th,
.pfg-rv-article .wp-block-post-content .wp-block-table td,
.pfg-rv-article .wp-block-post-content .wp-block-table th {
	overflow-wrap: anywhere;
	border: 0;
	border-bottom: 1px solid rgba(255, 255, 255, 0.07);
	padding: 11px 14px;
	text-align: left;
	vertical-align: top;
}

.pfg-page-body .wp-block-post-content .wp-block-table td,
.pfg-rv-article .wp-block-post-content .wp-block-table td {
	font-variant-numeric: tabular-nums;
}

.pfg-page-body .wp-block-post-content .wp-block-table thead,
.pfg-rv-article .wp-block-post-content .wp-block-table thead {
	border-bottom: 0;
}

.pfg-page-body .wp-block-post-content .wp-block-table thead th,
.pfg-rv-article .wp-block-post-content .wp-block-table thead th {
	/* Labels never break mid-word; the figure's overflow guard covers the
	   pathological case. Body cells keep `anywhere`. */
	overflow-wrap: normal;
	border-bottom: 1px solid rgba(255, 255, 255, 0.10);
	font-size: clamp(10.5px, 0.6vw, 12.5px);
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	/* #9AA1B5 was a fallback for a token that never resolved, so the palette
	   moved to #828BA6 and this did not follow. Named properly, it tracks. */
	color: var(--wp--preset--color--text-label, #828BA6);
}

.pfg-page-body .wp-block-post-content .wp-block-table figcaption,
.pfg-rv-article .wp-block-post-content .wp-block-table figcaption {
	margin-top: 9px;
	font-size: clamp(11.5px, 0.66vw, 13px);
	color: var(--wp--preset--color--text-3, #979CAD);
	text-align: left;
}

@media (max-width: 699px) {
	.pfg-page-body .wp-block-post-content .wp-block-table td,
	.pfg-page-body .wp-block-post-content .wp-block-table th,
	.pfg-rv-article .wp-block-post-content .wp-block-table td,
	.pfg-rv-article .wp-block-post-content .wp-block-table th {
		padding: 9px 10px;
	}
}

/* The methodology weights table (theme pattern methodology-weights.php):
   the weight column carries the accent, per the design's grade tooltip. */
.pfg-method-table.pfg-method-table td:nth-child(2) {
	font-variant-numeric: tabular-nums;
	font-weight: 800;
	color: var(--acc, var(--wp--preset--color--accent, #A79FFF));
	white-space: nowrap;
}

/* -------------------------------------------------------------------------
   Hub intro prose

   The hub's <main> is 1760px so the toplist panel renders at the same width it
   does on the home page — clicking a pill should not resize the table. Prose at
   1760px is unreadable, so the intro caps itself.

   It caps with max-width and a LEFT margin of zero, not with a constrained
   layout: constrained centres, which parked the intro ~290px right of the H1
   directly above it. Same treatment as .pfg-hero__sub, which solved this first.

   The intro is `wp:post-excerpt` since 2026-08-26, not `wp:post-content` — the
   move that freed post content to be the hub's editable body. The selector is
   unchanged because both render a <p> inside this wrapper; `margin-block: 0`
   is new, because a flow LAYOUT container zeroed the first and last child's
   block margins for free and the excerpt wrapper is not one, so the UA's
   `1em` would otherwise reappear above and below the standfirst.
   ------------------------------------------------------------------------- */

/* No written excerpt means no standfirst at all (Blocks::require_written_
   standfirst), which leaves this wrapper in the markup with nothing in it.
   The hero group carries a blockGap, so an empty div is not free — it spends
   one gap between the H1 and whatever follows. Collapse it. */
.pfg-hub-intro:empty {
	display: none;
}

.pfg-hub-intro p {
	/* Document measure, owner decision 2026-08-24 — the hub intro is
	   long-form prose, same column as the home copy and page.html. */
	max-width: var(--wp--custom--layout--document-max, 75ch);
	margin-block: 0;
	margin-left: 0;
	margin-right: 0;
}

/* -------------------------------------------------------------------------
   Hub body — the page's own content, below the hero

   Same document column as .pfg-page-body, and for the same reason: the hub's
   <main> is 1760px so the toplist panel keeps the width it has on the home
   page, and prose at 1760px is unreadable. It is a SEPARATE rule rather than
   a second class on .pfg-page-body because of the alignment: page.html is a
   centred document, and its column centres. A hub is not — the H1 sits at the
   left edge of the hero above, so a centred 660px column beneath it would
   park the prose ~290px right of the heading it belongs to. That is the exact
   defect .pfg-hub-intro was written to solve, so the body solves it the same
   way: cap, and pin the left margin.

   Product blocks and panels are exempt. A firm list is a panel, not prose,
   and the design never shows one at reading width — so the toplist section
   (a .pfg-panel group holding the filter bar and the toplist block) keeps the
   full container, as does anything of ours and anything an editor
   deliberately sets alignwide/alignfull.
   ------------------------------------------------------------------------- */

.pfg-hub-body {
	/* Registered <length> (see @property below the plain-page column): it
	   computes once here against this wrapper's body font and inherits down
	   as one pixel value, so a 30px h2 shares the left edge with the
	   paragraphs rather than getting a ~1300px box of its own. */
	--pfg-document-col: var(--wp--custom--layout--document-max, 75ch);

	/* WHERE THE READING COLUMN SITS, and the whole of the flip: `0` pins the
	   column to the left gutter, `calc((100% - min(var(--pfg-document-col),
	   100%)) / 2)` centres it on the container. One declaration, because six
	   of the seven flips were hand-edits in more than one place, and two
	   places that must agree are two places that can disagree.

	   The centring value is an explicit inset rather than `margin-inline:
	   auto` because `auto` centres each box on its own width, and these boxes
	   are not all the same width: a 62ch standfirst and a 75ch heading centred
	   on one container start 46px apart. Insetting by the container's leftover
	   space puts every box on one left edge whatever its own measure is.
	   `min(…, 100%)` keeps mobile honest — once the container is narrower than
	   the column the leftover is zero, so the gutters stay symmetric instead
	   of going negative. Both values are correct; only the choice changed.

	   Since the rail landed, this token means something narrower than it used
	   to. Percentage margins resolve against the CONTAINING BLOCK, and for a
	   child of the article column that is the grid area, not the container. So
	   centring now centres each box in the column it actually sits in: prose
	   inside the 1088px article area, and the furniture above the rail inside
	   the full 1372px container. Nothing had to be taught that; it falls out of
	   the formula. */
	--pfg-col-margin: calc((100% - min(var(--pfg-document-col), 100%)) / 2);
}

.pfg-hub-body > .wp-block-post-content > * {
	max-width: var(--pfg-document-col);
	/* CENTRED, as of flip eight, 2026-08-27. The history below is in order and
	   worth reading before touching the token above: the answer has changed
	   whenever the page changed, and three times it changed back.

	   Centring failed the first time because the body held SEVERAL full-width
	   blocks: the toplist, a text callout, the grade distribution. A centred
	   660px column among three full-bleed neighbours reads as two competing
	   grids, so left-capping was correct while that was true.

	   It stopped being true when width started following content (see the
	   exemption block below): the callout and the chart now sit at the measure,
	   leaving the toplist as the only full-bleed element. One deliberate
	   full-bleed element beneath a centred column is an ordinary editorial
	   layout — and both share an axis, the heading centring on 799.5 where the
	   panel centres on 800.

	   That premise is DEAD, and the flip-six note below is what killed it. The
	   columns exemption made the explainer strip full-bleed too, so the count
	   is two, not one. Measured rather than counted: the toplist paints
	   background and border across 34..1406, and the strip paints three
	   hairlines across 34..1406. Do not reuse the paragraph above as an
	   argument for centring without recounting first.

	   LEFT AGAIN, 2026-08-26, and this time for a reason none of the previous
	   four flips weighed. Every argument above compares the body to the TOPLIST
	   below it. None of them looked UP. The hero's market label, H1 and
	   standfirst are all flush to the main container's padding edge, so a
	   centred body column starts roughly 300px to the right of the H1 that
	   introduces it — two left edges on one page, which is what the content
	   lead reported ("overall text is not aligned", /forex/).

	   docs/design/screens/design/design-1440.png settles it rather than another
	   opinion doing so: the design puts the H1, the standfirst, the counted
	   stats, the filter row and the toplist panel all on ONE left gutter, and
	   shows no centred column anywhere. The body joins that gutter.

	   CENTRED AGAIN, 2026-08-27, flip six, on the owner's instruction after
	   looking at the left-aligned page. Everything above stayed true of the
	   page it was written about; what changed is the page.

	   That morning the columns exemption below shipped, and the futures body
	   stopped being a single left column with one full-bleed panel under it.
	   The explainer strip now spans the container too. Left-capping had been
	   holding a 663px column of prose against 1372px of neighbours on both
	   sides of it, and the owner's reading of that was "content paragraphs and
	   headings under not centered" — the same words the previous flip was
	   made to avoid, pointing the opposite way.

	   Recording the trade rather than pretending there isn't one. Centring
	   RE-CREATES the defect the 2026-08-26 note describes: the hero's label,
	   H1 and standfirst stay flush to the container's padding edge, so the
	   body column now starts 354px right of the H1 that introduces it, and
	   design-1440.png still shows one left gutter and no centred column. That
	   cost was put to the owner and accepted.

	   LEFT AGAIN, 2026-08-27, flip seven, same day, after the owner looked at
	   flip six. Recorded in full because this pair is the most useful evidence
	   in the whole note, and it took two hours rather than five occasions.

	   Centred, the owner's reading was "it looks weird some blocks are wider
	   than paragraph". Left, that same morning, with THE SAME TWO WIDTHS on
	   the page — 663px of prose and 1372px of panel — they did not say that.
	   They said the content was not centred. So the width difference is not
	   what changed; what changed is whether it has an anchor.

	   That is the mechanism, and it is why this flip is not just another
	   opinion. Left-aligned, a wider block extends further right from the same
	   left edge as the prose: two widths, one shared edge, which reads as a
	   column with a wide figure in it. Centred, the same block overhangs by
	   354px on BOTH sides and shares no edge with anything, so the only
	   relationship left between the two widths is a centre axis, which the eye
	   does not read. Left alignment does not fix a width disagreement; it
	   gives it somewhere to start.

	   Neither flip touched the actual complaint. 1372 − 663 = 709px of empty
	   space exists identically in both: left puts all 709 on the right, centre
	   splits it 354/354. Every complaint on this property so far has been
	   about that space, which is why flipping keeps producing a new one.

	   So the answer is not on this line. DESIGN-INVENTORY.md:587-593 and :1243
	   record what the design does with that space: the editorial body is
	   `section.sk-art`, a `256px minmax(0,1fr)` grid with a sticky table of
	   contents in the left column from 1240px and a third rail column from
	   1500px. It fills the space rather than moving it. If there is ever a
	   flip eight, it should be a decision NOT to build that, taken knowingly —
	   not another turn of this one declaration.

	   CENTRED, 2026-08-27, flip eight, on the owner's instruction, and the
	   paragraph above is why it was worth asking again rather than repeating
	   flip seven's answer. The ToC got built. The prose no longer sits in a
	   1372px container with 709px of nothing beside it; it sits in a 1088px
	   article column with a 256px rail holding the space that made a centred
	   column look unanchored. That is a genuinely different page, so the
	   argument that settled flip seven had to be re-run rather than cited.

	   What centring now means, precisely: percentage margins resolve against
	   the containing block, so a child of the article column centres in the
	   COLUMN and the furniture above the rail centres in the CONTAINER. Prose
	   and the strip it sits under end up on one axis — 862 against 862 at
	   1440, where flip six could only manage a shared centre with nothing else
	   agreeing.

	   ONE COST, MEASURED, AND THE OWNER SHOULD SEE IT. Left, the rail's right
	   edge is 28px from the prose — the design's own gutter, a proper
	   two-column pair. Centred, that gap is 240px at 1440 and 397px at 1920,
	   because the prose walks right while the rail stays put. A table of
	   contents 400px from the text it indexes reads as belonging to neither
	   column. Measured by toggling this one token on a single page load, so
	   it is the same stylesheet and the same layout either way.

	   If flip nine comes, it is that gap that will cause it, and the fix is
	   not this line: it is either narrowing the article column toward the
	   measure so centring moves the prose less, or building the >=1500px rail
	   the design puts on the right, which would give the prose something to
	   centre BETWEEN instead of drifting away from its own contents list. */
	margin-inline: var(--pfg-col-margin);
}

/* A HEADING THAT LABELS A FULL-BLEED PANEL STAYS ON THAT PANEL'S EDGE.
 *
 * "Top futures prop firms" introduces the toplist directly beneath it. Capped
 * at the reading measure like every other heading, it followed the column
 * wherever the column went — which was invisible while the column was left,
 * and became the worst thing on the page the moment it was centred: at flip
 * six the label sat at x=388 above a panel starting at x=34, sharing an axis
 * with nothing. On /forex/ and /crypto/ it is worse still, because those hubs
 * have no editorial body at all, so that heading is the ONLY capped child and
 * it floats centred over a full-bleed panel with nothing else on its axis.
 * It was reported during flip six review and the fix was proposed then and
 * not taken. (An earlier version of this comment credited that report to
 * the links lane, which has since said plainly it was not theirs and did no
 * ToC or heading work. The finding stands; the name was wrong, so it is
 * removed rather than reassigned to another guess.)
 *
 * It is a rule rather than a patch: a label belongs on the edge of the thing
 * it labels. The test is what FOLLOWS the heading, not what the heading is
 * called — same grain as the width exemptions above, which ask what a block
 * holds rather than what its class says. Both forms are needed because the
 * toplist is sometimes the next sibling and sometimes wrapped in the panel
 * group with the filter bar.
 */
.pfg-hub-body > .wp-block-post-content > :is(h1, h2, h3, h4, h5, h6):has(+ [class*="pfg-toplist"]),
.pfg-hub-body > .wp-block-post-content > :is(h1, h2, h3, h4, h5, h6):has(+ * [class*="pfg-toplist"]) {
	margin-inline: 0;
}

/* WIDTH FOLLOWS CONTENT, NOT CLASS NAME.
 *
 * This exempted every `wp-block-propfirmgrade-*` and every `.pfg-panel`, which
 * is too blunt in both directions and was visibly wrong on the live futures
 * hub: `.pfg-panel` wraps the toplist (a table, genuinely wide) AND plain text
 * callouts (a heading and a paragraph, which then ran 1530px beside 660px
 * prose), while `review-grade-distribution` is a labelled bar chart that reads
 * perfectly well at the document measure and looked absurd at full width next
 * to the paragraph introducing it.
 *
 * So the test is what a block actually holds. A tabular list earns the full
 * container; prose in a panel does not. An author can still override either
 * way with alignwide/alignfull, which is the deliberate escape hatch rather
 * than a guess about block names. */
.pfg-hub-body > .wp-block-post-content > .alignwide,
.pfg-hub-body > .wp-block-post-content > .alignfull,
.pfg-hub-body > .wp-block-post-content > table,
.pfg-hub-body > .wp-block-post-content > [class*="pfg-toplist"],
.pfg-hub-body > .wp-block-post-content > :has(table),
.pfg-hub-body > .wp-block-post-content > :has([class*="pfg-toplist"]) {
	max-width: none;
	/* Taking the whole container means taking the inset back too. The column's
	   inset is a real length, not `auto`, so it does not fall away on its own
	   the way `auto` would against `max-width: none`. */
	margin-inline: 0;
}

/* Columns are the third thing that earns the container, added 2026-08-27, and
   it is the same test as the two above rather than a new one. `wp:columns` is
   a side-by-side layout an editor deliberately built: like a table, its width
   is set by how many tracks have to fit across it, not by a reading measure.
   Capped at 75ch the futures explainer ("Program fit / Rule scope / Evidence")
   divided 663px into three 198px tracks — narrower than any prose on the page,
   and the most conspicuous part of what the owner reported.

   ONLY WHILE THEY ARE COLUMNS. Core stacks `wp:columns` below 782px
   (`flex-wrap:nowrap` is scoped to `min-width:782px` in
   wp-includes/blocks/columns/style.min.css), and a stacked track is prose
   again — so it belongs at the document measure like everything else. The
   media query here is core's own breakpoint, not a number of ours.

   THIS DOES NOT WIDEN PROSE, which is what would make it a regression. Only
   the columns wrapper loses the cap; the paragraphs inside each track are
   bounded by the track, and `.pfg-home-section__lede` — the standfirst above
   the tracks — carries its own 62ch cap. Measured on /futures/ at 1440 before
   and after: top-level paragraphs 663px → 663px, lede 572px → 572px, tracks
   198px → 434px. */
@media (min-width: 782px) {
	.pfg-hub-body > .wp-block-post-content > .wp-block-columns,
	.pfg-hub-body > .wp-block-post-content > :has(.wp-block-columns) {
		max-width: none;
		margin-inline: 0;
	}

	/* A full-width wrapper is not a licence for the prose inside it.
	   `.pfg-explainer` is one block holding a heading, a standfirst and the
	   tracks; the exemption above widens the WRAPPER so the tracks can spread,
	   which also frees its own heading and standfirst from the column every
	   other heading on the page sits on.

	   Under the left policy those are the same x, so the inset half of this
	   rule is dormant and only the cap does anything. Flip six is what made it
	   visible: centring moved every other heading 354px right and left this
	   one at the container edge, one heading against the next. The rule is
	   written to hold under either policy rather than to be added and removed
	   with the token, which is how this file has been bitten before.

	   Both halves read the same inset token as a top-level child. Because the
	   wrapper is exactly as wide as the container, the token computes to the
	   same value inside it as outside, and the two land on one left edge
	   without either knowing about the other.

	   The cap is in `:where()` on purpose, so it carries no specificity and
	   anything with a tighter measure of its own keeps it. That is what holds
	   `.pfg-home-section__lede` at 62ch instead of widening it to the 75ch
	   column, and prose not widening is the hard acceptance criterion here. */
	:where(.pfg-hub-body > .wp-block-post-content > :has(> .wp-block-columns) > :not(.wp-block-columns)) {
		max-width: var(--pfg-document-col);
	}

	.pfg-hub-body > .wp-block-post-content > :has(> .wp-block-columns) > :not(.wp-block-columns) {
		margin-inline: var(--pfg-col-margin);
	}
}

/* =========================================================================
   Hub article grid — the contents rail and the column beside it

   DESIGN-INVENTORY.md:587-593. `<1240px` the article is display:block and the
   ToC is hidden; `>=1240px` it becomes `256px minmax(0,1fr)` with a 28px gap
   and `align-items:start`, and the rail sticks below the header. The `>=1500px`
   third column is NOT built: the design fills it with stat cards this hub
   already spends in its hero and an offers aside that is a product decision,
   so an empty rail would be worse than two columns. Stated deviation, owner
   approved 2026-08-27, not an oversight.

   WHY THE GRID IS ON POST CONTENT RATHER THAN A WRAPPER. The design's
   `section.sk-art` is a sibling BELOW the dashboard, so it can be a tidy
   two-item grid of nav + article. Our hub has no such boundary: the toplist
   lives inside post content along with the prose, and wrapping the lot would
   take 284px off it (1372 to 1088 at 1440), which is the product's centrepiece
   and the reason that option was rejected. So post content itself becomes the
   grid, with named lines: everything keeps the FULL container by default, and
   only the siblings after the rail move into the article column. The toplist
   is untouched because it never leaves `full`.

   ALL OF IT IS GUARDED ON `:has(> .pfg-hub-toc)`. No rail, no grid, no
   column — /forex/ and /crypto/ carry no editorial body and no block, so they
   render exactly as they did before this existed, and a hub whose ToC declined
   to render (fewer than three headings) falls back to plain flow rather than
   opening an empty 256px column.
   ========================================================================= */

@media (min-width: 1240px) {

	.pfg-hub-body > .wp-block-post-content:has(> .pfg-hub-toc) {
		display: grid;
		grid-template-columns: [full-start] 256px [col-start] minmax(0, 1fr) [col-end full-end];
		column-gap: 28px;
		/* Zero, because the vertical rhythm is already there: core's flow
		   layout puts `margin-block-start` on every child and those margins
		   still apply to grid items. A row-gap would add a second gap on top
		   of every one of them. */
		row-gap: 0;
		align-items: start;
	}

	/* Default is the full container — the page as it was. Only what follows
	   the rail becomes a column, which is what makes this safe for the
	   toplist above it. */
	.pfg-hub-body > .wp-block-post-content:has(> .pfg-hub-toc) > * {
		grid-column: full;
	}

	.pfg-hub-body > .wp-block-post-content:has(> .pfg-hub-toc) > .pfg-hub-toc ~ * {
		grid-column: col;
	}

	.pfg-hub-body > .wp-block-post-content:has(> .pfg-hub-toc) > .pfg-hub-toc {
		grid-column: full-start / col-start;
		display: block;
		position: sticky;
		/* Clears the sticky header AND the sticky subnav below it, which the
		   design's export folds into one header of `--hdr-h`. */
		top: calc(var(--hdr-h, 73px) + 68px);
		max-height: calc(100dvh - var(--hdr-h, 73px) - 88px);
		overflow-y: auto;
		scrollbar-width: thin;
		padding: 2px;

		/* `align-self: start` is load-bearing, not cosmetic. Stretched, the
		   rail would fill its grid area and sticky would have nowhere to
		   travel; content-height inside a tall area is what lets it move. The
		   span is generated by render.php, one row per top-level block after
		   it, because a rail confined to a single row sticks for a few hundred
		   pixels and then scrolls away looking broken. */
		align-self: start;
		grid-row: auto / span var(--pfg-hub-toc-span, 1);
	}

	/* Anchors land below the sticky header rather than under it. */
	.pfg-hub-body > .wp-block-post-content:has(> .pfg-hub-toc) [id^="a-"] {
		scroll-margin-top: calc(var(--hdr-h, 73px) + 68px);
	}
}

/* A standalone call to action sits centred under the column it follows.

   `wp:buttons` is a flex container and core's default justification is
   flex-start, so "Browse all reviewed firms" hugged the left edge of a centred
   62–75ch column while the toplist's own show-more sat centred a few pixels
   above it. Two buttons, the same width of page, two different alignments —
   which reads as an oversight rather than a hierarchy, and the hierarchy is the
   whole point of that pair (neutral show-more, filled route out).

   Scoped to a TOP-LEVEL button group only. A `wp:buttons` inside a group or
   columns is part of a composed layout an author built, and centring it there
   would be us overruling them. `:not([class*="is-content-justification"])`
   does the same job for the toolbar: the moment an editor picks an alignment
   core stamps that class, and their choice wins. */
.pfg-hub-body > .wp-block-post-content > .wp-block-buttons:not([class*="is-content-justification"]) {
	/* Centred on the CONTAINER, not inside the document column, so it lines up
	   with the toplist's own show-more control directly above it. That pairing
	   (neutral show-more, filled route out) is the point of the rule.

	   Written against the container rather than the column deliberately, so it
	   survives the flip either way: under the left policy centring inside the
	   column would park the button ~424px in, and under the centred policy the
	   column's axis and the container's coincide anyway. The control it pairs
	   with is on the container, so this is too. */
	max-width: none;
	margin-inline: 0;
	justify-content: center;
}

/* =========================================================================
   Home feed teaser

   The home page shows the top few firms of one market and routes to that
   market's hub for the rest. The group lives in the front page's own CONTENT
   (propfirmgrade-data#535) so editors own its wording; the theme keeps only
   these class names. It deliberately has no toplist-header and no filter bar,
   so it needs its own title and its own way out — that is all this is.

   The route out is a LINK, not a button: it goes somewhere. The alternate
   markets sit quieter than the primary route on purpose — one obvious next
   step, two available ones.
   ========================================================================= */

.pfg-teaser__title {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--h-4, 18px);
	font-weight: 700;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	margin: 0;
	padding: 2px 6px 0;
	letter-spacing: 0;
	text-transform: capitalize;
}

.pfg-teaser__sub {
	margin: 6px 0 16px;
	padding: 0 6px;
	font-size: var(--wp--preset--font-size--small, 14px);
	color: var(--wp--preset--color--text-3, #979CAD);
	max-width: 62ch;
}

.pfg-teaser__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 10px 22px;
	margin-top: 20px;
	padding: 0 6px;
	text-align: center;
}

.pfg-teaser__more,
.pfg-teaser__alt {
	margin: 0;
}

.pfg-teaser__more a::after {
	content: "\2192";
	margin-left: 9px;
}

.pfg-teaser__more a {
	display: inline-flex;
	align-items: center;
	min-height: 46px;
	padding: 0 30px;
	border: 1px solid var(--acc, #a79fff);
	border-radius: 999px;
	color: var(--acc, #a79fff);
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
	background: color-mix(in srgb, var(--acc, #a79fff) 8%, transparent);
	transition: background 0.15s ease, color 0.15s ease;
	text-transform: capitalize;
}

.pfg-teaser__more a:hover,
.pfg-teaser__more a:focus-visible {
	background: var(--acc, #a79fff);
	color: #0b0d14;
}

.pfg-teaser__alt {
	font-size: var(--wp--preset--font-size--small, 14px);
	color: var(--wp--preset--color--text-4, #838A9D);
}

.pfg-teaser__alt a {
	color: var(--wp--preset--color--text-2, #C7CBD9);
	text-decoration: none;
	border-bottom: 1px solid rgba(255, 255, 255, 0.16);
	padding-bottom: 1px;
}

.pfg-teaser__alt a + a {
	margin-left: 14px;
}

.pfg-teaser__alt a:hover,
.pfg-teaser__alt a:focus-visible {
	color: var(--wp--preset--color--text-1, #F2F3F8);
	border-bottom-color: currentColor;
}

/* =========================================================================
   Trust / methodology strip
   ========================================================================= */

.pfg-strip {
	background: var(--wp--preset--color--surface-1, #14171E);
	border: 1px solid rgba(255, 255, 255, 0.055);
	border-radius: var(--wp--custom--radius--card, 20px);
	padding: var(--wp--preset--spacing--40);
}

.pfg-strip__aside .wp-block-buttons {
	margin-top: 16px;
}

.pfg-strip__claims {
	font-size: clamp(13px, 0.75vw, 15.5px);
	line-height: 1.55;
	color: var(--wp--preset--color--text-2, #C6CBDD);
}

/* =========================================================================
   Disclosure + footer
   ========================================================================= */

.pfg-disclosure {
	font-size: var(--wp--preset--font-size--small, 14px);
	line-height: 1.6;
	color: var(--wp--preset--color--text-3, #979CAD);
}

.pfg-footer,
footer:has(> .pfg-footer__inner) {
	margin-top: 10px;
	border-top: 1px solid rgba(255, 255, 255, 0.07);
}

/* No footer-only logo size. A `.pfg-footer .pfg-lockup svg { height: 20px }`
   rule sat here and never applied, because the wordmark carried an inline
   24px height. Once the size moved to an attribute (mobile follow-up,
   2026-09-17) that rule would have shrunk the desktop footer logo on the
   templates whose footer carries .pfg-footer and not on the others, so it is
   removed: the footer logo stays the 24px it has always rendered at, and
   takes the phone rule's 20px below 761px like the header's. */
.pfg-footer .pfg-lockup {
	order: 0;
	margin-right: 0;
}

.pfg-footer__cols {
	gap: clamp(20px, 3vw, 40px);
}

.pfg-footer__label {
	font-size: clamp(12px, 0.69vw, 14px);
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--text-4, #838A9D);
	font-family: var(--wp--preset--font-family--body);
	margin: 0;
	/*
	 * Pinned, and now load-bearing in a third way. These were <h6> to look
	 * small, which made the footer skip h2 -> h6; they were promoted to <h2>,
	 * which fixed the skip and silently shortened the page by 3px (6px at 390,
	 * where the columns stack) because h6 resolves to 1.4 and h2 to 1.16.
	 *
	 * They are now <p>. data#385: "How we make money" and "Editorial" are
	 * footer disclosures, and a heading here puts them in the article outline
	 * of every page on the site. Not being headings at all settles both
	 * problems - nothing to skip, nothing in the outline - and this block is
	 * what keeps the appearance identical across all three shapes. A label's
	 * appearance must not depend on which element it happens to use.
	 */
	line-height: 1.4;
}

.pfg-footer__text {
	line-height: 1.6;
	color: var(--wp--preset--color--text-3, #979CAD);
	margin: 0;
}

.pfg-footernav .wp-block-navigation__container {
	gap: 0;
}

.pfg-footernav .wp-block-navigation-item__content {
	display: flex;
	align-items: center;
	min-height: 32px;
	padding: 5px 0;
	color: var(--wp--preset--color--text-body, #A6ACC0);
	font-weight: 600;
}

.pfg-footernav .wp-block-navigation-item__content:hover {
	color: var(--wp--preset--color--text-1, #F2F3F8);
}

.pfg-footer__legal {
	border-top: 1px solid rgba(255, 255, 255, 0.05);
	padding-top: 14px;
	align-items: baseline;
}

.pfg-footer__legal p {
	margin: 0;
}

/* =========================================================================
   Phone tab bar
   ========================================================================= */

/* --pfg-tabbar-h is the bar's height EXCLUDING the safe-area inset (that comes
   from the padding below). Anything that must float above the bottom nav —
   the review sticky offer bar, the cookie notice — reads it, so the two
   cannot drift apart. It is 71px only while the bar is actually in the DOM:
   the bar is withheld for the MVP ('mobile-tabbar' in Unbuilt.php), and
   furniture floating 71px above nothing is a hole at the bottom of the page. */
:root {
	--pfg-tabbar-h: 0px;
}

:root:has(.pfg-tabbar) {
	--pfg-tabbar-h: 71px;
}

.pfg-tabbar {
	display: none;
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 96;
	align-items: stretch;
	justify-content: space-around;
	gap: 2px;
	padding: 7px 10px calc(7px + env(safe-area-inset-bottom));
	background: rgba(14, 16, 23, 0.96);
	-webkit-backdrop-filter: blur(16px);
	backdrop-filter: blur(16px);
	border-top: 1px solid var(--border-2);
}

.pfg-tabbar__item {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 3px;
	flex: 1 1 0;
	min-height: 54px;
	padding: 2px 0 0;
	border-radius: var(--wp--custom--radius--md, 14px);
	color: var(--wp--preset--color--text-3, #979CAD);
	text-decoration: none;
}

.pfg-tabbar__item:hover,
.pfg-tabbar__item[aria-current="page"] {
	color: var(--wp--preset--color--text-1, #F2F3F8);
}

.pfg-tabbar__icon {
	display: grid;
	place-items: center;
	width: 26px;
	height: 24px;
}

.pfg-tabbar__label {
	font-size: 10.5px;
	font-weight: 700;
}

.pfg-tabbar__item.is-primary {
	color: var(--acc);
}

.pfg-tabbar__item.is-primary .pfg-tabbar__icon {
	width: 42px;
	height: 42px;
	margin-top: -16px;
	border-radius: 999px;
	background: var(--acc-fill);
	color: var(--on-acc);
	box-shadow: 0 8px 20px -6px rgba(var(--acc-rgb), 0.55);
}

/* =========================================================================
   Page frame
   ========================================================================= */

.pfg-main {
	position: relative;
	z-index: 1;
}

/* =========================================================================
   Tablet and below: the burger takes over
   ========================================================================= */

@media (max-width: 1079px) {
	:root {
		--gutter: 20px;
	}

	.pfg-header {
		padding: 14px var(--gutter) 0;
		row-gap: 0;
	}

	/* One row: wordmark left, search and burger right. */
	.pfg-auth,
	.pfg-settings {
		display: none;
	}

	.pfg-burger {
		display: block;
	}

	.pfg-util {
		gap: 8px;
	}

	/* ---- Mobile search: a full-width overlay state, not a growing pill ----

	   The desktop affordance is a 44px circle that widens to min(280px, 42vw)
	   in place. That arithmetic does not survive a phone row: at 390px the
	   wordmark is 183px and the expanded field 242px, which with the burger and
	   two gaps needs 481px of a 390px row. The field was therefore drawn on top
	   of the logo and still clipped at the right edge.

	   The fix is a different STATE, not a smaller number. While the search has
	   focus the wordmark stands down and the field takes the row it vacates, so
	   the field is as wide as the header minus the burger, which stays reachable
	   the whole time. `:has()` is already the header's state mechanism — the
	   drawer is read the same way. */
	.pfg-header:has(.pfg-search:focus-within) .pfg-lockup {
		display: none;
	}

	.pfg-header:has(.pfg-search:focus-within) .pfg-util {
		flex: 1 1 auto;
		min-width: 0;
		margin-left: 0;
	}

	.pfg-header:has(.pfg-search:focus-within) .pfg-search {
		flex: 1 1 auto;
		min-width: 0;
	}

	.pfg-search:focus-within .wp-block-search__inside-wrapper {
		width: 100%;
	}

	/* The switcher becomes a full-bleed segmented band below the header. */
	.pfg-segwrap {
		display: block;
		order: 20;
		flex: 1 1 100%;
		width: 100%;
		margin: 12px calc(-1 * var(--gutter)) 0;
		padding: 8px var(--gutter) 10px;
		background: var(--wp--preset--color--bg-page, #101219);
		border-top: 1px solid var(--border-1);
		box-shadow: 0 14px 18px -18px rgba(0, 0, 0, 0.9);
	}

	.pfg-seg {
		order: 0;
		width: 100%;
		height: 50px;
		margin-right: 0;
	}

	/* The navigation is now ONE block that positions itself; there is no panel
	   wrapper left to style. What remains from that group is the account
	   pattern, which used to be hidden along with the panel below this width and
	   must keep being hidden now that it is a direct child of the header. */
	.pfg-header .pfg-auth {
		display: none;
	}

	/* Tap outside to close. */
	/* The header is sticky with z-index 50, so it is a stacking context: every
	   z-index inside it — including the drawer's — is scoped to that 50, and
	   the tab bar (96) painted straight over the open menu. Lift the whole
	   header while the menu is open; closed, it stays at 50 as before. */
	.pfg-header:has(.pfg-burger:checked) {
		z-index: 120;
	}

	/* Hung from the logo row, exactly like the drawer it dismisses: with the
	   drawer covering the switcher band, a scrim that started below the band
	   would leave a live strip of tab links poking out beside an open menu. */
	.pfg-header:has(.pfg-burger:checked) .pfg-navscrim {
		display: block;
		position: absolute;
		top: var(--hdr-row-h, 70px);
		left: 0;
		width: 100vw;
		height: calc(100dvh - var(--hdr-row-h, 70px));
		/* Above the cookie notice (90) and the tab bar (96): while the drawer is
		   open it owns the screen, and the dismiss target must cover them too. */
		z-index: 110;
		background: var(--scrim);
	}

	.pfg-tabbar {
		display: flex;
	}

	/* The tab bar must never cover the last line of the footer — and with
	   no bar there is nothing to clear. */
	body:has(.pfg-tabbar) .pfg-footer,
	body:has(.pfg-tabbar) footer:has(> .pfg-footer__inner) {
		padding-bottom: calc(74px + env(safe-area-inset-bottom));
	}
}

/* =========================================================================
   Phone
   ========================================================================= */

@media (max-width: 760px) {
	.pfg-subnav-bar {
		position: static;
	}


	:root {
		--gutter: 12px;
	}

	.pfg-lockup svg {
		height: 20px;
	}

	.pfg-hero__title {
		font-size: clamp(30px, 9vw, 40px);
	}

	/* Hover-expansion is a pointer affordance with no touch equivalent: a tap
	   leaves :hover latched afterwards. `:not(:focus-within)` is load-bearing —
	   without it this rule sits later in the sheet than the overlay state above
	   and clamps the focused field back to 44px whenever the pointer happens to
	   rest on it, which is exactly where a tap leaves it.

	   The phone tier's other search rule — focus to min(280px, 62vw) — is gone.
	   That 62vw was the overlap bug: 242px of field beside a 183px wordmark in a
	   390px row. */
	.pfg-search:hover:not(:focus-within) .wp-block-search__inside-wrapper {
		width: 44px;
	}

	/* ---- The collapse gets no duration ----

	   `:focus-within` drops on the same frame as the blur, so the overlay state
	   above stops applying at once and the 183px wordmark is laid out again
	   immediately. The field's `width` does not follow: it is transitioned
	   (240ms, the base rule at the top of this sheet), so it is still ~310px and
	   only interpolates down from there.

	   For those 240ms the sheet is in the idle state and the geometry is in the
	   focused one, and the logo row cannot hold both. It does not overflow — the
	   header wraps, because the switcher band below it is a `flex: 1 1 100%`
	   child of the same flex container — so the utility cluster breaks onto a
	   second line instead. Measured at 390px: the header is 164px tall rather
	   than 140px for the whole 240ms, and the band, `main`, and everything under
	   it are shoved down 24px and snapped back. At 480px the wordmark is the
	   child that wraps and the header reaches 182px.

	   So the collapse is given no duration and the two change state on the same
	   frame, leaving no window in which they disagree. This is a state fix, not
	   a motion one: the transition was the carrier, not the cause.

	   The expand keeps its 240ms. Nothing is stranded mid-width on the way in —
	   the wordmark has already stood down, so the row has the space the whole
	   time, and it is measured clean frame by frame.

	   The transition that runs is the one declared in the AFTER-change style, so
	   the duration belongs on the focused rule and the idle rule declares none.
	   Both blur paths land on a rule with no duration: bare, and with `:hover`
	   latched by the tap, which sets `width` only.

	   Scoped to this tier rather than to 1079px, where the overlay state itself
	   is defined, because that is where the row is short enough to break: 390,
	   430 and 480 all wrap, 520 and up are clean. Above 760px the pointer
	   hover-expansion is live and unimplicated, and it keeps animating both
	   ways. `prefers-reduced-motion` is handled globally in base.css. */
	.pfg-search .wp-block-search__inside-wrapper {
		transition: none;
	}

	.pfg-search:focus-within .wp-block-search__inside-wrapper {
		transition: width 240ms cubic-bezier(0.16, 1, 0.3, 1);
	}

	.pfg-footer__legal {
		gap: 8px;
	}

	.pfg-footer__cols {
		gap: 22px;
	}

	/* READING TEXT IS 14PX ON A PHONE (mobile follow-up, 2026-09-17). The
	   footer's two paragraphs of independence copy read at 12.5px (preset
	   `small`), its legal line at 11.5px (preset `xs`) and the review
	   disclosures at 12.5px, because every preset clamp sits at its minimum
	   here. They take the `ui` token, 14px at these widths.

	   `!important` only on the footer paragraphs, and only because the block
	   markup carries `has-small-font-size` / `has-xs-font-size`, which WordPress
	   prints with `!important`; changing the part's fontSize would change the
	   desktop footer too. The uppercase footer labels ("How we make money")
	   are labels and stay at their 12px floor. Above 760px nothing changes. */
	.pfg-footer__text,
	.pfg-footer__legal p {
		font-size: var(--wp--preset--font-size--ui, 14px) !important;
	}

	.pfg-disclosure {
		font-size: var(--wp--preset--font-size--ui, 14px);
	}

	/* Authored tables in a review or page body: cells and captions at 14px, the
	   uppercase head row stays a label at the 12.5px `small` step. The plugin's
	   review-context copy of this idiom carries the same phone rule; keep the
	   two in step, as the note above the base rules asks. */
	.pfg-page-body .wp-block-post-content .wp-block-table table,
	.pfg-rv-article .wp-block-post-content .wp-block-table table,
	.pfg-page-body .wp-block-post-content .wp-block-table figcaption,
	.pfg-rv-article .wp-block-post-content .wp-block-table figcaption {
		font-size: var(--wp--preset--font-size--ui, 14px);
	}

	.pfg-page-body .wp-block-post-content .wp-block-table thead th,
	.pfg-rv-article .wp-block-post-content .wp-block-table thead th {
		font-size: var(--wp--preset--font-size--small, 12.5px);
	}
}

/* ---- The logo row at 320px ----

   The row is wordmark 183 + its 4px margin, search 44 and burger 42, with two
   14px header gaps and 12px of gutter each side: 325px. At 320px the burger
   is the child that wraps, so the header grew from 140px to 182px, the
   switcher band and page were pushed down 42px, and the drawer (hung from
   --hdr-row-h, 70px) opened OVER the burger that closes it. 8px gaps bring the
   row to 313px. 360px and up are untouched: that row is 325px there too. */
@media (max-width: 359px) {
	.pfg-header {
		column-gap: 8px;
	}
}

/* =========================================================================
   Not-built notice (mocked navigation destinations)

   Marks a page that exists only so the design's secondary navigation is
   walkable. The route is development-only; production 404s it. See
   RouteRegistry::mock_pages() and docs/design/MOCKED-SECTIONS.md.
   ========================================================================= */

.pfg-notbuilt {
	background: rgba(240, 185, 11, 0.05);
	border: 1px dashed rgba(240, 185, 11, 0.35);
	border-radius: 18px;
	padding: 20px;
	display: flex;
	flex-direction: column;
	gap: 10px;
	max-width: 70ch;
}

.pfg-notbuilt__label {
	margin: 0;
	font-size: clamp(10.5px, 0.6vw, 12.5px);
	font-weight: 800;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--warning, #F0B90B);
}

.pfg-notbuilt p {
	margin: 0;
	font-size: clamp(13.5px, 0.78vw, 15.5px);
	line-height: 1.6;
	color: var(--wp--preset--color--text-2, #C6CBDD);
}

.pfg-notbuilt__foot {
	font-size: var(--wp--preset--font-size--small, 14px) !important;
	color: var(--wp--preset--color--text-4, #838A9D) !important;
}

/* -------------------------------------------------------------------------
   Plain-page document column (page.html)

   Plain pages never had a measure at all: their post content rendered at
   the raw contentSize — paragraphs 1180px wide at 1440 — and this flex
   column plus the constrained layout's auto margins made every direct
   child shrink to fit-content, so short titles floated centred over
   full-width paragraphs.

   The column is the DOCUMENT measure (owner decision 2026-08-24): pages
   rendered through this wrapper — legal, learn articles, methodology
   children, verify, tools — are documents, and they read at 75ch (~660px
   at 1440, scaling with the fluid type). The same ruling (second pass,
   same day) put ALL long-form prose on this measure — .pfg-home-copy and
   .pfg-hub-intro included. The 62ch reading measure survives only where
   it is structural rather than editorial: the hero sub, the home section
   ledes, and the teaser sub — standfirsts inside a composition, not
   documents. The two are separate tokens on purpose.

   The measure is registered as a <length> so it computes HERE, against the
   wrapper's body font, and inherits down as one pixel value — capping each
   child at a raw `75ch` would resolve against the child's own font-size
   and hand a 30px h2 a ~1300px box, breaking the shared left edge (the
   same trap editor.css documents). Browsers without @property fall back
   to per-element ch: wider heading boxes, same centred column.

   Product blocks are the documented exception: a firm list or summary
   panel is a panel, not prose — the design never shows one at reading
   width — so anything of ours, and anything an editor deliberately sets
   alignwide/alignfull, keeps the full container instead.
   ------------------------------------------------------------------------- */

@property --pfg-document-col {
	syntax: "<length>";
	inherits: true;
	initial-value: 660px;
}

.pfg-page-body {
	display: flex;
	flex-direction: column;
	gap: var(--wp--preset--spacing--30, 20px);
	--pfg-document-col: var(--wp--custom--layout--document-max, 75ch);
}

/* Defeat the flex-item fit-content shrink: children span the container,
   then cap. WordPress's constrained-layout auto margins do the centring. */
.pfg-page-body > * {
	width: 100%;
}

.pfg-page-body > .wp-block-post-title,
.pfg-page-body > .wp-block-post-content > * {
	max-width: var(--pfg-document-col);
	margin-inline: auto;
}

/* Same content test as the hub column above: a block earns the full container
 * by holding a table or a toplist, not by carrying a product class. */
.pfg-page-body > .wp-block-post-content > .alignwide,
.pfg-page-body > .wp-block-post-content > .alignfull,
.pfg-page-body > .wp-block-post-content > table,
.pfg-page-body > .wp-block-post-content > [class*="pfg-toplist"],
.pfg-page-body > .wp-block-post-content > :has(table),
.pfg-page-body > .wp-block-post-content > :has([class*="pfg-toplist"]) {
	max-width: none;
}

/* A standalone call to action sits centred under the column it follows.

   `wp:buttons` is a flex container and core's default justification is
   flex-start, so "Browse all reviewed firms" hugged the left edge of a centred
   62–75ch column while the toplist's own show-more sat centred a few pixels
   above it. Two buttons, the same width of page, two different alignments —
   which reads as an oversight rather than a hierarchy, and the hierarchy is the
   whole point of that pair (neutral show-more, filled route out).

   Scoped to a TOP-LEVEL button group only. A `wp:buttons` inside a group or
   columns is part of a composed layout an author built, and centring it there
   would be us overruling them. `:not([class*="is-content-justification"])`
   does the same job for the toolbar: the moment an editor picks an alignment
   core stamps that class, and their choice wins. */
.pfg-page-body > .wp-block-post-content > .wp-block-buttons:not([class*="is-content-justification"]) {
	/* Centred on the CONTAINER, not inside the document column. The column is
	   left-aligned now, so centring within it would park the button ~424px in,
	   agreeing with neither the prose at the gutter nor the toplist's own
	   show-more control, which centres on the full container directly above it.
	   Escaping the column keeps this button under that one, which is the
	   pairing the owner asked for when they asked for it to be centred. */
	max-width: none;
	justify-content: center;
}

/* Trust-strip claims.

   Was a wp:html island with inline flex styles, which the Site Editor rendered
   as a textarea of markup — so four lines of editorial copy on the home page
   could not be edited where they appear. It is a core list now; the bullet is
   drawn here rather than typed into each line, so an editor adding a fifth
   claim gets a matching one for free. */

.pfg-strip__claims {
	display: flex;
	flex-direction: column;
	gap: 7px;
	margin: 14px 0 0;
	padding: 0;
	list-style: none;
}

.pfg-strip__claims li {
	position: relative;
	padding-left: 14px;
}

.pfg-strip__claims li::before {
	content: "\00B7";
	position: absolute;
	left: 0;
}

/* =========================================================================
   Featured trio — three tickets, one per market

   The tickets themselves are styled by the featured-deal block (ticket
   variant). This is only the row: three across from 1024px, one below. A
   market that resolves no firm renders no block at all, so auto-fit closes
   the row up to two or one rather than leaving a hole.
   ========================================================================= */

.pfg-featured-trio {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(14px, 1.4vw, 20px);
	align-items: stretch;
}

/* The group is a flow layout, which margins every child after the first.
   In a grid that margin reads as the first ticket sitting higher. */
.wp-block-group.pfg-featured-trio > * + *,
.wp-block-group.pfg-markets__grid > * + * {
	margin-block-start: 0;
}

@media (min-width: 1024px) {
	.pfg-featured-trio {
		grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
	}
}

/* =========================================================================
   Home page sections below the feed

   Prose-width sections set in the page's type, separated by space rather
   than boxes. One heading, at most one lede, then the content.
   ========================================================================= */

.pfg-home-section {
	max-width: 1160px;
	margin: clamp(40px, 4.6vw, 72px) auto 0;
}

.pfg-home-section__title {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(24px, 2.2vw, 34px);
	font-weight: 300;
	line-height: 1.15;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	margin: 0 0 10px;
}

.pfg-home-section__lede {
	max-width: 62ch;
	font-size: clamp(15px, 1.05vw, 17px);
	line-height: 1.6;
	color: var(--wp--preset--color--text-body, #A6ACC0);
	margin: 0 0 clamp(18px, 2vw, 28px);
}

.pfg-home-section p {
	color: var(--wp--preset--color--text-body, #A6ACC0);
}

.pfg-home-section__more {
	margin: clamp(14px, 1.6vw, 22px) 0 0;
}

.pfg-home-section__more a,
.pfg-home-section a {
	color: var(--acc, #A79FFF);
}

/* Grade / ranking / fit: three columns, a hairline above each term. */
.pfg-explainer__cols {
	gap: clamp(20px, 2.4vw, 40px);
}

.pfg-explainer__cols .wp-block-column {
	border-top: 1px solid rgba(255, 255, 255, 0.09);
	padding-top: 14px;
}

.pfg-explainer__term {
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(19px, 1.4vw, 23px);
	font-weight: 400;
	color: var(--wp--preset--color--text-1, #F2F3F8);
	margin: 0 0 8px;
}

.pfg-explainer__cols p {
	font-size: clamp(14.5px, 1vw, 16px);
	line-height: 1.65;
	margin: 0;
}

/* How a grade is earned: four numbered steps in two columns, the numeral
   set in the accent. Numbered because the order is the order of the work. */
.pfg-steps__list {
	counter-reset: pfg-step;
	list-style: none;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr));
	gap: clamp(16px, 2vw, 28px) clamp(24px, 3vw, 48px);
	margin: 0;
	padding: 0;
}

.pfg-steps__list > li {
	counter-increment: pfg-step;
	position: relative;
	padding-left: 44px;
	font-size: clamp(14.5px, 1vw, 16px);
	line-height: 1.65;
	color: var(--wp--preset--color--text-body, #A6ACC0);
}

.pfg-steps__list > li::before {
	content: counter(pfg-step);
	position: absolute;
	left: 0;
	top: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 24px;
	font-weight: 300;
	line-height: 1.1;
	font-variant-numeric: tabular-nums;
	color: var(--acc, #A79FFF);
}

.pfg-steps__list > li strong {
	color: var(--wp--preset--color--text-1, #F2F3F8);
	font-weight: 600;
}

/* Three markets: each card carries its market's accent. A class rather than
   data-world, because core/group's save() emits no data attributes and the
   Site Editor would flag the pattern as invalid. */
.pfg-market--futures {
	--acc: var(--v-futures-text);
	--acc-rgb: var(--v-futures-rgb);
}

.pfg-market--forex {
	--acc: var(--v-forex-text);
	--acc-rgb: var(--v-forex-rgb);
}

.pfg-market--crypto {
	--acc: var(--v-crypto-text);
	--acc-rgb: var(--v-crypto-rgb);
}

.pfg-markets__grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
	gap: clamp(14px, 1.4vw, 20px);
}

/* The design's cross-vertical card: surface-1, a white hairline, a colour
   DOT for the market — never a coloured edge (borders over shadows, and the
   accent only where the design puts it). */
.pfg-market {
	background: var(--wp--preset--color--surface-1, #13151D);
	border: 1px solid var(--border-2, rgba(255, 255, 255, 0.08));
	border-radius: 20px;
	padding: clamp(16px, 1.6vw, 22px) clamp(18px, 1.8vw, 26px);
	transition: border-color 160ms ease;
}

.pfg-market:hover,
.pfg-market:has(:focus-visible) {
	border-color: var(--border-strong, rgba(255, 255, 255, 0.14));
}

.pfg-market__name {
	display: flex;
	align-items: center;
	gap: 10px;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(20px, 1.5vw, 25px);
	font-weight: 400;
	margin: 0 0 6px;
}

.pfg-market__name::before {
	content: "";
	width: 9px;
	height: 9px;
	border-radius: 999px;
	background: var(--acc, #A79FFF);
	flex: 0 0 9px;
}

.pfg-market__name a {
	color: var(--wp--preset--color--text-1, #F2F3F8);
	text-decoration: none;
}

.pfg-market__name a::after {
	content: "";
	position: absolute;
	inset: 0;
}

.pfg-market {
	position: relative;
}

.pfg-market__count {
	margin: 0 0 8px;
	font-size: 13px;
	color: var(--wp--preset--color--text-3, #979CAD);
}

.pfg-market__count strong {
	font-variant-numeric: tabular-nums;
	font-family: var(--wp--preset--font-family--display);
	font-size: 26px;
	font-weight: 300;
	color: var(--acc, #A79FFF);
	margin-right: 4px;
}

.pfg-market__what {
	margin: 0;
	font-size: 14.5px;
	line-height: 1.55;
}

/* FAQ: native details, one hairline per question, no box. */
.pfg-faq__item {
	border-top: 1px solid rgba(255, 255, 255, 0.09);
	padding: 14px 0;
	margin: 0;
	max-width: 78ch;
}

.pfg-faq__item:last-of-type {
	border-bottom: 1px solid rgba(255, 255, 255, 0.09);
}

.pfg-faq__item > summary {
	cursor: pointer;
	list-style: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	font-size: clamp(15.5px, 1.1vw, 18px);
	font-weight: 600;
	color: var(--wp--preset--color--text-1, #F2F3F8);
}

.pfg-faq__item > summary::-webkit-details-marker {
	display: none;
}

.pfg-faq__item > summary::after {
	content: "+";
	flex: 0 0 auto;
	font-family: var(--wp--preset--font-family--display);
	font-size: 24px;
	font-weight: 300;
	line-height: 1;
	color: var(--acc, #A79FFF);
	transition: transform 180ms ease-out;
}

.pfg-faq__item[open] > summary::after {
	transform: rotate(45deg);
}

.pfg-faq__item > summary:focus-visible {
	outline: none;
	box-shadow: var(--focus-ring);
	border-radius: 6px;
}

.pfg-faq__item p {
	margin: 12px 0 0;
	font-size: clamp(14.5px, 1vw, 16px);
	line-height: 1.65;
}

@media (prefers-reduced-motion: reduce) {
	.pfg-market,
	.pfg-faq__item > summary::after {
		transition: none;
	}
}

/*
 * PHONE: THE REVIEW STARTS UNDER THE SUBNAV, NOT 14PX BELOW IT.
 *
 * The firm template's <main> carries an inline padding-top of
 * clamp(14px, 2vw, 26px). On a phone its floor, 14px, stacked on the group's
 * 26px block margin and left an empty band between the subnav and the
 * breadcrumb. Owner's call, 2026-09-17: drop the padding on phones. The rule
 * lives here rather than in the template because the template's inline style
 * is also copied into any saved wp_template override, which a template edit
 * would not reach. Desktop keeps the clamp.
 */
@media (max-width: 760px) {
	body.single-pfg_firm main.pfg-glow {
		padding-top: 0 !important;
	}
}

/*
 * PHONE: EDITORIAL LISTS SIT ON THE TEXT EDGE.
 *
 * Nothing in the theme set list padding, so every editor-written list kept
 * the browser's 40px inline-start indent. On a 390px screen that is a tenth of
 * the width spent on air, and the bullets floated in from the paragraph above
 * them. 1.1em leaves exactly the room an outside bullet needs, so the bullet
 * lines up with the paragraph edge and the text starts just after it.
 * Owner's call, 2026-09-17.
 */
@media (max-width: 760px) {
	.wp-block-list {
		padding-inline-start: 1.1em;
	}
}

/*
 * FOOTER SOCIAL ICONS: the hit area, not the glyph.
 *
 * Core's logos-only style sets the anchor's padding to 0, which leaves a 16px
 * icon as a 16x16 target — under the 24x24 minimum this site holds itself to
 * (WCAG 2.2 target size, the same rule the mobile pass applied to the header).
 * 6px of padding makes it 28x28 while the glyph stays 16px, so nothing looks
 * bigger and everything is tappable. Core's rule is `:root :where(...)`, which
 * carries the specificity of `:root` alone, so this class pair wins without
 * !important.
 */
.pfg-footer__social .wp-social-link a {
	padding: 6px;
}

.pfg-footer__social .wp-social-link a:focus-visible {
	outline: none;
	border-radius: 999px;
	box-shadow: var(--focus-ring);
}
