/*
Theme Name: AFP Theme
Theme URI: https://github.com/amcd79/affiliate-factory
Author: Digital Blocks
Author URI: https://digitalblocks.example
Description: Block theme for the Digital Blocks affiliate and local-directory sites. Pairs with the afp-core plugin; each site is a theme.json style variation (Roast, Clear, Fresh, Volt, Lawn, Shelter).
Version: 0.1.0
Requires at least: 7.1
Tested up to: 7.1
Requires PHP: 8.2
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: afp-theme
*/

/*
 * Global rules theme.json cannot express. Tokens only — never a raw colour.
 * Why each one is here rather than theme.json is noted inline.
 */

/* Pseudo-classes outside Button/Navigation Link and :where() selectors are not theme.json-native. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}
a {
	text-underline-offset: 3px;
	text-decoration-thickness: 1px;
}
:where(h1, h2, h3, h4) {
	text-wrap: balance;
}
:where(p, li) {
	text-wrap: pretty;
}

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
		scroll-behavior: auto !important;
	}
}

/* 44px tap targets (WCAG 2.5.8 is 24px; the design uses 44). min-height has no theme.json key. */
.wp-element-button,
.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
}

/* Site chrome. Borders sit on the part wrappers, which theme.json cannot target. */
.afp-site-header {
	position: relative;
	border-bottom: 1px solid var(--wp--preset--color--line);
}
.afp-site-header .wp-block-navigation-item__content {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}
/* Logo: core/site-logo renders nothing until a logo is set; when it does, the title is redundant (the logo's alt is the site name). */
.afp-brand .wp-block-site-logo + .wp-block-site-title {
	display: none;
}
.afp-brand .wp-block-site-logo img {
	display: block;
	width: 290px;
	max-width: min(290px, 60vw);
	height: auto;
}
/*
 * Multi-region sites also fit the region switcher in the header row: the logo takes what is
 * left after the gutters, gaps, menu button and switcher (full labels, then the short ones
 * afp-core shows under 560px). A vw calc, not a fluid preset: it depends on those widths.
 */
.afp-multi-region .afp-brand .wp-block-site-logo img {
	max-width: min(290px, 60vw, calc(100vw - 270px));
}
@media (max-width: 559px) {
	.afp-multi-region .afp-brand .wp-block-site-logo img {
		max-width: min(290px, calc(100vw - 214px));
	}
}

/*
 * Zero-JS mobile menu: desktop nav inline; under 782px the same menu sits in a native
 * <details> disclosure (core/details). Keeps the Interactivity API off every page (JS budget).
 * The summary is an icon button: its text ("Menu") stays as the accessible name but is
 * pushed out of view; the hamburger / close icons are CSS masks so they take currentColor.
 */
.afp-nav-mobile {
	display: none;
}
.afp-nav-mobile > summary {
	position: relative;
	display: block;
	width: 48px;
	height: 48px;
	overflow: hidden;
	white-space: nowrap;
	text-indent: 48px;
	border: 1px solid var(--wp--preset--color--line);
	border-radius: var(--wp--custom--radius--button);
	background: var(--wp--preset--color--base-2);
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
	list-style: none;
}
.afp-nav-mobile > summary::-webkit-details-marker {
	display: none;
}
.afp-nav-mobile > summary::before {
	content: "";
	position: absolute;
	inset: 0;
	margin: auto;
	width: 24px;
	height: 24px;
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 7h16M4 12h16M4 17h16'/%3E%3C/svg%3E") center / 24px no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M4 7h16M4 12h16M4 17h16'/%3E%3C/svg%3E") center / 24px no-repeat;
}
.afp-nav-mobile[open] > summary::before {
	-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E");
	mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E");
}
.afp-nav-mobile[open] > summary {
	background: var(--wp--preset--color--base-3);
}
.afp-nav-mobile > summary:focus-visible {
	outline: 2px solid var(--wp--preset--color--accent);
	outline-offset: 2px;
}
/* The panel: full width under the header bar, one large row per item. */
.afp-nav-mobile[open] > .wp-block-navigation {
	position: absolute;
	inset: 100% 0 auto 0;
	z-index: 50;
	margin: 0;
	padding: var(--wp--preset--spacing--20) var(--wp--style--root--padding-right, 1rem) var(--wp--preset--spacing--60);
	background: var(--wp--preset--color--base-2);
	border-top: 1px solid var(--wp--preset--color--line);
	border-bottom: 1px solid var(--wp--preset--color--line);
	box-shadow: var(--wp--preset--shadow--card);
}
.afp-nav-mobile .wp-block-navigation__container {
	gap: 0;
	width: 100%;
}
.afp-nav-mobile .wp-block-navigation-item {
	width: 100%;
	border-bottom: 1px solid var(--wp--preset--color--line);
}
.afp-nav-mobile .wp-block-navigation-item__content {
	width: 100%;
	min-height: 56px;
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--large);
	font-weight: var(--wp--custom--display--weight);
	letter-spacing: var(--wp--custom--display--tracking);
}
@media (max-width: 781px) {
	.afp-nav-desktop {
		display: none !important;
	}
	.afp-nav-mobile {
		display: block;
	}
}
/* A menu too long for one row at 782px (afp-core's estimate: body class afp-nav-long) stays
   in the mobile disclosure up to 1199px instead of wrapping onto two or three lines. */
