/*
 * auto-fill, not auto-fit — corrected site-wide 2026-09-04.
 *
 * The reasoning was already written down at .chefpaulo-recipe-grid below, and
 * fixed there alone; the other five grids kept the bug. With auto-fit an empty
 * track collapses to 0px and the surviving cards stretch to fill the row, so a
 * grid degrades to full-bleed at exactly the moment it is sparsest — a search
 * with one hit, a related-posts row with one sibling, a cluster with one post.
 *
 * That was a cosmetic annoyance until the recipes went to a staged rollout.
 * During wave 1 most recipes have one or two published siblings, so the
 * related-recipes block would have rendered one 1200px-wide card on nearly
 * every recipe page. auto-fill keeps the empty tracks, so one card is card-
 * sized and the row simply has gaps, which is what a partly-filled grid should
 * look like.
 *
 * .chefpaulo-post-grid--single (a per-call-site max-width band-aid applied in
 * taxonomy-cluster.php) is now redundant. It is left in place rather than
 * removed in the same deploy as the cascade fix, so that if anything looks
 * wrong afterwards there is one change to reason about, not two.
 */
/*
 Theme Name:   GeneratePress Child
 Theme URI:    https://chefpaulo.com
 Description:  Child theme for GeneratePress, built for Chef Paulo's site.
 Author:       Dave
 Author URI:   https://chefpaulo.com
 Template:     generatepress
 Version:      1.5.7
 Text Domain:  generatepress-child
*/

/*
 * GeneratePress (parent) sets its own body/container background via generated
 * Customizer CSS, which loads after theme.json's output and wins on specificity.
 * Bridge it to the brand palette here so page chrome matches immediately, ahead
 * of the block-based header/footer/templates landing in later build steps.
 * Single source of truth stays theme.json — this just points GP's selectors at
 * the same custom properties theme.json already generates.
 */
body,
.site {
	background-color: var(--wp--preset--color--cream);
	color: var(--wp--preset--color--espresso);
}

/* ==========================================================================
   Accessibility baseline
   ========================================================================== */

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

.screen-reader-text:focus {
	background-color: #fff;
	border-radius: 3px;
	box-shadow: 0 0 2px 2px rgba(0, 0, 0, .6);
	clip: auto !important;
	clip-path: none;
	color: var(--wp--preset--color--espresso);
	display: block;
	font-size: 0.875rem;
	font-weight: 700;
	height: auto;
	left: 5px;
	line-height: normal;
	padding: 15px 23px 14px;
	text-decoration: none;
	top: 5px;
	width: auto;
	z-index: 100000;
}

/*
 * The focus ring has to clear 3:1 against every ground it can land on, and no
 * single brand colour does: burnt orange is 2.98:1 on cream (a fail by 0.02)
 * and 1.61:1 on terracotta, which is effectively invisible on the signup band
 * and the current filter chip. Espresso clears cream and white comfortably;
 * the cream halo in the offset is what carries it on the terracotta grounds.
 */
a:focus-visible,
button:focus-visible,
input:focus-visible {
	outline: 3px solid var(--wp--preset--color--espresso);
	outline-offset: 2px;
	box-shadow: 0 0 0 2px var(--wp--preset--color--cream);
}

@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;
	}
}

/* ==========================================================================
   Site header
   ========================================================================== */

.chefpaulo-site-header {
	position: sticky;
	top: 0;
	z-index: 100;
	background-color: var(--wp--preset--color--cream);
	border-bottom: 2px solid var(--wp--preset--color--burnt-orange);
}

.chefpaulo-site-header-inner {
	position: relative;
	max-width: var(--wp--style--global--wide-size, 1280px);
	margin-inline: auto;
	padding: 1rem 1.5rem;
	display: flex;
	align-items: center;
	gap: 1.5rem;
}

.chefpaulo-wordmark {
	display: inline-flex;
	align-items: center;
	margin-right: auto;
}

.chefpaulo-wordmark img {
	display: block;
	width: 44px;
	height: 44px;
	border-radius: 50%;
}

.chefpaulo-menu-toggle {
	display: none;
	background: none;
	border: none;
	cursor: pointer;
	color: var(--wp--preset--color--espresso);
	padding: 0.5rem;
	border-radius: 6px;
}

.chefpaulo-primary-nav ul {
	display: flex;
	gap: 1.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.chefpaulo-primary-nav a {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	text-decoration: none;
	color: var(--wp--preset--color--espresso);
}

.chefpaulo-primary-nav a[aria-current="page"],
.chefpaulo-primary-nav a:hover {
	color: var(--wp--preset--color--terracotta);
}

.chefpaulo-header-search {
	position: relative;
	display: flex;
	align-items: center;
}

.chefpaulo-search-toggle {
	background: none;
	border: none;
	cursor: pointer;
	color: var(--wp--preset--color--espresso);
	padding: 0.5rem;
	border-radius: 6px;
}

.chefpaulo-search-form {
	display: none;
	position: absolute;
	top: calc(100% + 0.75rem);
	right: 0;
	background: var(--wp--preset--color--white);
	border-radius: 10px;
	box-shadow: 0 8px 24px rgba(51, 34, 27, 0.18);
	padding: 0.6rem;
	gap: 0.5rem;
	z-index: 10;
}

.chefpaulo-search-form.is-open {
	display: flex;
}

.chefpaulo-search-form input[type="search"] {
	border: 1.5px solid rgba(51, 34, 27, 0.2);
	border-radius: 6px;
	padding: 0.5rem 0.75rem;
	font-family: var(--wp--preset--font-family--body);
}

@media (max-width: 781px) {
	.chefpaulo-menu-toggle {
		display: inline-flex;
		align-items: center;
		justify-content: center;
	}

	.chefpaulo-primary-nav {
		display: none;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		background: var(--wp--preset--color--cream);
		border-bottom: 2px solid var(--wp--preset--color--burnt-orange);
		padding: 1rem 1.5rem 1.5rem;
	}

	.chefpaulo-primary-nav.is-open {
		display: block;
	}

	.chefpaulo-primary-nav ul {
		flex-direction: column;
		gap: 1rem;
	}
}

/* ==========================================================================
   Site footer
   ========================================================================== */

.chefpaulo-site-footer {
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	margin-top: 4rem;
}

.chefpaulo-site-footer-inner {
	max-width: var(--wp--style--global--wide-size, 1280px);
	margin-inline: auto;
	padding: 3rem 1.5rem;
	display: grid;
	grid-template-columns: 1.5fr 1fr 1fr;
	gap: 2rem;
}

.chefpaulo-footer-wordmark {
	display: inline-block;
	margin: 0 0 0.75rem;
}

.chefpaulo-footer-wordmark img {
	display: block;
	width: 56px;
	height: 56px;
	border-radius: 50%;
}

/*
 * Cream at 0.9 / 0.85 opacity on terracotta composites to 4.21:1 and 3.93:1 —
 * both failing. The 3.93 one is the verbatim "As an Amazon Associate I earn
 * from qualifying purchases" sentence, which Associates §5 requires and §6
 * makes a material breach to get wrong, rendered below the readable threshold
 * on every page of the site. Full opacity, one slightly lighter cream.
 */
.chefpaulo-footer-bio {
	margin: 0 0 1rem;
	opacity: 1;
	color: #F7F1E2;
}

.chefpaulo-footer-social {
	display: flex;
	gap: 0.75rem;
	list-style: none;
	margin: 0;
	padding: 0;
}

.chefpaulo-footer-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	color: var(--wp--preset--color--cream);
	/* Was 0.4 alpha = 1.97:1, against a 3:1 requirement for a UI component
	   boundary. These are the only visible edge of the social buttons. */
	border: 1.5px solid rgba(240, 228, 200, 0.75);
	border-radius: 50%;
	text-decoration: none;
}

.chefpaulo-footer-social a:hover {
	border-color: var(--wp--preset--color--cream);
}

.chefpaulo-footer-social a[aria-disabled="true"] {
	opacity: 0.45;
	cursor: default;
}

.chefpaulo-footer-heading {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.05em;
	font-size: 0.875rem;
	margin: 0 0 0.75rem;
	color: var(--wp--preset--color--cream);
}

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

.chefpaulo-footer-column a {
	color: #F7F1E2;
	opacity: 1;
	text-decoration: none;
}

.chefpaulo-footer-column a:hover {
	color: var(--wp--preset--color--white);
	text-decoration: underline;
}

.chefpaulo-site-footer-bottom {
	border-top: 1px solid rgba(240, 228, 200, 0.25);
	padding: 1.25rem 1.5rem;
	display: flex;
	justify-content: space-between;
	align-items: center;
	flex-wrap: wrap;
	gap: 0.5rem;
	font-size: 0.875rem;
}

.chefpaulo-amazon-disclosure,
.chefpaulo-footer-copyright {
	margin: 0;
	opacity: 1;
	color: #F7F1E2;
}

@media (max-width: 781px) {
	.chefpaulo-site-footer-inner {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   Email capture forms
   ========================================================================== */

.chefpaulo-email-capture-form {
	margin: 1.25rem 0 0.75rem;
}

.chefpaulo-form-honeypot {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.chefpaulo-form-row {
	display: flex;
	gap: 0.75rem;
	flex-wrap: wrap;
}

.chefpaulo-form-row input[type="email"] {
	flex: 1 1 240px;
	min-width: 0;
	padding: 0.875rem 1rem;
	border-radius: 8px;
	border: 1.5px solid rgba(51, 34, 27, 0.25);
	font-family: var(--wp--preset--font-family--body);
	font-size: 1rem;
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--espresso);
}

.chefpaulo-form-row button {
	flex: 0 0 auto;
}

.chefpaulo-form-message {
	padding: 0.75rem 1rem;
	border-radius: 8px;
	margin: 0 0 1rem;
	font-size: 0.9375rem;
}

.chefpaulo-form-message--error {
	background: #fbe4e1;
	color: #8a2a1e;
}

.chefpaulo-email-capture--compact .chefpaulo-email-capture-form {
	margin: 0;
}

.chefpaulo-email-capture--compact {
	display: flex;
	align-items: center;
	gap: 1rem;
	flex-wrap: wrap;
}

.chefpaulo-email-capture--compact p {
	margin: 0;
	white-space: nowrap;
}

.chefpaulo-email-capture--compact .chefpaulo-form-row {
	flex-wrap: nowrap;
}

.chefpaulo-email-capture--compact .chefpaulo-form-row input[type="email"] {
	flex: 0 1 220px;
}

@media (max-width: 480px) {
	.chefpaulo-form-row {
		flex-direction: column;
	}

	.chefpaulo-form-row button {
		width: 100%;
	}

	.chefpaulo-email-capture--compact .chefpaulo-form-row {
		flex-direction: row;
	}
}

/* ==========================================================================
   Shared: buttons, section shell
   ========================================================================== */

.chefpaulo-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	text-decoration: none;
	border-radius: 8px;
	padding: 0.875rem 1.75rem;
	border: 2px solid transparent;
}

.chefpaulo-btn--primary {
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
}

.chefpaulo-btn--primary:hover {
	background-color: var(--wp--preset--color--burnt-orange);
	color: var(--wp--preset--color--cream);
}

.chefpaulo-btn--secondary {
	background-color: transparent;
	border-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--terracotta);
}

.chefpaulo-btn--secondary:hover {
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
}