@media (max-width: 1199px) {
	.afp-nav-long .afp-nav-desktop {
		display: none !important;
	}
	.afp-nav-long .afp-nav-mobile {
		display: block;
	}
}
/*
 * Footer: an ink band. theme.json's link and navigation colours are for light
 * surfaces, so links, muted text and the focus ring are re-pointed here (muted =
 * base mixed into ink, ≥ 7:1 on every variation's ink). Descendant selectors on a
 * part wrapper have no theme.json equivalent.
 */
/* The footer band meets the page directly (a hub's last colour band runs into it). */
.wp-site-blocks > footer.wp-block-template-part {
	margin-block-start: 0;
}
.afp-site-footer {
	--afp-footer-muted: color-mix(in srgb, var(--wp--preset--color--base) 76%, var(--wp--preset--color--contrast));
	--afp-footer-rule: color-mix(in srgb, var(--wp--preset--color--base) 18%, var(--wp--preset--color--contrast));
	border-top: 4px solid var(--wp--preset--color--accent);
}
.afp-site-footer a,
.afp-site-footer .wp-block-navigation-item__content {
	color: var(--wp--preset--color--base);
}
.afp-site-footer a:hover {
	color: var(--wp--preset--color--base);
	text-decoration: underline;
}
.afp-site-footer :focus-visible {
	outline-color: var(--wp--preset--color--base);
}
.afp-site-footer .wp-block-site-title {
	font-size: var(--wp--preset--font-size--x-large);
}
.afp-site-footer .wp-block-site-title a {
	color: var(--wp--preset--color--base);
}
.afp-footer-brand > * {
	margin-block: 0;
}
.afp-footer-brand > * + * {
	margin-block-start: var(--wp--preset--spacing--30);
}
.afp-site-footer .wp-block-site-tagline {
	color: var(--afp-footer-muted);
	font-size: var(--wp--preset--font-size--medium);
	max-width: 34ch;
}
.afp-footer-brand .afp-footer-disclosure {
	margin-block-start: var(--wp--preset--spacing--50);
	padding-inline-start: var(--wp--preset--spacing--40);
	border-inline-start: 2px solid var(--afp-footer-rule);
	color: var(--afp-footer-muted);
	max-width: 44ch;
}
.afp-site-footer .afp-footer-heading {
	margin-block-end: var(--wp--preset--spacing--40);
	font-family: var(--wp--preset--font-family--body);
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--afp-footer-muted);
}
.afp-footer-nav .wp-block-navigation-item__content {
	padding-block: 0.25rem;
	font-weight: 500;
	text-decoration: none;
}
.afp-footer-bottom {
	border-top: 1px solid var(--afp-footer-rule);
	color: var(--afp-footer-muted);
}
.afp-footer-bottom p {
	margin: 0;
}
.afp-footer-bottom a {
	font-weight: 700;
}