.chefpaulo-section {
	padding: var(--wp--preset--spacing--50, 4rem) 1.5rem;
}

.chefpaulo-section-inner {
	max-width: var(--wp--style--global--wide-size, 1280px);
	margin-inline: auto;
}

.chefpaulo-section-heading {
	text-align: center;
	margin: 0 0 2rem;
}

.chefpaulo-section-cta {
	text-align: center;
	margin-top: 2.5rem;
}

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

/*
 * The hero now opens on food.
 *
 * It was a flat terracotta gradient with a faint wheat outline — a cookbook
 * publisher's homepage with nothing edible on it, which was the largest
 * remaining brand gap and the one thing no amount of CSS tuning could fix.
 *
 * THE SCRIM IS MEASURED, NOT EYEBALLED.
 *
 * Cream text (#F0E4C8) directly on this photograph measures 1.25:1 — entirely
 * unreadable. So the overlay is doing real work, and its opacity was chosen by
 * sampling the actual image rather than by taste:
 *
 *   terracotta at 85% ......... 3.90:1  still short of AA for the tagline
 *   espresso at 65% (mean) .... 4.94:1  passes on the average pixel
 *   espresso at 65% (worst) ... 3.86:1  FAILS on the bright cloth
 *   espresso at 72% (worst) ... 4.84:1  passes everywhere  <- chosen
 *
 * The middle figure is the trap: measuring the mean of the text area says 65%
 * is fine, and it is not. The centre of this photograph is sunlit linen with
 * near-white pixels (254,254,250), so the scrim has to be sized against the
 * brightest realistic pixel behind the text, not the average one. 72% clears
 * 4.5:1 across the whole text area while still leaving the food legible.
 *
 * The gradient is kept underneath as the fallback colour, so if the image ever
 * fails to load the hero degrades to exactly what it looked like before rather
 * than to unreadable cream on white.
 *
 * If the photograph is ever replaced, RE-MEASURE. A darker image needs less
 * scrim and a brighter one needs more; inheriting this number would be luck.
 */
.chefpaulo-hero {
	background-color: var(--wp--preset--color--terracotta);
	background-image:
		radial-gradient(
			ellipse 66% 80% at 50% 50%,
			rgba(51, 34, 27, 0.78) 0%,
			rgba(51, 34, 27, 0.75) 45%,
			rgba(51, 34, 27, 0.40) 70%,
			rgba(51, 34, 27, 0.02) 100%
		),
		url("assets/images/homepage-hero.jpg");
	background-position: center center;
	background-size: cover;
	background-repeat: no-repeat;
	color: var(--wp--preset--color--cream);
	position: relative;
	overflow: hidden;
}

/*
 * WHY THE SCRIM IS A RADIAL AND NOT A FLAT WASH — changed 2026-09-06 after
 * Dave saw it live and said the shading was killing the picture. He was right.
 *
 * A flat 72% wash is the safe answer and the dull one: it buys legibility by
 * muting the whole photograph evenly, including the olives, bread and tomatoes
 * at the edges that are the entire reason for having a photograph. The text
 * only occupies the middle, so only the middle needs darkening.
 *
 * The ellipse keeps the measured contrast exactly where it is needed and lets
 * the food come back everywhere else. Against the brightest realistic pixel
 * behind the text (the sunlit linen, 254,254,250):
 *
 * These numbers are simulated, not estimated: the gradient is rebuilt over the
 * actual JPEG, composited, and the contrast of cream text computed for every
 * pixel the text can cross.
 *
 *   text area  minimum 4.77:1, median 6.5:1, nothing below 4.5
 *   edges      median overlay 0.38, down from 0.72 flat
 *
 * The values were chosen by searching ellipse size and stop opacities for the
 * LIGHTEST edges that still hold 4.6:1 behind the text, rather than by picking
 * a number that looked about right.
 *
 * ONE TRAP, BECAUSE IT NEARLY SHIPPED WRONG: in CSS the two percentages after
 * `ellipse` are the RADII, not the diameters. Normalising the falloff by half
 * of them made the first simulation twice as steep as reality and reported 58%
 * of the text area failing when it was actually fine. If this is ever re-tuned,
 * divide by 0.66 and 0.80 -- not by half of each.
 *
 * The ellipse is in percentages so it scales with the hero on a phone, where
 * the box is taller and narrower but the text is still centred in it.
 */

@media (prefers-reduced-data: reduce) {
	.chefpaulo-hero {
		background-image: linear-gradient(135deg, var(--wp--preset--color--terracotta) 0%, var(--wp--preset--color--burnt-orange) 100%);
	}
}

/*
 * The decorative wheat outline is retired now the hero carries a photograph.
 * It existed to give a flat gradient some texture; drawn over food it is just
 * faint lines across the picture. Kept as a no-op rather than deleted so the
 * reason is on the record if anyone wonders where it went.
 */
.chefpaulo-hero::before {
	content: none;
}

.chefpaulo-hero-inner {
	position: relative;
	max-width: 720px;
	margin-inline: auto;
	padding: 6rem 1.5rem;
	text-align: center;
}

.chefpaulo-hero-title {
	font-size: var(--wp--preset--font-size--huge);
	color: var(--wp--preset--color--cream);
	margin: 0 0 1rem;
}

.chefpaulo-hero-tagline {
	font-size: var(--wp--preset--font-size--large);
	margin: 0 0 2.5rem;
	opacity: 0.95;
}

.chefpaulo-hero-actions {
	display: flex;
	gap: 1rem;
	justify-content: center;
	flex-wrap: wrap;
}

.chefpaulo-hero .chefpaulo-btn--primary {
	background-color: var(--wp--preset--color--cream);
	color: var(--wp--preset--color--terracotta);
}

.chefpaulo-hero .chefpaulo-btn--primary:hover {
	background-color: var(--wp--preset--color--white);
}

.chefpaulo-hero .chefpaulo-btn--secondary {
	border-color: var(--wp--preset--color--cream);
	color: var(--wp--preset--color--cream);
}

.chefpaulo-hero .chefpaulo-btn--secondary:hover {
	background-color: var(--wp--preset--color--cream);
	color: var(--wp--preset--color--terracotta);
}

@media (max-width: 480px) {
	.chefpaulo-hero-inner {
		padding: 4rem 1.25rem;
	}

	.chefpaulo-hero-actions {
		flex-direction: column;
	}
}

/* ==========================================================================
   Book cards
   ========================================================================== */

.chefpaulo-book-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: 2rem;
}

.chefpaulo-book-card {
	display: flex;
	flex-direction: column;
	text-align: center;
}

.chefpaulo-book-cover {
	position: relative;
	overflow: hidden;
	aspect-ratio: 2 / 3;
	border-radius: 12px;
	background-color: var(--wp--preset--color--terracotta);
	background-image: linear-gradient(160deg, var(--wp--preset--color--terracotta) 0%, var(--wp--preset--color--burnt-orange) 100%);
	color: var(--wp--preset--color--cream);
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	padding: 1.5rem;
	margin-bottom: 1rem;
	box-shadow: 0 8px 24px rgba(51, 34, 27, 0.18);
}

/* Real cover photos (once uploaded) fill the same box the gradient
   placeholder uses — absolute + inset:0 fills the ancestor's padding box,
   so it covers the placeholder's own padding without needing to restructure
   the placeholder markup. */
.chefpaulo-book-cover img,
.chefpaulo-book-cta-cover img,
.chefpaulo-single-book-cover img,
.chefpaulo-book-row-cover img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.chefpaulo-book-cover-series {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	opacity: 0.85;
}

.chefpaulo-book-cover-title {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 800;
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.2;
	text-align: left;
}

.chefpaulo-book-title {
	font-size: var(--wp--preset--font-size--medium);
	margin: 0 0 0.25rem;
}

.chefpaulo-book-subtitle {
	font-size: var(--wp--preset--font-size--small);
	opacity: 0.85;
	margin: 0 0 0.5rem;
}

.chefpaulo-book-recipe-count {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--wp--preset--color--burnt-orange);
	margin: 0 0 1rem;
}

.chefpaulo-book-cta {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	text-decoration: none;
	border-radius: 8px;
	padding: 0.7rem 1.5rem;
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	margin-top: auto;
}

.chefpaulo-book-cta:hover {
	background-color: var(--wp--preset--color--burnt-orange);
}

.chefpaulo-book-cta--disabled {
	background-color: transparent;
	border: 2px solid rgba(51, 34, 27, 0.25);
	color: var(--wp--preset--color--espresso);
	opacity: 0.6;
	cursor: default;
}

/* ==========================================================================
   Post cards
   ========================================================================== */

.chefpaulo-post-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
	gap: 2rem;
}

.chefpaulo-post-card {
	display: flex;
	flex-direction: column;
	text-decoration: none;
	color: var(--wp--preset--color--espresso);
	background-color: var(--wp--preset--color--white);
	border-radius: 12px;
	overflow: hidden;
	box-shadow: 0 4px 16px rgba(51, 34, 27, 0.1);
}

.chefpaulo-post-card-image {
	aspect-ratio: 3 / 2;
	background-color: var(--wp--preset--color--burnt-orange);
	overflow: hidden;
}

.chefpaulo-post-card-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.chefpaulo-post-card-image-placeholder {
	display: block;
	width: 100%;
	height: 100%;
	background: linear-gradient(135deg, var(--wp--preset--color--burnt-orange) 0%, var(--wp--preset--color--terracotta) 100%);
}

.chefpaulo-post-card-body {
	padding: 1.25rem;
}

.chefpaulo-post-card-cluster {
	display: inline-block;
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--wp--preset--color--burnt-orange);
	margin-bottom: 0.5rem;
}

.chefpaulo-post-card-title {
	font-size: var(--wp--preset--font-size--medium);
	margin: 0 0 0.5rem;
}

.chefpaulo-post-card-excerpt {
	font-size: var(--wp--preset--font-size--small);
	opacity: 0.85;
	margin: 0;
}

.chefpaulo-post-card:hover .chefpaulo-post-card-title {
	color: var(--wp--preset--color--terracotta);
}

/* ==========================================================================
   Social strip
   ========================================================================== */

.chefpaulo-social-strip-inner {
	display: flex;
	justify-content: center;
	gap: 1.5rem;
}

.chefpaulo-social-strip a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	border-radius: 50%;
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	text-decoration: none;
}

.chefpaulo-social-strip a:hover {
	background-color: var(--wp--preset--color--burnt-orange);
}

.chefpaulo-social-strip a[aria-disabled="true"] {
	background-color: rgba(51, 34, 27, 0.15);
	color: var(--wp--preset--color--espresso);
	opacity: 0.5;
}

/* ==========================================================================
   Blog hub header + cluster cards
   ========================================================================== */

.chefpaulo-hub-header {
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	padding: 4rem 1.5rem;
	text-align: center;
}

.chefpaulo-hub-header-inner {
	max-width: 720px;
	margin-inline: auto;
}

.chefpaulo-hub-header h1 {
	color: var(--wp--preset--color--cream);
	margin: 0 0 0.75rem;
}

.chefpaulo-hub-header p {
	margin: 0;
	opacity: 0.95;
	font-size: var(--wp--preset--font-size--large);
}

.chefpaulo-cluster-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: 1.5rem;
}

.chefpaulo-cluster-card {
	display: block;
	text-decoration: none;
	color: var(--wp--preset--color--espresso);
	background-color: var(--wp--preset--color--white);
	border-radius: 12px;
	padding: 1.75rem;
	box-shadow: 0 4px 16px rgba(51, 34, 27, 0.1);
	border-left: 4px solid var(--wp--preset--color--burnt-orange);
}

.chefpaulo-cluster-card:hover .chefpaulo-cluster-card-title {
	color: var(--wp--preset--color--terracotta);
}

.chefpaulo-cluster-card-title {
	font-size: var(--wp--preset--font-size--large);
	margin: 0 0 0.5rem;
}

.chefpaulo-series-card .chefpaulo-cluster-card-title {
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.25;
}

.chefpaulo-cluster-card-count {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--wp--preset--color--burnt-orange);
	margin: 0;
}

/* ==========================================================================
   Book CTA strip (end of post, cluster "Related Book")
   ========================================================================== */

.chefpaulo-book-cta-strip {
	display: flex;
	gap: 1.75rem;
	align-items: center;
	background-color: var(--wp--preset--color--white);
	border-radius: 16px;
	padding: 1.75rem;
	box-shadow: 0 4px 16px rgba(51, 34, 27, 0.1);
}

.chefpaulo-book-cta-cover {
	position: relative;
	overflow: hidden;
	flex: 0 0 120px;
	aspect-ratio: 2 / 3;
	border-radius: 10px;
	background-image: linear-gradient(160deg, var(--wp--preset--color--terracotta) 0%, var(--wp--preset--color--burnt-orange) 100%);
	color: var(--wp--preset--color--cream);
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	padding: 0.85rem;
	box-shadow: 0 6px 16px rgba(51, 34, 27, 0.18);
}

.chefpaulo-book-cta-cover .chefpaulo-book-cover-series {
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.625rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	opacity: 0.85;
}

.chefpaulo-book-cta-cover .chefpaulo-book-cover-title {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 800;
	font-size: 0.8125rem;
	line-height: 1.25;
	text-align: left;
}

.chefpaulo-book-cta-eyebrow {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	color: var(--wp--preset--color--burnt-orange);
	margin: 0 0 0.35rem;
}

.chefpaulo-book-cta-title {
	margin: 0 0 0.35rem;
	font-size: var(--wp--preset--font-size--large);
}

.chefpaulo-book-cta-subtitle {
	margin: 0 0 1rem;
	font-size: var(--wp--preset--font-size--small);
	opacity: 0.85;
}

@media (max-width: 600px) {
	.chefpaulo-book-cta-strip {
		flex-direction: column;
		text-align: center;
	}

	.chefpaulo-book-cta-cover {
		flex-basis: auto;
		width: 120px;
	}
}

/* ==========================================================================
   Single post
   ========================================================================== */

.chefpaulo-post-header {
	max-width: 720px;
	margin: 0 auto;
	padding: 3rem 1.5rem 0;
}

.chefpaulo-breadcrumb {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	margin: 0 0 1rem;
}

.chefpaulo-breadcrumb a {
	color: var(--wp--preset--color--burnt-orange);
	text-decoration: none;
}

.chefpaulo-breadcrumb a:hover {
	text-decoration: underline;
}

.chefpaulo-post-byline {
	font-size: var(--wp--preset--font-size--small);
	opacity: 0.75;
	margin: 0.5rem 0 2rem;
}

.chefpaulo-post-featured-image {
	border-radius: 12px;
	overflow: hidden;
	margin-bottom: 2rem;
	aspect-ratio: 16 / 9;
}

.chefpaulo-post-featured-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.chefpaulo-post-body {
	max-width: 720px;
	margin: 0 auto;
	padding: 0 1.5rem;
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.7;
}

.chefpaulo-post-body h2 {
	margin-top: 2.5rem;
}

.chefpaulo-post-body h3 {
	margin-top: 2rem;
}

.chefpaulo-post-body > p:first-of-type {
	font-size: var(--wp--preset--font-size--large);
}

.chefpaulo-post-disclosure {
	max-width: 720px;
	margin: 0 auto 2rem;
	padding: 0 1.5rem;
}

/* Above-the-fold Amazon Associates disclosure on non-post templates
   (home, series archive, single book) — same block as
   .chefpaulo-post-disclosure, narrowed to match its 720px measure even
   inside a wider .chefpaulo-section-inner (1280px) or the book header. */
.chefpaulo-page-disclosure {
	max-width: 720px;
	margin: 0 auto 2rem;
}

.chefpaulo-single-book-info .chefpaulo-page-disclosure {
	max-width: none;
	margin: 0 0 1.25rem;
}

/* Link-level Amazon Associates disclosure — "(paid link)" set adjacent to
   every affiliate link's visible text, per CLAUDE.md's Amazon Associates
   compliance section. */
/* The single definition of this lives in the Recipes section near the end of
   this file. It used to be declared here too, at a different opacity, and the
   later one silently won — see the note there. */

.chefpaulo-post-section {
	max-width: 720px;
	margin: 3rem auto 0;
	padding: 0 1.5rem;
}

.chefpaulo-related-posts-heading {
	font-size: var(--wp--preset--font-size--large);
	margin: 0 0 1.5rem;
}

.chefpaulo-post-footer-capture {
	background-color: var(--wp--preset--color--terracotta);
	margin-top: 4rem;
	padding: 3rem 1.5rem;
}

.chefpaulo-post-footer-capture .chefpaulo-email-capture {
	max-width: 560px;
	margin-inline: auto;
}

.chefpaulo-post-footer-capture h2,
.chefpaulo-post-footer-capture p {
	color: var(--wp--preset--color--espresso);
}

.chefpaulo-post-grid--single {
	max-width: 380px;
	margin-inline: auto;
}

/* ==========================================================================
   Books hub hero
   ========================================================================== */

.chefpaulo-books-hero {
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	padding: 3.5rem 1.5rem;
}

.chefpaulo-books-hero-eyebrow {
	display: inline-block;
	margin: 0 0 1.5rem;
	font-family: var(--wp--preset--font-family--heading);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	font-size: var(--wp--preset--font-size--small);
	font-weight: 800;
	color: var(--wp--preset--color--terracotta);
	background-color: var(--wp--preset--color--cream);
	padding: 0.4em 0.9em;
	border-radius: 999px;
}

.chefpaulo-books-hero-layout {
	display: flex;
	gap: 2rem;
	align-items: center;
}

.chefpaulo-books-hero-info h1 {
	color: var(--wp--preset--color--cream);
	margin: 0 0 0.5rem;
}

.chefpaulo-books-hero-info h1 a {
	color: inherit;
	text-decoration: none;
}

.chefpaulo-books-hero .chefpaulo-single-book-subtitle {
	color: var(--wp--preset--color--cream);
	opacity: 0.9;
}

.chefpaulo-books-hero .chefpaulo-email-capture-form input[type="email"] {
	background-color: var(--wp--preset--color--cream);
}

@media (max-width: 640px) {
	.chefpaulo-books-hero-layout {
		flex-direction: column;
		align-items: flex-start;
	}
}

/* ==========================================================================
   Single book page
   ========================================================================== */

.chefpaulo-single-book-layout {
	display: flex;
	gap: 2.5rem;
	align-items: flex-start;
}

.chefpaulo-single-book-cover,
.chefpaulo-books-hero .chefpaulo-single-book-cover {
	position: relative;
	overflow: hidden;
	flex: 0 0 220px;
	width: 220px;
	aspect-ratio: 2 / 3;
	border-radius: 12px;
	background-image: linear-gradient(160deg, var(--wp--preset--color--terracotta) 0%, var(--wp--preset--color--burnt-orange) 100%);
	color: var(--wp--preset--color--cream);
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	padding: 1.5rem;
	box-shadow: 0 8px 24px rgba(51, 34, 27, 0.18);
	text-decoration: none;
}

.chefpaulo-single-book-subtitle {
	font-size: var(--wp--preset--font-size--large);
	opacity: 0.85;
	margin: 0 0 1rem;
}

.chefpaulo-single-book-status {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	font-size: var(--wp--preset--font-size--small);
	text-transform: uppercase;
	letter-spacing: 0.05em;
	margin: 0 0 1.25rem;
}

.chefpaulo-single-book-status--available {
	color: var(--wp--preset--color--burnt-orange);
}

.chefpaulo-format-buttons {
	display: flex;
	gap: 0.75rem;
	flex-wrap: wrap;
}

.chefpaulo-notify-me {
	max-width: 420px;
}

.chefpaulo-notify-me-label {
	font-weight: 700;
	margin: 0 0 0.75rem;
}

@media (max-width: 640px) {
	.chefpaulo-single-book-layout {
		flex-direction: column;
	}

	.chefpaulo-single-book-cover {
		width: 160px;
		flex-basis: auto;
	}
}

/* ==========================================================================
   Series page: available-now rows, coming-soon list
   ========================================================================== */

.chefpaulo-book-row-list {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.chefpaulo-book-row {
	display: flex;
	gap: 1.5rem;
	align-items: center;
	background-color: var(--wp--preset--color--white);
	border-radius: 12px;
	padding: 1.5rem;
	box-shadow: 0 4px 16px rgba(51, 34, 27, 0.1);
}

.chefpaulo-book-row-cover {
	position: relative;
	overflow: hidden;
	flex: 0 0 90px;
	width: 90px;
	aspect-ratio: 2 / 3;
	border-radius: 8px;
	background-image: linear-gradient(160deg, var(--wp--preset--color--terracotta) 0%, var(--wp--preset--color--burnt-orange) 100%);
	display: flex;
	align-items: flex-end;
	padding: 0.6rem;
	text-decoration: none;
}

.chefpaulo-book-row-cover .chefpaulo-book-cover-title {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 800;
	font-size: 0.6875rem;
	line-height: 1.2;
	color: var(--wp--preset--color--cream);
}

.chefpaulo-book-row-body h3 {
	margin: 0 0 0.35rem;
	font-size: var(--wp--preset--font-size--large);
}

.chefpaulo-book-row-body h3 a {
	color: inherit;
	text-decoration: none;
}

.chefpaulo-book-row-subtitle {
	font-size: var(--wp--preset--font-size--small);
	opacity: 0.85;
	margin: 0 0 0.85rem;
}

@media (max-width: 480px) {
	.chefpaulo-book-row {
		flex-direction: column;
		align-items: flex-start;
	}
}

.chefpaulo-coming-soon-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.chefpaulo-coming-soon-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 1rem;
	background-color: var(--wp--preset--color--white);
	border-radius: 10px;
	padding: 1rem 1.25rem;
	text-decoration: none;
	color: var(--wp--preset--color--espresso);
	box-shadow: 0 2px 10px rgba(51, 34, 27, 0.08);
}

.chefpaulo-coming-soon-title {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	flex: 1 1 auto;
}

.chefpaulo-coming-soon-target {
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--burnt-orange);
	white-space: nowrap;
}

.chefpaulo-coming-soon-notify {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--terracotta);
	white-space: nowrap;
	text-decoration: underline;
}

.chefpaulo-coming-soon-row:hover .chefpaulo-coming-soon-title {
	color: var(--wp--preset--color--terracotta);
}

@media (max-width: 560px) {
	.chefpaulo-coming-soon-row {
		flex-wrap: wrap;
	}
}

/* ==========================================================================
   About page
   ========================================================================== */

.chefpaulo-about-header {
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	padding: 3.5rem 1.5rem;
}