/* Homepage sections (patterns): vertical rhythm for full-width bands. */
.afp-section {
	padding-block: var(--wp--preset--spacing--70);
}

/* Direct-answer opener on every recipe (AI search): reads as a dek. */
.afp-direct-answer {
	line-height: 1.5;
}

/* Diagram slot (diagram imagery mode): a bordered, matte panel. */
.afp-diagram {
	background-color: var(--wp--custom--image--matte);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: var(--wp--custom--radius--card);
	padding: var(--wp--preset--spacing--50);
}

/* core/table → design .tbl inside a .tbl-box. Cell rules need descendant selectors. */
.wp-block-table {
	overflow-x: auto;
	background-color: var(--wp--preset--color--base-2);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: var(--wp--custom--radius--card);
}
.wp-block-table table {
	border-collapse: separate;
	border-spacing: 0;
	width: 100%;
}
.wp-block-table thead,
.wp-block-table tfoot {
	border: 0;
}
.wp-block-table th,
.wp-block-table td {
	padding: 0.75rem 1rem;
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--line);
	text-align: left;
	vertical-align: top;
}
.wp-block-table tr:last-child > th,
.wp-block-table tr:last-child > td {
	border-bottom: 0;
}
.wp-block-table thead th {
	vertical-align: bottom;
	font-weight: 700;
	color: var(--wp--preset--color--contrast);
	border-bottom: 1px solid var(--wp--preset--color--line);
}
.wp-block-table tbody th {
	font-weight: 600;
	font-size: 0.8125rem;
	color: var(--wp--preset--color--contrast-2);
	white-space: nowrap;
}
.wp-block-table td {
	font-variant-numeric: tabular-nums;
}
.wp-block-table figcaption {
	margin: 0;
	padding: 0.75rem 1rem;
	border-top: 1px solid var(--wp--preset--color--line);
}

/* core/details → design .faq rows (not the mobile menu). ::marker and summary layout are not theme.json-native. */
.wp-block-details:not(.afp-nav-mobile) {
	border-top: 1px solid var(--wp--preset--color--line);
	border-bottom: 1px solid var(--wp--preset--color--line);
}
.wp-block-details:not(.afp-nav-mobile) + .wp-block-details {
	border-top: 0;
	margin-block-start: 0;
}
.wp-block-details:not(.afp-nav-mobile) summary {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 1rem;
	min-height: 56px;
	padding-block: 0.875rem;
	font-weight: 700;
	color: var(--wp--preset--color--contrast);
	cursor: pointer;
	list-style: none;
}
.wp-block-details:not(.afp-nav-mobile) summary::-webkit-details-marker {
	display: none;
}
.wp-block-details:not(.afp-nav-mobile) summary::after {
	content: "";
	flex: none;
	width: 0.6em;
	height: 0.6em;
	margin-inline-end: 0.25em;
	border-right: 2px solid var(--wp--preset--color--contrast-2);
	border-bottom: 2px solid var(--wp--preset--color--contrast-2);
	transform: translateY(-25%) rotate(45deg);
}
.wp-block-details:not(.afp-nav-mobile)[open] summary::after {
	transform: translateY(25%) rotate(-135deg);
}
.wp-block-details:not(.afp-nav-mobile) > :not(summary) {
	color: var(--wp--preset--color--contrast-2);
	max-width: 64ch;
}
.wp-block-details:not(.afp-nav-mobile) > :last-child:not(summary) {
	padding-bottom: 1.25rem;
}

/* core/search: field border token (3:1 non-text contrast). */
.wp-block-search__input {
	min-height: 44px;
	padding-inline: 0.875rem;
	border: 1px solid var(--wp--preset--color--field);
	border-radius: var(--wp--custom--radius--button);
	background-color: var(--wp--preset--color--base-2);
	color: var(--wp--preset--color--contrast);
}