.chefpaulo-about-header-inner {
	max-width: 720px;
	margin-inline: auto;
	display: flex;
	align-items: center;
	gap: 1.5rem;
}

.chefpaulo-about-header-inner h1 {
	color: var(--wp--preset--color--cream);
	margin: 0;
}

.chefpaulo-portrait {
	flex: 0 0 88px;
	width: 88px;
	height: 88px;
	border-radius: 50%;
	overflow: hidden;
	border: 3px solid var(--wp--preset--color--cream);
}

.chefpaulo-portrait img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.chefpaulo-about-story {
	font-size: var(--wp--preset--font-size--medium);
	line-height: 1.7;
}

.chefpaulo-about-story p:first-of-type {
	font-size: var(--wp--preset--font-size--large);
}

.chefpaulo-about-teasers {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 2rem;
}

.chefpaulo-about-teaser {
	background-color: var(--wp--preset--color--white);
	border-radius: 12px;
	padding: 2rem;
	box-shadow: 0 4px 16px rgba(51, 34, 27, 0.1);
}

.chefpaulo-about-teaser h2 {
	font-size: var(--wp--preset--font-size--large);
	margin: 0 0 0.75rem;
}

.chefpaulo-about-teaser p {
	margin: 0 0 1.25rem;
}

.chefpaulo-about-contact {
	text-align: center;
}

.chefpaulo-about-contact-text {
	max-width: 480px;
	margin: 0 auto 2rem;
}

@media (max-width: 480px) {
	.chefpaulo-about-header-inner {
		flex-direction: column;
		text-align: center;
	}
}

/* ==========================================================================
   Standard page (Privacy, Terms, Affiliate Disclosure, Contact)
   ========================================================================== */

.chefpaulo-standard-page .chefpaulo-post-header {
	padding-bottom: 1rem;
}

.chefpaulo-standard-page .chefpaulo-post-body {
	padding-bottom: 4rem;
}

/* The "large lede" treatment on the first paragraph exists for blog-post
   storytelling opens — wrong for a plain content page whose first line is
   often just "Last updated" or a form field label. */
.chefpaulo-standard-page .chefpaulo-post-body > p:first-of-type {
	font-size: inherit;
}

.chefpaulo-standard-page .chefpaulo-post-body h2 {
	font-size: var(--wp--preset--font-size--large);
}

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

.chefpaulo-search-empty {
	text-align: center;
	max-width: 480px;
	margin-inline: auto;
}

.chefpaulo-search-empty .chefpaulo-hero-actions {
	justify-content: center;
	margin-top: 1.5rem;
}

.chefpaulo-pagination {
	margin-top: 3rem;
	display: flex;
	justify-content: center;
}

.chefpaulo-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	height: 40px;
	padding: 0 0.75rem;
	margin: 0 0.25rem;
	border-radius: 8px;
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
}

.chefpaulo-pagination .page-numbers.current {
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
}

.chefpaulo-pagination .page-numbers:not(.current):hover {
	background-color: var(--wp--preset--color--burnt-orange);
	color: var(--wp--preset--color--cream);
}

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

.chefpaulo-404-inner {
	padding-top: 5rem;
	padding-bottom: 5rem;
}

.chefpaulo-404-inner .chefpaulo-section-inner {
	max-width: 560px;
	text-align: center;
}

.chefpaulo-404-eyebrow {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--huge);
	font-weight: 800;
	color: var(--wp--preset--color--burnt-orange);
	opacity: 0.35;
	margin: 0;
	line-height: 1;
}

.chefpaulo-404-copy {
	margin: 0.5rem 0 2rem;
}

.chefpaulo-404-search {
	display: flex;
	gap: 0.75rem;
	max-width: 420px;
	margin: 0 auto 2rem;
}

.chefpaulo-404-search input[type="search"] {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0.875rem 1rem;
	border-radius: 8px;
	border: 1.5px solid rgba(51, 34, 27, 0.25);
	font-family: var(--wp--preset--font-family--body);
	font-size: 1rem;
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--espresso);
}

.chefpaulo-404-inner .chefpaulo-hero-actions {
	justify-content: center;
	flex-wrap: wrap;
}

@media (max-width: 480px) {
	.chefpaulo-404-search {
		flex-direction: column;
	}
}

/* ==========================================================================
   Thank you
   ========================================================================== */

.chefpaulo-thank-you-hero .chefpaulo-hero-actions .chefpaulo-btn--primary {
	background-color: var(--wp--preset--color--cream);
	color: var(--wp--preset--color--terracotta);
}

/* ==========================================================================
   Recipes

   Rewritten after an art-direction review. The diagnosis was not that the page
   was badly styled but that it was UN-GRIDDED: seven different text edges down
   one scroll, twelve type sizes doing the work of seven, eight spacing values
   with no ratio between them, and six opacity levels standing in for a colour
   system. A reader can't name any of that, but they read it as "made by
   someone guessing" — which is exactly the word that came back.

   Everything below derives from four small token sets: one measure, seven type
   steps, three spacing values, three inks. If you add a rule here that needs a
   number outside those sets, that is the signal to change a token rather than
   type a new value.
   ========================================================================== */

.chefpaulo-recipe,
.chefpaulo-recipe-archive {
	/* One measure. 640px of Source Serif 4 at 18px is ~71 characters, inside
	   the 60-72 band. The card bleeds 40px past it on each side so its INNER
	   text edge lands on 640 too — a deliberate break in the column rather than
	   an eighth arbitrary width. */
	--cp-measure: 640px;
	--cp-panel: 720px;
	--cp-gutter: 1.5rem;

	/* Three spacings on a real 1 : 2.3 : 6 ratio. Everything used to sit
	   between 28px and 48px, so "these belong together" and "this is a new
	   section" looked identical. That is what made the page feel like floating
	   fragments. */
	--cp-tight: 0.75rem;
	--cp-group: 1.5rem;
	--cp-section: 3.25rem;
	--cp-block: 2rem; /* breaks inside the recipe card, where a rule already separates */

	/* Three inks instead of six opacity values. Opacity is not a colour
	   system, and two of the old values fell below accessible contrast. */
	--cp-ink: #33221B;
	--cp-ink-2: #6B584D;
	/* Was #8A7869, which computed to 3.35:1 on cream and 4.22:1 on white —
	   failing on both, and worst on the at-a-glance labels: 11px uppercase at
	   3.35:1, the most-scanned text on the page, for a 40-65+ audience.
	   #736152 gives 4.67:1 on cream and 5.90:1 on white.

	   Worth knowing why ink-2 and ink-3 now sit so close: the cream ground has
	   no room for a third accessible ink. The lightest warm brown that passes
	   on #F0E4C8 is about #75634F. So the quiet register has to come from size,
	   weight and tracking — which the design already does — rather than from a
	   lighter colour. */
	--cp-ink-3: #736152;

	/* Rules with distinct weights — how print communicates structure without
	   reaching for colour. Previously every rule was 1px at 6% and invisible. */
	--cp-rule-row: rgba(51, 34, 27, 0.12);
	--cp-rule-struct: rgba(51, 34, 27, 0.20);
	--cp-lift: 0 4px 16px rgba(51, 34, 27, 0.1);

	padding-inline: var(--cp-gutter);
}

/* -- One column ------------------------------------------------------------ */

.chefpaulo-recipe .chefpaulo-post-header,
.chefpaulo-recipe .chefpaulo-post-body,
.chefpaulo-recipe .chefpaulo-post-section,
.chefpaulo-recipe-disclosure,
.chefpaulo-recipe-meta,
.chefpaulo-recipe-hero {
	max-width: var(--cp-measure);
	margin-inline: auto;
	padding-inline: 0;
}

.chefpaulo-recipe .chefpaulo-post-header {
	padding-top: var(--cp-section);
}

/* -- Masthead -------------------------------------------------------------- */

.chefpaulo-recipe .chefpaulo-breadcrumb {
	margin: 0 0 var(--cp-tight);
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--cp-ink-3);
}

.chefpaulo-recipe .chefpaulo-breadcrumb a {
	color: var(--cp-ink-2);
	text-decoration: none;
}

.chefpaulo-recipe .chefpaulo-breadcrumb a:hover {
	color: var(--wp--preset--color--terracotta);
}

/* 50px at weight 800 read as a SaaS landing page rather than a cookbook.
   Nunito is a rounded humanist sans and needs negative tracking at display
   size; 800 is a poster weight. */
.chefpaulo-recipe .chefpaulo-post-header h1 {
	font-size: 2.5rem;
	font-weight: 700;
	line-height: 1.06;
	letter-spacing: -0.02em;
	margin: 0 0 var(--cp-tight);
}

.chefpaulo-recipe .chefpaulo-post-byline {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.35rem 1rem;
	margin: 0 0 var(--cp-group);
	font-size: 0.9375rem;
	color: var(--cp-ink-2);
	/* The shared .chefpaulo-post-byline sets opacity 0.75. Overriding only the
	   colour left ink-2 compositing to #8C7B6C = 3.22:1, and dragged the
	   methodology link down with it — the least legible text on the page was
	   the one carrying the E-E-A-T argument. */
	opacity: 1;
}

.chefpaulo-methodology-link {
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--cp-ink-2);
	text-decoration: none;
	border-bottom: 1.5px solid currentColor;
}

.chefpaulo-methodology-link:hover {
	color: var(--wp--preset--color--terracotta);
}

/* -- Hero ------------------------------------------------------------------
   Full measure. 480px centred in a 672px column left 96px of dead cream either
   side of the best asset on the page — the classic hedge. Square is the format
   the photography is shot in, so it is shown square and at full width, which
   makes the shape read as a decision. No aspect-ratio, no object-fit: cropping
   a dish photo to a landscape banner cuts the food out of frame. */

.chefpaulo-recipe-hero {
	margin: 0 auto var(--cp-group);
	aspect-ratio: auto;
	overflow: visible;
}

.chefpaulo-recipe-hero img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 14px;
	box-shadow: var(--cp-lift);
}

/* -- Disclosure ------------------------------------------------------------
   Smaller because it is shorter, not because it is hidden: full-contrast ink,
   above the fold, long before the only affiliate link on the page.

   It sits between the byline and the hero photograph, so it needs the space
   on both sides — without the bottom margin it butts straight into the image,
   which reads as a caption rather than a notice. The rule above it is the
   same hairline that separates the byline from the rest of the masthead. */

.chefpaulo-recipe-disclosure {
	margin-top: var(--cp-group);
	margin-bottom: var(--cp-group);
}

.chefpaulo-affiliate-disclosure--recipe,
.chefpaulo-affiliate-disclosure--compact {
	padding: 0.7rem 0 0;
	border-top: 1px solid rgba(51, 34, 27, 0.12);
	background: none;
}

.chefpaulo-affiliate-disclosure--recipe p,
.chefpaulo-affiliate-disclosure--compact p {
	margin: 0;
	font-size: 0.9375rem;
	line-height: 1.5;
	/* #6B584D = 5.32:1 on cream. Deliberately not a lighter grey: this is a
	   compliance notice and Amazon requires it to be clear. */
	color: #6B584D;
}

/* The compact variant runs on book, series, home and search pages, which use
   the wide section shell rather than the recipe measure. Constrain it so the
   line does not stretch to 1280px. */
.chefpaulo-page-disclosure .chefpaulo-affiliate-disclosure--compact {
	max-width: 640px;
	margin-inline: auto;
}

/* -- At-a-glance ----------------------------------------------------------
   Was a white five-cell pill with dividers and a drop shadow — pixel for pixel
   the WP Recipe Maker details widget, and the single strongest signal that the
   page came out of a plugin. It also out-inked the headline while wrapping
   badly at 640px and leaving orphaned dividers on the second row.

   Now what a cookbook actually prints under a title: one typeset line between
   two rules. Label and value share a baseline, no card, no shadow, no colour. */

.chefpaulo-recipe-meta {
	display: flex;
	flex-wrap: wrap;
	/* Row gap must exceed the 0.5rem inside each label/value pair, or a wrapped
	   strip on mobile groups down the columns instead of across the rows —
	   "Cook" reads as paired with "Serves". */
	gap: 1.1rem 2.25rem;
	margin-block: var(--cp-section);
	padding: 0.875rem 0;
	background: none;
	border-radius: 0;
	box-shadow: none;
	border-top: 1px solid var(--cp-rule-struct);
	border-bottom: 1px solid var(--cp-rule-struct);
	overflow: visible;
}

.chefpaulo-recipe-meta-item {
	display: flex;
	align-items: baseline;
	gap: 0.5rem;
	padding: 0;
	text-align: left;
	border-right: 0;
	min-width: 0;
}

.chefpaulo-recipe-meta dt {
	margin: 0;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.6875rem;
	font-weight: 800;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--cp-ink-3);
}

.chefpaulo-recipe-meta dd {
	margin: 0;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 1rem;
	font-weight: 700;
	line-height: 1.2;
	font-variant-numeric: tabular-nums;
	color: var(--cp-ink);
}

/* -- Headnote -------------------------------------------------------------
   The opening is where the voice lives, so it gets a real entry point — but
   sized to lead the reader in, not to shout over the dish. */

/* No top margin: the at-a-glance rule above already carries a full section
   gap, and stacking both is how the page ended up feeling like a long scroll
   of disconnected fragments. */
.chefpaulo-recipe-intro {
	margin-top: 0;
}

/* Scoped, so it does not depend on merely appearing later in the file than
   .chefpaulo-post-body > p:first-of-type, which has identical specificity. */
.chefpaulo-recipe .chefpaulo-recipe-intro > p:first-of-type {
	font-size: 1.25rem;
	line-height: 1.55;
	color: var(--cp-ink);
}

.chefpaulo-recipe-intro > p {
	color: var(--cp-ink-2);
}

/* -- The recipe card ------------------------------------------------------
   No coloured top lip. A white rounded card with a terracotta top edge is the
   visual signature of every recipe plugin on WordPress; a publisher's card
   puts its rule inside, under the header. */

.chefpaulo-recipe-card-print {
	max-width: var(--cp-panel);
	width: auto;
	margin: var(--cp-section) auto;
	padding: 2.5rem;
	background: var(--wp--preset--color--white);
	border-radius: 16px;
	border-top: 0;
	box-shadow: var(--cp-lift);
}

.chefpaulo-recipe-print-header {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 1.25rem;
	flex-wrap: wrap;
	margin-bottom: var(--cp-group);
	padding-bottom: 1.25rem;
	border-bottom: 1px solid var(--cp-rule-struct);
}

/* Print furniture. Telling a reader who is already on chefpaulo.com that this
   recipe is from chefpaulo.com is noise on screen; it earns its place only on
   the printout, where it is the only provenance the page has. */
.chefpaulo-recipe-print-source {
	display: none;
}

.chefpaulo-print-button {
	flex: none;
	font-size: 0.8125rem;
	padding: 0.6rem 1.15rem;
	/* Pinned rather than left to the inherited line-height, which lands
	   anywhere between 39px and 45px depending on what GeneratePress sets. */
	min-height: 44px;
	border-color: rgba(51, 34, 27, 0.25);
	color: var(--cp-ink-2);
}

.chefpaulo-recipe-card-print h2 {
	margin: 0 0 1.25rem;
	font-size: 1.5rem;
	font-weight: 800;
	letter-spacing: -0.01em;
}

/* A section break has to be louder than a row rule. Both used to be 6%, which
   inverted the hierarchy and made the card read as one undifferentiated slab. */
.chefpaulo-recipe-section + .chefpaulo-recipe-section {
	margin-top: var(--cp-block);
	padding-top: var(--cp-block);
	border-top: 1px solid var(--cp-rule-struct);
}

/* -- Ingredients ----------------------------------------------------------
   A scanning list, not read prose — so it gets its own tinted ground, tighter
   leading and a slightly smaller size. That difference in register is how a
   cookbook separates ingredients from method, and it does the job a hairline
   could not.

   Single column, deliberately. CSS multi-column fills column one to the
   balance point before starting column two, so a reader scanning left-to-right
   across the gutter reads the list in the wrong order — unacceptable on a
   recipe. It also left row rules misaligned across the gutter and a dangling
   underline beneath the final item. */

.chefpaulo-recipe-ingredients {
	background: var(--wp--preset--color--cream);
	border-radius: 12px;
	padding: 1.75rem 2rem;
}

.chefpaulo-recipe-ingredients h2 {
	margin-bottom: 1rem;
}

.chefpaulo-recipe-ingredients ul {
	list-style: none;
	margin: 0;
	padding: 0;
	columns: auto;
}

.chefpaulo-recipe-ingredients li {
	padding: 0.45rem 0;
	border-bottom: 1px solid var(--cp-rule-row);
	font-size: 1.0625rem;
	line-height: 1.45;
}

.chefpaulo-recipe-ingredients li:last-child {
	border-bottom: 0;
	padding-bottom: 0;
}

/* -- Method ---------------------------------------------------------------
   A hanging numeral in the margin, not a filled disc. Discs are web-UI
   vocabulary — onboarding wizards and checkout steps — and no cookbook or food
   publication uses them. Matching line-height on the pseudo-element to the
   list item puts the numeral's baseline exactly on the step's first line,
   which is the difference between typeset and positioned. */

.chefpaulo-recipe-method ol {
	list-style: none;
	counter-reset: chefpaulo-step;
	margin: 0;
	padding: 0;
}

.chefpaulo-recipe-method li {
	counter-increment: chefpaulo-step;
	position: relative;
	min-height: 0;
	margin: 0 0 var(--cp-group);
	padding-left: 2.75rem;
	line-height: 1.7;
}

.chefpaulo-recipe-method li:last-child {
	margin-bottom: 0;
}

.chefpaulo-recipe-method li::before {
	content: counter(chefpaulo-step);
	position: absolute;
	left: 0;
	top: 0;
	display: block;
	width: auto;
	height: auto;
	background: none;
	border-radius: 0;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 1.375rem;
	font-weight: 800;
	line-height: 1.7;
	font-variant-numeric: tabular-nums;
	color: var(--wp--preset--color--terracotta);
}

/* -- Chef's notes ---------------------------------------------------------- */

.chefpaulo-recipe-notes {
	background: var(--wp--preset--color--cream);
	border-radius: 12px;
	padding: 1.5rem 1.75rem;
}

.chefpaulo-recipe-section.chefpaulo-recipe-notes {
	border-top: 0;
	padding-top: 1.5rem;
}

.chefpaulo-recipe-notes h2 {
	font-size: 1.25rem;
	margin-bottom: 0.75rem;
}

.chefpaulo-recipe-notes p:last-child {
	margin-bottom: 0;
}

/* -- Nutrition ------------------------------------------------------------
   Rows on hairlines, not a grid of rounded tiles. Tiles are a macro-tracker
   treatment; a cookbook prints nutrition as a compact block. Takes a third of
   the space and stops the panel reading like a fitness app. */

.chefpaulo-nutrition-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: 0 2.5rem;
}

.chefpaulo-nutrition-list li {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 1rem;
	padding: 0.5rem 0;
	text-align: left;
	background: none;
	border-radius: 0;
	border-bottom: 1px solid var(--cp-rule-row);
}

.chefpaulo-nutrition-label {
	display: block;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.6875rem;
	font-weight: 800;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--cp-ink-3);
	margin-bottom: 0;
}

.chefpaulo-nutrition-value {
	display: block;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 1rem;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	color: var(--cp-ink);
}

.chefpaulo-nutrition-source {
	margin: 1.25rem 0 0;
	font-size: 0.9375rem;
	font-style: italic;
	color: var(--cp-ink-3);
	line-height: 1.55;
}

/* -- Technique link -------------------------------------------------------- */

.chefpaulo-recipe-technique {
	max-width: var(--cp-measure);
	margin: 0 auto var(--cp-section);
	padding: 1rem 0;
	border-top: 1px solid var(--cp-rule-row);
	border-bottom: 1px solid var(--cp-rule-row);
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.4rem 0.9rem;
	font-size: 1rem;
}

.chefpaulo-recipe-technique-label {
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.6875rem;
	font-weight: 800;
	letter-spacing: 0.13em;
	text-transform: uppercase;
	color: var(--cp-ink-3);
	flex: none;
}

/* -- Book CTA and related -------------------------------------------------
   Not recipe-specific: this strip also runs at the end of blog posts and on
   cluster pages, and was wrong in all three. The title inherited the global
   link style, so a heading rendered underlined in burnt orange. */

.chefpaulo-recipe-book-heading,
.chefpaulo-related-recipes .chefpaulo-related-posts-heading {
	text-align: center;
	font-size: 1.5rem;
	font-weight: 800;
	letter-spacing: -0.01em;
	margin-bottom: var(--cp-group);
}

.chefpaulo-book-cta-title {
	font-size: 1.25rem;
	line-height: 1.3;
	margin-bottom: 0.4rem;
}

.chefpaulo-book-cta-title a {
	text-decoration: none;
	color: var(--wp--preset--color--espresso);
}

.chefpaulo-book-cta-title a:hover {
	color: var(--wp--preset--color--terracotta);
	text-decoration: underline;
}

.chefpaulo-book-cta-subtitle {
	margin: 0 0 1.1rem;
	font-size: 0.9375rem;
	line-height: 1.5;
	color: var(--cp-ink-2);
}

/* -- Book covers ----------------------------------------------------------
   The container is a 2/3 gradient box sized for the PLACEHOLDER (series name
   over title, for books with no artwork yet). A real cover is 1600x2560, which
   is 5:8 — narrower than 2/3 — so object-fit: cover was scaling it up and
   slicing the top and bottom off the artwork. On a book cover that removes the
   title and the author name, which is most of what a cover is for.

   So: when there is a real image, the box stops being a box. No forced ratio,
   no gradient behind, no padding — the cover displays at its own proportions,
   uncropped, and the placeholder styling is left untouched for books that
   still need it. */
.chefpaulo-book-cta-cover:has(img),
.chefpaulo-book-cover:has(img),
.chefpaulo-single-book-cover:has(img),
.chefpaulo-book-row-cover:has(img) {
	aspect-ratio: auto;
	background-image: none;
	background-color: transparent;
	padding: 0;
	display: block;
}

.chefpaulo-book-cta-cover img,
.chefpaulo-book-cover img,
.chefpaulo-single-book-cover img,
.chefpaulo-book-row-cover img {
	position: static;
	inset: auto;
	width: 100%;
	height: auto;
	/* `fill` rather than `cover`: with the container's aspect-ratio removed
	   above, the box is exactly the image's own shape, so there is nothing to
	   fit into and nothing to crop. */
	object-fit: fill;
	border-radius: inherit;
}