/*
 * Breadcrumbs: a quiet strip straight under the header bar, full width, in the
 * header's colour (custom.crumbs.band). Painted with a border-image outset, so no
 * wrapper markup and no horizontal scroll; the H1 then gets the page's top air.
 */
.afp-main:has(> .wp-block-afp-breadcrumbs:first-child) {
	margin-block-start: 0;
}
.afp-main > .wp-block-afp-breadcrumbs:first-child {
	margin-block-start: calc(-1 * var(--wp--preset--spacing--50));
	padding-block: 0.625rem;
	border-image: linear-gradient(to top, var(--wp--preset--color--line) 0 1px, var(--wp--custom--crumbs--band, var(--wp--preset--color--base-2)) 1px) fill 0 / / 0 100vw;
	font-size: 0.78125rem;
}
.afp-main > .wp-block-afp-breadcrumbs:first-child [aria-current="page"] {
	color: inherit;
}
.afp-main > .wp-block-afp-breadcrumbs:first-child + * {
	margin-block-start: var(--wp--preset--spacing--60);
}

/*
 * Page rhythm. The page head is the kicker, the H1, the dek and one quiet meta
 * line (afp/head-meta: updated date, commission statement); the full byline
 * closes the article; the content and the trust footer get more air.
 * Adjacent-sibling and :has() selectors have no theme.json equivalent.
 */
.afp-main > :is(.wp-block-post-content, .wp-block-afp-term-content, .afp-with-sidebar) {
	margin-block-start: var(--wp--preset--spacing--60);
}
.afp-main > :is(.wp-block-afp-author-box, .wp-block-afp-related-content),
.afp-with-sidebar__main > .wp-block-afp-author-box {
	margin-block-start: var(--wp--preset--spacing--80);
}
/* The byline closes the article, just above the author box. */
.afp-main > .wp-block-afp-last-updated,
.afp-with-sidebar__main > .wp-block-afp-last-updated {
	margin-block-start: var(--wp--preset--spacing--70);
	padding-block-start: var(--wp--preset--spacing--40);
	border-top: 1px solid var(--wp--preset--color--line);
}
.afp-main > .wp-block-afp-last-updated + .wp-block-afp-author-box,
.afp-with-sidebar__main > .wp-block-afp-last-updated + .wp-block-afp-author-box {
	margin-block-start: var(--wp--preset--spacing--40);
}

/*
 * Articles (guides, products): sections breathe, per-pick sections are separated
 * by a rule and space instead of nested cards. Margins collapse in this flow
 * layout, so a data block's margin and the next heading's never add up.
 */
.afp-article > h2 {
	margin-block-start: var(--wp--preset--spacing--70);
}
.afp-article > h3 {
	margin-block-start: var(--wp--preset--spacing--60);
}
.afp-article > [class*="wp-block-afp-"]:not(.wp-block-afp-affiliate-disclosure, .wp-block-afp-inline-product),
.afp-article > :is(.wp-block-table, .wp-block-image, .wp-block-embed, .wp-block-gallery, .wp-block-media-text, .afp-media, .afp-short-answer, .wp-block-columns) {
	margin-block: var(--wp--preset--spacing--60);
}
.afp-article > .is-style-eyebrow:has(+ h2) {
	margin-block-start: var(--wp--preset--spacing--80);
	padding-block-start: var(--wp--preset--spacing--60);
	border-top: 1px solid var(--wp--preset--color--line);
}
.afp-article > .is-style-eyebrow + h2 {
	margin-block-start: var(--wp--preset--spacing--20);
}
.afp-article > .wp-block-afp-faq {
	margin-block-start: var(--wp--preset--spacing--70);
}

/*
 * Articles, pages and product pages: one 1200px column, the same width as the
 * header and the hubs. Data blocks (picks, tables, summaries, offers) use the
 * full width; prose keeps a readable measure on the same left edge.
 */