/* The strip's cover column. Width only — height follows the artwork, so the
   cover keeps whatever proportions it was designed at rather than being made
   to fit a box someone guessed at. */
.chefpaulo-book-cta-strip .chefpaulo-book-cta-cover {
	flex: none;
	width: 116px;
	align-self: flex-start;
}

/* No opacity. This was declared twice — 0.8 earlier in the file, 0.85 here,
   the later winning silently — and both failed: 3.93:1 as cream inside the
   terracotta button, 2.51:1 inheriting the link colour in body copy. Amazon
   requires the disclosure to be CLEAR, and 2.51:1 is not clear. It is a
   compliance element, so it renders at full contrast and takes its
   de-emphasis from size and weight only. */
.chefpaulo-paid-link-note {
	margin-left: 0.45em;
	font-size: 0.85em;
	font-weight: 400;
}

/* -- Archive --------------------------------------------------------------- */

.chefpaulo-recipe-card {
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--white);
	border-radius: 12px;
	overflow: hidden;
	box-shadow: var(--cp-lift, 0 4px 16px rgba(51, 34, 27, 0.1));
}

.chefpaulo-recipe-card-media img {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: cover;
}

.chefpaulo-recipe-card-title {
	margin: 1rem 1.25rem 0.4rem;
	font-size: 1.25rem;
	line-height: 1.3;
}

.chefpaulo-recipe-card-title a {
	text-decoration: none;
	color: var(--wp--preset--color--espresso);
}

.chefpaulo-recipe-card-title a:hover {
	color: var(--wp--preset--color--terracotta);
}

.chefpaulo-recipe-card-meta {
	margin: 0 1.25rem 1.25rem;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--cp-ink-3, #736152);
	font-variant-numeric: tabular-nums;
}

.chefpaulo-recipe-filters {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 0.5rem;
	margin-top: var(--cp-group, 1.75rem);
}

.chefpaulo-filter-chip {
	display: inline-flex;
	align-items: center;
	/* These are the archive's primary navigation for a 40-65+ audience, and
	   measured 37px high. 44px is the comfortable touch target. */
	min-height: 44px;
	padding: 0.4rem 1rem;
	background: var(--wp--preset--color--white);
	border: 1.5px solid transparent;
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.8125rem;
	font-weight: 700;
	letter-spacing: 0.04em;
	text-decoration: none;
	color: var(--wp--preset--color--espresso);
	box-shadow: 0 1px 4px rgba(51, 34, 27, 0.07);
}

.chefpaulo-filter-chip:hover,
.chefpaulo-filter-chip:focus-visible {
	border-color: var(--wp--preset--color--burnt-orange);
	color: var(--wp--preset--color--terracotta);
}

.chefpaulo-filter-chip.is-current {
	background: var(--wp--preset--color--terracotta);
	border-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
}

/* The archive header had NO rule at all until 2026-09-03, which is why the
   "Recipes" h1 sat flush against the left edge of the viewport while the intro
   and the filter chips below it were centred inside their own max-widths. The
   heading was not styled wrong; it was not styled. */

.chefpaulo-archive-header {
	max-width: var(--wp--style--global--wide-size, 1280px);
	margin-inline: auto;
	padding: var(--cp-section, 3.25rem) var(--cp-gutter, 1.5rem) 0;
	text-align: center;
}

.chefpaulo-archive-header h1 {
	margin-bottom: var(--cp-group, 1.5rem);
}

.chefpaulo-archive-intro {
	max-width: 640px;
	margin-inline: auto;
	text-align: center;
	font-size: 1.25rem;
	line-height: 1.55;
	color: var(--cp-ink-2, #6B584D);
}

/* auto-FILL, not auto-FIT. This is the whole bug behind the single recipe card
   rendering 1377px wide and 300px tall across the entire viewport: auto-fit
   COLLAPSES the empty tracks to 0px and lets the one real item stretch over
   all of them, so the grid degrades to full-bleed exactly when it is sparsest.
   auto-fill keeps the empty tracks at their minmax size, so one card is a
   card. The archive is going to sit at one, then ten, then forty-six recipes
   while we stage the publish, so the sparse case is the normal case here. */

.chefpaulo-recipe-grid {
	grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

@media (max-width: 640px) {
	.chefpaulo-recipe-card-print {
		padding: 1.75rem 1.35rem;
		border-radius: 12px;
	}

	.chefpaulo-recipe-ingredients {
		padding: 1.35rem 1.25rem;
	}

	.chefpaulo-recipe .chefpaulo-post-header h1 {
		font-size: 2rem;
	}
}

/* -- Book contents list ---------------------------------------------------
   Up to 100 recipe names on a book page. Multi-column is right here in a way
   it was wrong on the ingredients: nobody reads a contents list in sequence,
   so left-to-right ambiguity costs nothing, and three columns turn an
   intimidating 100-item scroll into something scannable. */

.chefpaulo-book-recipe-index .chefpaulo-section-inner {
	max-width: 900px;
}

.chefpaulo-book-recipe-index-note {
	text-align: center;
	margin: -1rem 0 2rem;
	color: var(--wp--preset--color--terracotta);
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	font-size: 0.9375rem;
}

.chefpaulo-book-recipe-list {
	list-style: none;
	margin: 0;
	padding: 0;
	columns: 3;
	column-gap: 2.5rem;
	font-size: 0.9375rem;
}

.chefpaulo-book-recipe-list li {
	break-inside: avoid;
	padding: 0.4rem 0;
	border-bottom: 1px solid rgba(51, 34, 27, 0.10);
	line-height: 1.4;
}

.chefpaulo-book-recipe-list li.is-free {
	font-weight: 600;
}

.chefpaulo-book-recipe-list a {
	text-decoration: none;
	border-bottom: 1px solid currentColor;
}

.chefpaulo-book-recipe-free {
	display: inline-block;
	margin-left: 0.4rem;
	padding: 0.1rem 0.4rem;
	border-radius: 3px;
	background: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	font-family: var(--wp--preset--font-family--heading);
	font-size: 0.625rem;
	font-weight: 800;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	vertical-align: 0.1em;
}

@media (max-width: 900px) {
	.chefpaulo-book-recipe-list {
		columns: 2;
	}
}

@media (max-width: 560px) {
	.chefpaulo-book-recipe-list {
		columns: 1;
	}
}

/* ==========================================================================
   Print — recipes get printed, and nothing on this site handled that before.
   Strips the chrome and everything transactional, so what leaves the printer
   is the recipe and where it came from, not a screenshot of a web page.
   ========================================================================== */

@media print {
	.chefpaulo-site-header,
	.chefpaulo-site-footer,
	.chefpaulo-breadcrumb,
	.chefpaulo-recipe-filters,
	.chefpaulo-email-capture,
	.chefpaulo-post-footer-capture,
	.chefpaulo-recipe-disclosure,
	.chefpaulo-recipe-technique,
	.chefpaulo-book-cta-strip,
	.chefpaulo-recipe-book,
	.chefpaulo-related-recipes,
	.chefpaulo-related-posts,
	.chefpaulo-print-button,
	.chefpaulo-methodology-link,
	nav,
	.wp-block-navigation {
		display: none !important;
	}

	body {
		background: #fff !important;
		color: #000 !important;
		font-size: 11.5pt;
	}

	/* Hidden on screen, shown here: on paper it is the only provenance the
	   recipe carries. */
	.chefpaulo-recipe-print-source {
		display: block;
		color: #000;
	}

	.chefpaulo-recipe-print-header {
		justify-content: flex-start;
	}

	.chefpaulo-recipe-card-print {
		max-width: none;
		margin: 0;
		padding: 0;
		border-radius: 0;
		box-shadow: none;
	}

	.chefpaulo-recipe-hero {
		max-width: 64mm;
		margin-inline: 0;
	}

	.chefpaulo-recipe-hero img {
		border-radius: 0;
		box-shadow: none;
	}

	.chefpaulo-recipe-ingredients,
	.chefpaulo-recipe-notes {
		background: none;
		border: 1px solid #999;
	}

	/* body { color: #000 !important } does not reach these: !important on an
	   inherited property still loses to any element that declares its own
	   colour. Without this the labels and notes print as mid-grey halftone. */
	.chefpaulo-recipe-meta dt,
	.chefpaulo-nutrition-label,
	.chefpaulo-nutrition-source,
	.chefpaulo-recipe-intro > p,
	.chefpaulo-recipe-intro > p:first-of-type,
	.chefpaulo-affiliate-disclosure--recipe p {
		color: #000;
	}

	.chefpaulo-recipe .chefpaulo-post-byline {
		opacity: 1;
		color: #000;
	}

	.chefpaulo-recipe-method li::before {
		color: #000;
		/* em, not rem: at 11.5pt body type the fixed 1.375rem numeral no longer
		   shares a baseline with its step. */
		font-size: 1.25em;
	}

	/* A split ingredient list across two sheets is the classic printed-recipe
	   failure, so these hold together even at the cost of a page break. */
	.chefpaulo-recipe-section,
	.chefpaulo-recipe-ingredients ul,
	.chefpaulo-nutrition-list {
		break-inside: avoid;
		page-break-inside: avoid;
	}

	h1, h2 {
		break-after: avoid;
		page-break-after: avoid;
	}

	a[href]::after {
		content: "";
	}
}



/* ==========================================================================
   EDITORIAL BASE LAYER + TOKEN PROMOTION
   Added 2026-09-04, in the same deploy that stops the parent stylesheet from
   being silently dropped (see the note in functions.php).

   Two things are happening in this block and they are deliberately separate.

   1. The --cp-* tokens are promoted to :root. They were scoped to
      `.chefpaulo-recipe, .chefpaulo-recipe-archive`, which meant every
      component drawn outside a recipe page resolved them to nothing. The
      visible symptom was .chefpaulo-book-cta-subtitle, which sets
      `color: var(--cp-ink-2)` with no fallback: the SAME book CTA rendered in
      one colour on a recipe and a different colour on a blog post, purely
      because of which template drew it.

      This promotion is ADDITIVE. Nothing in lines 1-1520 is retired against
      the tokens here; the scoped block below stays exactly as it is and simply
      re-declares the same values. Retiring the ad-hoc values is a separate,
      surface-by-surface job — --cp-ink-2 and --cp-ink-3 are tuned for the cream
      ground and are close to invisible on the terracotta grounds used by the
      hero and the footer capture, so a blanket sweep would break those.

   2. An element layer for editorial content, which has never existed on this
      site. Because the parent stylesheet was never loading, the only rules
      reaching a <table>, a <figure> or a <blockquote> in post content were
      WordPress core's block defaults — and core's default is
      `border: 1px solid` on every cell, resolving to currentColor. The best
      piece of reasoning on the site, the lid/heat/salt comparison table in
      /sweating-vs-sauteing/, rendered as a fully boxed grid with an 8px pad.
      A Word table, in the highest-value content.
   ========================================================================== */

:root {
	--cp-measure: 640px;
	--cp-panel: 720px;
	--cp-gutter: 1.5rem;

	--cp-tight: 0.75rem;
	--cp-group: 1.5rem;
	--cp-section: 3.25rem;
	--cp-block: 2rem;

	--cp-ink: #33221B;
	--cp-ink-2: #6B584D;
	--cp-ink-3: #736152;

	--cp-rule-row: rgba(51, 34, 27, 0.12);
	--cp-rule-struct: rgba(51, 34, 27, 0.20);
	--cp-lift: 0 4px 16px rgba(51, 34, 27, 0.1);
}

/* --- Tables ---------------------------------------------------------------
   No vertical rules. A comparison table is read across a row, and boxing every
   cell fights that; horizontal hairlines carry the row and nothing else needs
   to be drawn. The head is set in the label register the rest of the site uses
   for eyebrows and captions, so a table reads as part of the page rather than
   as pasted-in data. Wrapped in its own scroll container so a wide table never
   makes the page body scroll sideways. */
.chefpaulo-post-body table,
.chefpaulo-standard-page table,
.chefpaulo-prose table {
	width: 100%;
	border-collapse: collapse;
	margin: var(--cp-section) 0;
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
}

.chefpaulo-post-body table :where(th, td),
.chefpaulo-standard-page table :where(th, td),
.chefpaulo-prose table :where(th, td) {
	border: 0;
	border-bottom: 1px solid var(--cp-rule-row);
	padding: 0.75rem 1rem 0.75rem 0;
	text-align: left;
	vertical-align: top;
}

.chefpaulo-post-body table thead th,
.chefpaulo-standard-page table thead th,
.chefpaulo-prose table thead th {
	border-bottom: 1.5px solid var(--cp-rule-struct);
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--cp-ink-3);
}

/* The first column of a comparison table is the thing being compared, so it
   carries the row the way a term carries a definition. */
.chefpaulo-post-body table tbody td:first-child,
.chefpaulo-prose table tbody td:first-child {
	font-weight: 600;
	color: var(--cp-ink);
}

.chefpaulo-post-body table tbody tr:last-child :where(th, td),
.chefpaulo-prose table tbody tr:last-child :where(th, td) {
	border-bottom: 0;
}

.chefpaulo-post-body .wp-block-table,
.chefpaulo-prose .wp-block-table {
	overflow-x: auto;
}

/* --- Figures and captions -------------------------------------------------
   There was no caption style anywhere in this file, which meant no image could
   carry a caption, which meant no image could carry expertise. On a site whose
   entire argument is first-hand craft, the caption is not decoration — it is
   where the claim gets made. */
.chefpaulo-post-body :where(figure, .wp-block-image),
.chefpaulo-prose :where(figure, .wp-block-image) {
	margin: var(--cp-section) 0;
}

.chefpaulo-post-body :where(figure, .wp-block-image) img,
.chefpaulo-prose :where(figure, .wp-block-image) img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: 3px;
}