:is(.afp-main--article, .afp-main--page, .afp-main--product) .afp-article > :is(p, ul, ol, h2, h3, h4, blockquote, .wp-block-afp-faq, .wp-block-details, .wp-block-afp-callout) {
	max-width: var(--wp--style--global--content-size, 880px);
}
/* Reading text: size, leading and line length are per-site knobs (custom.prose). */
:is(.afp-main--article, .afp-main--page) .afp-article > :is(p, ul, ol):not([class*="-font-size"]),
:is(.afp-main--article, .afp-main--page) .afp-article > .wp-block-columns > .wp-block-column > p:not([class*="-font-size"]) {
	font-size: var(--wp--custom--prose--size, inherit);
	line-height: var(--wp--custom--prose--leading, inherit);
	max-width: var(--wp--custom--prose--measure, var(--wp--style--global--content-size, 880px));
}
/* The spec table reads like prose (label → value): keep it to the text measure. */
.afp-main--product .afp-article .afp-spec__table,
.afp-main--product .afp-article .afp-spec__groups,
.afp-main--product .afp-article .afp-spec__note {
	max-width: var(--wp--style--global--content-size, 880px);
}
.afp-main--product > .wp-block-post-content {
	margin-block-start: var(--wp--preset--spacing--50);
}
.afp-main--product .afp-article > :first-child {
	margin-block-start: 0;
}

/*
 * Category hubs: everything sits at wide width on one left edge (no narrow intro
 * over a wide grid). Prose keeps a readable measure inside that column; the FAQ sits
 * closer to the grid than a new section would. The hub copy is a plain wrapper
 * (afp/term-content), not a layout container, so it gets its own flow spacing.
 */
.afp-main--hub .afp-term-content > * {
	margin-block: 0;
}
.afp-main--hub .afp-term-content > * + * {
	margin-block-start: var(--wp--style--block-gap, 1.25rem);
}
.afp-main--hub .afp-term-content > :is(p, ul, ol, h2, h3, .wp-block-afp-faq) {
	max-width: var(--wp--style--global--content-size, 880px);
}
.afp-main--hub .afp-term-content > p:first-child {
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.5;
	color: var(--wp--preset--color--contrast-2);
}
.afp-main--hub .afp-term-content > h2 {
	margin-block-start: var(--wp--preset--spacing--70);
}
.afp-main--hub .afp-term-content > [class*="wp-block-afp-"] {
	margin-block-start: var(--wp--preset--spacing--70);
}
/*
 * Page headers with a photo. Hubs: the title and opening paragraph beside the category
 * photo (term meta afp_hero_image, via afp/term-content part "image"). Articles: the
 * title and the post's own excerpt beside its featured image. Without a photo the text
 * runs the full width. Responds to the main column's width, not the viewport.
 */
.afp-main--hub,
.afp-main--article {
	container-type: inline-size;
}
:is(.afp-hub-head, .afp-article-head) {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--wp--preset--spacing--60);
	align-items: center;
}
/* Articles: the title column starts at the top of the photo (kicker, H1, dek, meta line). */
.afp-article-head {
	align-items: start;
}
:is(.afp-hub-head__text, .afp-article-head__text) > * {
	margin-block: 0;
}
:is(.afp-hub-head__text, .afp-article-head__text) > * + * {
	margin-block-start: var(--wp--preset--spacing--40);
}
:is(.afp-hub-head__text, .afp-article-head__text) > .afp-kicker + * {
	margin-block-start: var(--wp--preset--spacing--20);
}
:is(.afp-hub-head__text, .afp-article-head__text) > .afp-head-meta {
	margin-block-start: var(--wp--preset--spacing--40);
}
.afp-article-head__dek {
	max-width: 40em;
	color: var(--wp--preset--color--contrast-2);
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.5;
}
.afp-article-head__dek .wp-block-post-excerpt__excerpt {
	margin: 0;
}
.afp-article-head > .wp-block-post-featured-image {
	margin: 0;
	overflow: hidden;
	border-radius: clamp(12px, calc(var(--wp--custom--radius--card) * 1.4), 24px);
	background-color: var(--wp--custom--image--placeholder);
}
.afp-article-head > .wp-block-post-featured-image img {
	display: block;
	border-radius: 0;
}
@container (min-width: 720px) {
	.afp-article-head:has(> .wp-block-post-featured-image) {
		grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
		gap: var(--wp--preset--spacing--70);
	}
}
.afp-hub-head__text .afp-term-content > p:first-child {
	max-width: 40em;
}
.afp-term-image {
	margin: 0;
	overflow: hidden;
	aspect-ratio: var(--wp--custom--hub--image-ratio, 1 / 1);
	border-radius: clamp(12px, calc(var(--wp--custom--radius--card) * 1.4), 24px);
	background-color: var(--wp--custom--image--placeholder);
}
.afp-term-image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
@container (min-width: 720px) {
	.afp-hub-head:has(> .afp-term-image) {
		grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
		gap: var(--wp--preset--spacing--70);
	}
}
@container (max-width: 719px) {
	.afp-term-image {
		order: -1;
		aspect-ratio: 16 / 10;
	}
}

/*
 * Criteria list (core/list, block style "criteria"): what a page ranks on, as short items
 * (a bold lead-in, then one line of detail) in an intrinsic grid, each with an icon on a soft
 * tile. The icon follows the list item's class: is-icon-texture, is-icon-warranty, is-icon-cup,
 * is-icon-cabinet (default: a check). Grid layout and ::before/::after icons have no theme.json
 * equivalent; colours are tokens, the SVGs are masks.
 */
.wp-block-list.is-style-criteria {
	--afp-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E");
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
	gap: 0 var(--wp--preset--spacing--40);
	margin-block: var(--wp--preset--spacing--30) 0;
	padding: 0;
	list-style: none;
}
.is-style-criteria > li {
	position: relative;
	min-height: 40px;
	margin: 0;
	padding: 14px 0 14px 52px;
	border-top: 1px solid var(--wp--preset--color--line);
	font-size: 0.875rem;
	line-height: 1.5;
	color: var(--wp--preset--color--contrast-2);
}
.is-style-criteria > li::before,
.is-style-criteria > li::after {
	content: "";
	position: absolute;
	top: 14px;
	left: 0;
	width: 40px;
	height: 40px;
}
.is-style-criteria > li::before {
	border-radius: 12px;
	background: var(--wp--preset--color--base-3);
}
.is-style-criteria > li::after {
	background: var(--wp--preset--color--accent);
	-webkit-mask: var(--afp-icon) center / 22px no-repeat;
	mask: var(--afp-icon) center / 22px no-repeat;
}
.is-style-criteria > li > strong:first-child {
	display: block;
	font-size: 0.9375rem;
	color: var(--wp--preset--color--contrast);
}
.is-style-criteria > .is-icon-texture {
	--afp-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 15c2-2 4-2 6 0s4 2 6 0 3-2 4-1'/%3E%3Cpath d='M4 10c2-2 4-2 6 0s4 2 6 0 3-2 4-1'/%3E%3C/svg%3E");
}
.is-style-criteria > .is-icon-warranty {
	--afp-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3l7 2.6v5.4c0 4.3-3 7.7-7 9.5-4-1.8-7-5.2-7-9.5V5.6z'/%3E%3Cpath d='M9 12l2 2 4-4.5'/%3E%3C/svg%3E");
}
.is-style-criteria > .is-icon-cup {
	--afp-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 4h10l-1.5 16h-7z'/%3E%3Cpath d='M7.5 9h9'/%3E%3C/svg%3E");
}
.is-style-criteria > .is-icon-cabinet {
	--afp-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 5h18'/%3E%3Cpath d='M8 5v14M16 5v14'/%3E%3Cpath d='M8 19h8'/%3E%3Cpath d='M12 9v6M10 13l2 2 2-2'/%3E%3C/svg%3E");
}

/*
 * "Before you buy" (list class afp-before-you-buy): the bold lead-in of each item
 * reads as a short tip, so the list becomes a row of numbered tip cards.
 */