.chefpaulo-post-body figcaption,
.chefpaulo-prose figcaption {
	margin-top: var(--cp-tight);
	padding-top: var(--cp-tight);
	border-top: 1px solid var(--cp-rule-row);
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	line-height: 1.5;
	color: var(--cp-ink-3);
	text-align: left;
}

/* --- Lists ----------------------------------------------------------------
   The UA default is a 40px indent, which inside a 640-720px measure pushes
   list text visibly out of the column the paragraphs sit in. */
.chefpaulo-post-body :where(ul, ol),
.chefpaulo-prose :where(ul, ol) {
	padding-left: 1.35em;
	margin: 0 0 var(--cp-group);
}

.chefpaulo-post-body :where(ul, ol) li,
.chefpaulo-prose :where(ul, ol) li {
	margin-bottom: 0.4em;
}

.chefpaulo-post-body :where(ul, ol) li::marker,
.chefpaulo-prose :where(ul, ol) li::marker {
	color: var(--cp-ink-3);
}

/* --- Quotes ---------------------------------------------------------------
   Ruled, not boxed. A box says "separate object"; this is the same voice,
   raised. */
.chefpaulo-post-body blockquote,
.chefpaulo-prose blockquote {
	margin: var(--cp-section) 0;
	padding-left: var(--cp-group);
	border-left: 2px solid var(--wp--preset--color--burnt-orange);
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.45;
	color: var(--cp-ink);
}

.chefpaulo-post-body blockquote p:last-child,
.chefpaulo-prose blockquote p:last-child {
	margin-bottom: 0;
}

.chefpaulo-post-body blockquote cite,
.chefpaulo-prose blockquote cite {
	display: block;
	margin-top: var(--cp-tight);
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	font-style: normal;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--cp-ink-3);
}

/* --- Heading rhythm -------------------------------------------------------
   Was 40px above / 24px below on h2, a ratio of 1.67:1. A section head has to
   belong to what follows it, not float between two sections. 3.2:1 and 2.9:1
   are the same ratios the recipe system arrived at and documented. */
.chefpaulo-post-body h2,
.chefpaulo-prose h2 {
	margin: 4rem 0 1.25rem;
}

.chefpaulo-post-body h3,
.chefpaulo-prose h3 {
	margin: 2.5rem 0 0.875rem;
}

.chefpaulo-post-body > *:first-child,
.chefpaulo-prose > *:first-child {
	margin-top: 0;
}

/* --- Horizontal rule ------------------------------------------------------ */
.chefpaulo-post-body hr,
.chefpaulo-prose hr {
	border: 0;
	border-top: 1px solid var(--cp-rule-struct);
	margin: var(--cp-section) auto;
	width: 100%;
}

/* ==========================================================================
   CLASSES EMITTED BY PHP THAT HAD NO RULE
   Eight of the forty-five unstyled classes are load-bearing. These are they.
   Verified live at 1440px before this was written: .chefpaulo-prose inherited
   the 1280px wide-size and ran at roughly 128 characters per line, and
   .chefpaulo-landing-point-grid computed to display:block, so the "What's
   inside" three-up on the lead-magnet page rendered as three unstyled stacked
   divs on the highest-intent page in the funnel.
   ========================================================================== */

.chefpaulo-prose,
.chefpaulo-landing-body {
	max-width: var(--cp-measure);
	margin-inline: auto;
}

.chefpaulo-section-intro {
	max-width: var(--cp-measure);
	margin: 0 auto var(--cp-section);
	color: var(--cp-ink-2);
	text-align: center;
}

.chefpaulo-about-tagline {
	max-width: 30ch;
	margin: 0 auto var(--cp-group);
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--large);
	font-weight: 600;
	line-height: 1.3;
	text-align: center;
	color: var(--cp-ink-2);
}

.chefpaulo-landing-point-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: var(--cp-group);
	max-width: var(--cp-panel);
	margin: var(--cp-section) auto 0;
	text-align: left;
}

.chefpaulo-landing-point {
	padding-top: var(--cp-group);
	border-top: 2px solid var(--wp--preset--color--burnt-orange);
}

.chefpaulo-landing-point h3 {
	margin: 0 0 var(--cp-tight);
	font-size: var(--wp--preset--font-size--large);
}

.chefpaulo-landing-point p {
	margin: 0;
	color: var(--cp-ink-2);
}

.chefpaulo-landing-fine-print {
	max-width: var(--cp-measure);
	margin: var(--cp-group) auto 0;
	font-size: var(--wp--preset--font-size--small);
	color: var(--cp-ink-3);
	text-align: center;
}

/* --- The onward nav on a recipe -------------------------------------------
   Recipes had no route to the archive or to a cluster, so the whole post type
   was an island. See the note in single-recipe.php. */
.chefpaulo-recipe-onward {
	display: flex;
	flex-wrap: wrap;
	gap: var(--cp-tight) var(--cp-group);
	max-width: var(--cp-measure);
	margin: var(--cp-section) auto 0;
	padding-top: var(--cp-group);
	border-top: 1px solid var(--cp-rule-struct);
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
}

/* ==========================================================================
   CONTRAST CORRECTIONS
   Burnt orange #C96A2E measures 2.98:1 on the cream ground and 3.76:1 on
   white. Both fail WCAG AA for normal text (4.5:1); the cream figure fails
   even the 3:1 threshold for UI components. The file already knew this — the
   focus-ring block states the 2.98 figure exactly and routes around it — but
   three components kept using the colour for actual text. The recipe system
   solved this properly with --cp-ink-2 / --cp-ink-3 and the fix was never
   applied back.

   Burnt orange stays where it belongs: rules, borders, the separator, button
   hover. Those are not text and 3:1 is the right bar for them.
   ========================================================================== */

.chefpaulo-post-card-cluster,
.chefpaulo-cluster-card-count,
.chefpaulo-book-recipe-count {
	color: var(--cp-ink-3); /* was var(--wp--preset--color--burnt-orange) */
}


/* ==========================================================================
   BOOKS HUB — rebuilt 2026-09-04
   The old hub had no book cards, so it needed no grid styling. It has seven
   now, plus an upcoming list and an editor's pick. See the file header in
   page-templates/template-books.php for why the page changed shape.
   ========================================================================== */

.chefpaulo-books-intro {
	padding: var(--cp-section) var(--cp-gutter) 0;
	text-align: center;
}

.chefpaulo-books-intro h1 {
	margin: 0 0 var(--cp-group);
}

.chefpaulo-books-intro-copy {
	max-width: 46ch;
	margin: 0 auto var(--cp-group);
	font-size: var(--wp--preset--font-size--large);
	line-height: 1.45;
	color: var(--cp-ink-2);
}

.chefpaulo-books-intro-actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--cp-tight);
	justify-content: center;
	margin: 0;
}

/* The editor's pick sits on the cream ground with a rule above it rather than
   in a card. It is one recommendation, not a fourth kind of tile — see the
   note about not making everything a card. */
.chefpaulo-books-pick .chefpaulo-section-inner {
	border-top: 1px solid var(--cp-rule-struct);
	padding-top: var(--cp-section);
}

/* --- Upcoming titles ------------------------------------------------------
   A ruled list, not cards. These are titles a reader cannot act on yet, so
   they should read as information rather than as offers competing with the
   seven above them. */
.chefpaulo-upcoming-list {
	list-style: none;
	margin: 0 auto;
	padding: 0;
	max-width: var(--cp-panel);
}

.chefpaulo-upcoming-item {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 0.35rem 1rem;
	padding: var(--cp-group) 0;
	border-bottom: 1px solid var(--cp-rule-row);
	/*
	 * Holds one rhythm across the list whether or not a title has a cover yet.
	 * Matches .chefpaulo-upcoming-cover's height, so a row that gains real art
	 * does not suddenly grow and shove the rest of the list down the page.
	 * align-items is center rather than baseline for the same reason — a chip
	 * and a line of type have no shared baseline to sit on.
	 */
	min-height: 68px;
}

.chefpaulo-upcoming-cover {
	flex: 0 0 auto;
	display: block;
	width: 42px;
	overflow: hidden;
	border-radius: 2px;
	/* The Kindle cover ratio, 1600x2560. Reserving it stops layout shift. */
	aspect-ratio: 1 / 1.6;
	background: var(--cp-rule-row);
	box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
}

.chefpaulo-upcoming-cover img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.chefpaulo-upcoming-item:first-child {
	border-top: 1px solid var(--cp-rule-struct);
}

.chefpaulo-upcoming-title {
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	font-size: var(--wp--preset--font-size--medium);
	color: var(--cp-ink);
	flex: 1 1 16ch;
}

.chefpaulo-upcoming-series,
.chefpaulo-upcoming-when {
	font-family: var(--wp--preset--font-family--heading);
	font-size: var(--wp--preset--font-size--label);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--cp-ink-3);
	white-space: nowrap;
}