.afp-main .afp-term-content > ul.afp-before-you-buy,
.afp-main .afp-article > ul.afp-before-you-buy {
	--afp-tip-min: 15rem;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--afp-tip-min)), 1fr));
	gap: var(--wp--preset--spacing--40);
	max-width: none;
	padding: 0;
	list-style: none;
	counter-reset: afp-tip;
}
.afp-before-you-buy > li {
	position: relative;
	margin: 0;
	padding: var(--wp--preset--spacing--50);
	padding-block-start: calc(var(--wp--preset--spacing--50) + 2.75rem);
	background-color: var(--wp--preset--color--base-2);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: var(--wp--custom--radius--card);
	color: var(--wp--preset--color--contrast-2);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.55;
	counter-increment: afp-tip;
}
.afp-before-you-buy > li::before {
	content: counter(afp-tip);
	position: absolute;
	inset-block-start: var(--wp--preset--spacing--50);
	inset-inline-start: var(--wp--preset--spacing--50);
	display: grid;
	place-items: center;
	width: 2rem;
	height: 2rem;
	border-radius: 50%;
	background-color: var(--wp--preset--color--badge);
	color: var(--wp--preset--color--badge-contrast);
	font-family: var(--wp--preset--font-family--numeric);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
}
.afp-before-you-buy > li > strong:first-child {
	display: block;
	margin-block-end: var(--wp--preset--spacing--20);
	color: var(--wp--preset--color--contrast);
	font-family: var(--wp--preset--font-family--display);
	font-size: var(--wp--preset--font-size--medium);
	font-weight: var(--wp--custom--display--weight);
	letter-spacing: var(--wp--custom--display--tracking);
	line-height: 1.3;
}

/*
 * Hub FAQ and "Keep reading": full-width colour bands. The columns stay on the
 * 1200px grid; the band is painted with a border-image outset (ink overflow, so no
 * horizontal scroll and no layout change). Keep reading's band runs on into the
 * main element's bottom padding so it meets the footer.
 */
.afp-main--hub .afp-term-content > .wp-block-afp-faq {
	margin-block-start: var(--wp--preset--spacing--80);
	padding-block: var(--wp--preset--spacing--70);
	border-image: linear-gradient(var(--wp--preset--color--line) 0 1px, var(--wp--preset--color--base-2) 1px) fill 0 / / 0 100vw;
}
.afp-main--hub .afp-term-content:has(> .wp-block-afp-faq:last-child) + .wp-block-afp-related-content {
	margin-block-start: 0;
}
.afp-main--hub > .wp-block-afp-related-content {
	padding-block: var(--wp--preset--spacing--70) 0;
	border-image: conic-gradient(var(--wp--preset--color--base-3) 0 0) fill 0 / / 0 100vw var(--wp--preset--spacing--80);
}
.afp-main--hub > .wp-block-afp-related-content:last-child {
	margin-block-end: 0;
}

/*
 * Wide pages (templates/page-deals.html): the hub treatment for page content. One
 * 1200px column, prose capped at the content size on the same left edge, the
 * short disclosure set apart from the intro (it introduces the listings below it).
 */
.afp-wide-content > * {
	margin-block: 0;
}
.afp-wide-content > * + * {
	margin-block-start: var(--wp--style--block-gap, 1.25rem);
}
.afp-wide-content > :is(p, ul, ol, h2, h3) {
	max-width: var(--wp--style--global--content-size, 880px);
}
.afp-wide-content > h2 {
	margin-block-start: var(--wp--preset--spacing--70);
}
/* A section whose data blocks all rendered nothing (e.g. no deal verified today) leaves its heading straight before the next one: hide it. */
.afp-wide-content > h2:has(+ h2) {
	display: none;
}
.afp-wide-content > [class*="wp-block-afp-"] {
	margin-block-start: var(--wp--preset--spacing--60);
}
/* The quiet disclosure sits right under the intro line (no rule, small gap). */
.afp-wide-content > .wp-block-afp-affiliate-disclosure.afp-disclosure {
	margin-block-start: var(--wp--preset--spacing--20);
	max-width: var(--wp--style--global--content-size, 880px);
}
/* Deals: the "Verified deals" heading only shows when a callout rendered under it; the listing then starts high. */
.afp-wide-content > .afp-deals__heading:not(:has(+ .wp-block-afp-deal-callout)) {
	display: none;
}
.afp-wide-content > .afp-disclosure + .afp-deals__heading:not(:has(+ .wp-block-afp-deal-callout)) + .wp-block-afp-product-grid {
	margin-block-start: var(--wp--preset--spacing--50);
}