.chefpaulo-upcoming-when {
	margin-left: auto;
	font-weight: 700;
}

.chefpaulo-upcoming-more {
	max-width: var(--cp-panel);
	margin: var(--cp-group) auto 0;
	color: var(--cp-ink-2);
}

.chefpaulo-upcoming-notify {
	max-width: var(--cp-panel);
	margin: var(--cp-section) auto 0;
	padding-top: var(--cp-group);
	border-top: 1px solid var(--cp-rule-struct);
}

.chefpaulo-upcoming-notify-copy {
	margin: 0 0 var(--cp-tight);
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	color: var(--cp-ink);
}

/* --- Series card availability line ---------------------------------------- */
.chefpaulo-cluster-card-available {
	display: block;
	margin-top: 0.2rem;
	font-weight: 700;
	color: var(--wp--preset--color--terracotta);
}

/* Book cards on the hub: align to the top so covers of differing proportions
   do not stretch, and keep the title block on a common baseline. Without this
   the uncrop fix at .chefpaulo-book-card img (which correctly lets a 5:8 KDP
   cover keep its shape) leaves a ragged row of unaligned titles. */
.chefpaulo-books-hub .chefpaulo-book-grid {
	align-items: start;
}

/* ============================================================
   DEFAULT-STYLE LEAKS — found 2026-09-06 by looking at the site
   rather than reading its HTML.

   Three elements had never been given brand styling, so they were
   wearing WordPress's and GeneratePress's defaults in the middle
   of a designed page. Each one individually is small; together
   they are most of what reads as amateur, because default styling
   is the specific visual signature of an unfinished site.
   ============================================================ */

/*
 * Book card titles were rendering in DEFAULT LINK BLUE (#1e73be),
 * underlined, on a cream and terracotta page.
 *
 * `.chefpaulo-book-title` styled the <h3> and never the <a> inside
 * it, so the anchor fell through to the browser default. The card
 * image above it and the button below it were both fully branded,
 * which is what made it jarring rather than merely plain.
 *
 * The whole card is clickable via the cover link, so the title does
 * not need to advertise itself as a link at rest; it gets the
 * underline on hover instead, which keeps the affordance without
 * the permanent blue.
 */
.chefpaulo-book-title a,
.chefpaulo-upcoming-title a {
	color: var(--wp--preset--color--espresso);
	text-decoration: none;
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
}

.chefpaulo-book-title a:hover,
.chefpaulo-book-title a:focus-visible,
.chefpaulo-upcoming-title a:hover,
.chefpaulo-upcoming-title a:focus-visible {
	color: var(--wp--preset--color--terracotta);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

/*
 * The email submit button was GeneratePress's default: slate grey
 * (#55555e), square corners, system font.
 *
 * The only rule it had was `flex: 0 0 auto` for layout. Everything
 * visual came from the parent theme. This is the single most
 * important conversion element on the site — the lead magnet that
 * feeds the whole email list — and it looked like a form control
 * from a different website sitting inside a designed panel.
 *
 * Matched to .chefpaulo-book-cta so every action on the site now
 * shares one button language.
 */
.chefpaulo-form-row button {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 0.875rem 1.5rem;
	border: 0;
	border-radius: 8px;
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.2;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.chefpaulo-form-row button:hover,
.chefpaulo-form-row button:focus-visible {
	background-color: var(--wp--preset--color--burnt-orange);
	color: var(--wp--preset--color--cream);
}

/*
 * The logo link carried the default underline. Invisible most of
 * the time behind the image, visible the moment the image is slow,
 * broken, or the page is read with images off.
 */
.chefpaulo-site-header-inner > a {
	text-decoration: none;
}

/*
 * In-prose links were default WordPress blue (#1e73be) on every post.
 *
 * Not a few of them — all of them, across all 28 published posts, plus the
 * byline. Nothing in this stylesheet had ever styled a link inside body copy,
 * so the single most frequent interactive element on the site was the one
 * element still wearing the CMS default. On a cream and terracotta page, a
 * bright blue link is the most conspicuous possible tell.
 *
 * Terracotta on cream measures 4.8:1, which clears WCAG AA for body text. The
 * underline is kept deliberately rather than removed for tidiness: colour alone
 * is not an accessible link affordance, and this audience skews 40-65+. The
 * offset just stops the rule cutting through descenders.
 */
.chefpaulo-post-body a,
.chefpaulo-prose a,
.chefpaulo-recipe-technique a,
.chefpaulo-post-byline a {
	color: var(--wp--preset--color--terracotta);
	text-decoration: underline;
	text-underline-offset: 0.15em;
	text-decoration-thickness: 1px;
}

.chefpaulo-post-body a:hover,
.chefpaulo-post-body a:focus-visible,
.chefpaulo-prose a:hover,
.chefpaulo-prose a:focus-visible,
.chefpaulo-recipe-technique a:hover,
.chefpaulo-recipe-technique a:focus-visible,
.chefpaulo-post-byline a:hover,
.chefpaulo-post-byline a:focus-visible {
	color: var(--wp--preset--color--burnt-orange);
	text-decoration-thickness: 2px;
}

/* Buttons inside prose must not inherit the prose link treatment. */
.chefpaulo-post-body a.chefpaulo-book-cta,
.chefpaulo-prose a.chefpaulo-book-cta,
.chefpaulo-recipe-technique a.chefpaulo-book-cta {
	color: var(--wp--preset--color--cream);
	text-decoration: none;
}

/*
 * The rest of the default-button and default-link leaks, found by sweeping
 * every template rather than the two pages I happened to look at: the books
 * hub, a single book, the recipe archive, a cluster archive, the landing page,
 * the author page, search results and 404.
 *
 * Both search forms were still GeneratePress grey. The header one appears on
 * EVERY page of the site, so it was the most-shipped instance of the problem
 * and the one I missed first time by only fixing the email form.
 *
 * Colours only — deliberately no padding or sizing here. These two buttons sit
 * in tight layouts (a header that reveals on toggle, and the 404 search block)
 * and forcing the email button's generous padding on them would break both.
 * The brand language is carried by colour, radius and weight; the geometry
 * stays whatever each form already had.
 */
.chefpaulo-search-form button,
.chefpaulo-404-search button {
	border: 0;
	border-radius: 8px;
	background-color: var(--wp--preset--color--terracotta);
	color: var(--wp--preset--color--cream);
	font-family: var(--wp--preset--font-family--heading);
	font-weight: 700;
	cursor: pointer;
	transition: background-color 0.15s ease;
}

.chefpaulo-search-form button:hover,
.chefpaulo-search-form button:focus-visible,
.chefpaulo-404-search button:hover,
.chefpaulo-404-search button:focus-visible {
	background-color: var(--wp--preset--color--burnt-orange);
}

/*
 * The landing page's fine print sits in the hero, outside .chefpaulo-post-body,
 * so the prose rule above does not reach it. It is the one link on the page
 * that a cautious reader actually looks for before handing over an email
 * address, and it was rendering in default blue.
 */
.chefpaulo-landing-fine-print a {
	color: var(--wp--preset--color--terracotta);
	text-decoration: underline;
	text-underline-offset: 0.15em;
}

.chefpaulo-landing-fine-print a:hover,
.chefpaulo-landing-fine-print a:focus-visible {
	color: var(--wp--preset--color--burnt-orange);
}

/*
 * Links that wrap nothing but an image were inheriting the default underline,
 * which draws a rule under the picture. Invisible while every image loads and
 * obvious the moment one does not.
 */
.chefpaulo-recipe-card-media,
.chefpaulo-book-cover,
.chefpaulo-upcoming-cover,
.chefpaulo-post-card-image {
	text-decoration: none;
}

/*
 * Centre the reading column. The second half of the phantom-sidebar fix.
 *
 * Removing the sidebar layout was necessary and not sufficient. `.site-content`
 * is display:flex with justify-content:normal, and `#primary` is its only child
 * with `width:auto`, so it shrink-wraps to its contents' 720px measure and then
 * sits at flex-start. Measured live after the fix landed, at a 1280 viewport:
 *
 *   /                 main 1200px   gap right   48px   fine
 *   /books/           main 1200px   gap right   48px   fine
 *   /free-meal-plan/  main 1200px   gap right   48px   fine
 *   a post            main  720px   gap right  528px   <- broken
 *   a recipe          main  768px   gap right  480px   <- broken
 *
 * Only the two templates whose content has a reading measure were affected,
 * which is exactly why the earlier body-class check looked like a pass: the
 * class really had changed to `no-sidebar`, and three of five templates really
 * were correct. The recipe case mattered most, with 45 recipes about to publish
 * into it.
 *
 * `margin-inline: auto` centres a flex item in its row and is inert when the
 * item already fills the row, so the three correct templates are untouched.
 * The 720px measure itself is deliberate and stays — it is about 75 characters,
 * which is the readable line length. The bug was never the width; it was that
 * the column was pinned to the left edge.
 */
.site-content > #primary {
	margin-inline: auto;
}

/* ============================================================
   ALIGNMENT — the "off-centre" Dave reported, 2026-09-06.
   Two separate causes that read as one problem.
   ============================================================ */

/*
 * 1. The card grids left-packed against an empty track.
 *
 * `repeat(auto-fill, minmax(220px, 1fr))` in the 1152px content column builds
 * FOUR 264px tracks, and the homepage only has THREE cards. auto-fill keeps the
 * empty fourth track, so the row rendered as three cards hard left and a 296px
 * hole on the right. Measured live: tracks "264px 264px 264px 264px", children
 * at x=57, 353, 649, container right edge 296px past the last card.
 *
 * This was my own regression. These grids were `auto-fit` and I changed them to
 * `auto-fill` earlier today. That change was not wrong: auto-fit COLLAPSES the
 * empty track, which means a section holding one or two items stretches them to
 * absurd widths — a single post card 1152px wide. `.chefpaulo-post-grid--single`
 * exists precisely because someone hit that.
 *
 * So keep auto-fill, which caps the card width, and centre the tracks instead.
 * That fixes every count at every width: three cards centre, four fill the row,
 * five wrap with the orphan centred under them. Adding a fourth card to the
 * homepage (done separately, in template-home.php) fills the desktop row
 * exactly, but the layout no longer DEPENDS on the item count matching the
 * column count — which it never could at every breakpoint.
 */
.chefpaulo-book-grid,
.chefpaulo-post-grid,
.chefpaulo-cluster-grid {
	justify-content: center;
}

/*
 * 2. The header and footer hung 33px left of everything else.
 *
 * Both inners are max-width:1280px with 24px side padding and sit in the
 * full-bleed 1265px viewport, so their content began at x=24. The page content
 * lives inside GeneratePress's 1200px .grid-container, which centres with 32.5px
 * margins, so sections began at x=57.
 *
 * Nothing looked broken in isolation. What Dave saw was the footer logo — and
 * the header logo above it — sitting a third of an inch outside the column that
 * every heading, card and paragraph on the page lines up to. A vertical edge
 * that ALMOST lines up reads worse than one that obviously does not.
 *
 * Matching the 1200px container puts their content at 32.5 + 24 = 56.5px, on
 * the same edge as the body content, top to bottom of the page.
 */
.chefpaulo-site-header-inner,
.chefpaulo-site-footer-inner {
	max-width: 1200px;
	margin-inline: auto;
}