/*
 * Guide "With sidebar" template: 760px content + 320px sticky sidebar (TOC, compact top
 * pick). Responds to the main column's width, not the viewport; stacks below ~1000px.
 */
.afp-main--sidebar {
	container-type: inline-size;
}
.afp-with-sidebar__aside {
	margin-block-start: var(--wp--preset--spacing--70);
}
@container (min-width: 960px) {
	.afp-with-sidebar {
		display: grid;
		grid-template-columns: minmax(0, 760px) 320px;
		justify-content: space-between;
		align-items: start;
		column-gap: var(--wp--preset--spacing--60);
	}
	.afp-with-sidebar > .afp-with-sidebar__aside {
		position: sticky;
		top: calc(var(--wp-admin--admin-bar--height, 0px) + var(--wp--preset--spacing--50));
		margin-block-start: 0;
	}
}

/*
 * Guide cards (query loops): image on top, type label, title, read time. The whole card is
 * the title's link (stretched ::after); the type label stays clickable above it. Without a
 * featured image the card becomes a text card with an accent rule and a larger title.
 */
.afp-guide-card {
	position: relative;
	display: flex;
	flex-direction: column;
	height: 100%;
	overflow: hidden;
	background-color: var(--wp--preset--color--base-2);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: var(--wp--custom--radius--card);
	transition: box-shadow 0.2s ease;
}
.afp-guide-card:hover {
	box-shadow: var(--wp--preset--shadow--card);
}
.afp-guide-card .wp-block-post-featured-image {
	position: relative;
	margin: 0;
	border-radius: 0;
	background-color: var(--wp--custom--image--placeholder);
}
/* Hover: an ink wash over the photo (opacity only; nothing moves). */
.afp-guide-card .wp-block-post-featured-image::after {
	content: "";
	position: absolute;
	inset: 0;
	background-color: var(--wp--preset--color--contrast);
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.2s ease;
}
.afp-guide-card:is(:hover, :focus-within) .wp-block-post-featured-image::after {
	opacity: 0.2;
}
.afp-guide-card .wp-block-post-featured-image img {
	border-radius: 0;
}
.afp-guide-card .afp-guide-card__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: var(--wp--preset--spacing--50);
}
.afp-guide-card .afp-guide-card__type {
	position: relative;
	z-index: 1;
}
.afp-guide-card .afp-guide-card__type a {
	text-decoration: none;
}
.afp-guide-card .wp-block-post-title a::after {
	content: "";
	position: absolute;
	inset: 0;
}
.afp-guide-card .wp-block-post-excerpt__excerpt {
	margin: 0;
}
.afp-guide-card .afp-guide-card__meta {
	margin-block-start: auto;
	padding-block-start: var(--wp--preset--spacing--30);
}
.afp-guide-card:not(:has(.wp-block-post-featured-image)) {
	border-top: 4px solid var(--wp--preset--color--accent);
}
.afp-guide-card:not(:has(.wp-block-post-featured-image)) .afp-guide-card__body {
	min-height: 13rem;
	padding: var(--wp--preset--spacing--60) var(--wp--preset--spacing--50) var(--wp--preset--spacing--50);
}
.afp-guide-card:not(:has(.wp-block-post-featured-image)) .wp-block-post-title {
	font-size: var(--wp--preset--font-size--x-large) !important;
	line-height: 1.15;
}

/* Media patterns: captions sit close to their media. */
.afp-media > .afp-media__caption {
	margin-block-start: var(--wp--preset--spacing--20);
}
.afp-media-text .wp-block-media-text__media img,
.afp-gallery img {
	border-radius: var(--wp--custom--radius--card);
}


/* Front page / landing: full-width bands from the homepage patterns butt together. */
.afp-front-content > .alignfull {
	margin-block: 0;
}
