/*
Theme Name: MS Recipes
Theme URI: https://github.com/sebmouad/MS-Recipes-Theme
Author: MS
Description: A lean, clean recipe-blog theme inspired by Astra's structural conventions (simple container system, minimal header builder) but purpose-built for recipe content: warm editorial design, zero custom JavaScript, system fonts only, and every image/CSS/JS delivery decision left to the MS Turbo Cache / MS Image Optimizer plugin pair it's designed to run alongside.
Version: 2.2.0
Requires at least: 6.1
Requires PHP: 7.4
Tested up to: 6.7
Text Domain: ms-recipes
Tags: food-and-drink, blog, custom-logo, custom-menu, featured-images, threaded-comments, translation-ready, block-styles, wide-blocks, editor-style, sticky-post
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Performance/integration notes (see README.md for the full rationale):
- No @font-face: the type stack is 100% OS-bundled fonts, so there is never
  a font network request, FOIT/FOUT, or font-swap layout shift.
- No theme JavaScript: the responsive nav is a pure-CSS checkbox toggle
  (a visually-hidden, focusable checkbox whose label is the hamburger),
  not a JS-driven toggle — zero risk of the "first tap does nothing" bug
  that a JS-delay plugin can cause on a scripted hamburger menu.
- Featured/content images are rendered with plain the_post_thumbnail() /
  the_content() calls and no src/srcset/sizes/loading overrides — MS Image
  Optimizer and MS Turbo Cache own every one of those attributes via their
  own filters, and setting them here would fight (or silently break) that.
- Structured data / meta tags only when no SEO plugin is active (inc/seo.php
  detects MS SEO Plus + Yoast/Rank Math/AIOSEO/SEOPress/TSF): with one present
  the theme emits nothing, so it never duplicates or conflicts.
*/

/* =====================================================================
   1. Design tokens
   Palette deliberately harmonises with MS Recipe Card's own inline
   styling (warm cream #faf7f2 card head, amber #e8a33d stars, #e1e8ed /
   #d5c9b4 borders, 12px radius, 0 1px 4px shadow) so its auto-injected
   card never looks like a foreign element dropped into the page.
   ===================================================================== */
:root {
	--ms-bg: #fbf9f6;
	--ms-surface: #ffffff;
	--ms-surface-alt: #faf7f2;
	--ms-border: #e7e0d3;
	--ms-border-strong: #d5c9b4;
	--ms-text: #2b2622;
	--ms-text-muted: #6b6259;
	--ms-accent: #b35a28;
	--ms-accent-dark: #9c4f24;
	--ms-accent-contrast: #ffffff;
	--ms-star: #e8a33d;
	--ms-focus: #2b6cb0;
	--ms-radius: 14px;
	--ms-radius-sm: 8px;
	--ms-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
	--ms-shadow-md: 0 4px 16px rgba(43, 38, 34, 0.08);
	--ms-maxw: 1180px;
	--ms-maxw-narrow: 760px;
	--ms-sidebar-w: 300px;
	--ms-gap: 24px;
	--ms-gap-sm: 12px;
	/* Dedicated footer tokens (rather than reusing --ms-text as a
	   background, which is how a single-theme version of this looked
	   fine) — dark mode redefines --ms-text to a LIGHT color, and a
	   footer whose background is var(--ms-text) would then render light
	   text on a light background. Decoupling them keeps the footer
	   correct in both modes. */
	--ms-footer-bg: #2b2622;
	--ms-footer-text: #f4efe8;
	--ms-font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
		Helvetica, Arial, sans-serif;
	--ms-font-heading: Georgia, "Iowan Old Style", "Palatino Linotype",
		"Book Antiqua", Palatino, serif;
}

/* =====================================================================
   1b. Dark mode — same structural CSS throughout, only the tokens
   change. No JS/class toggle: this follows the OS/browser preference
   directly via prefers-color-scheme, consistent with the theme's
   zero-JS approach everywhere else.

   MS Recipe Card's injected .msseo-card is deliberately NOT re-themed
   here — it ships its own hardcoded inline <style> (light card: white
   background, cream header) that this theme doesn't control, and
   fighting another component's own styling with !important overrides is
   fragile across that plugin's updates. Its existing border/shadow give
   it enough presence to read as an intentional embedded card against a
   dark page, the same way an embedded tweet or video keeps its own
   chrome on an otherwise dark site.
   ===================================================================== */
@media (prefers-color-scheme: dark) {
	:root {
		--ms-bg: #221c17;
		--ms-surface: #2c2420;
		--ms-surface-alt: #362c26;
		--ms-border: #4a3d34;
		--ms-border-strong: #5c4c40;
		--ms-text: #f1e9df;
		--ms-text-muted: #b9a999;
		--ms-accent: #e8834a;
		--ms-accent-dark: #c1652f;
		--ms-accent-contrast: #1a1512;
		--ms-star: #f0b360;
		--ms-focus: #7db8f0;
		--ms-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
		--ms-shadow-md: 0 4px 16px rgba(0, 0, 0, 0.45);
		--ms-footer-bg: #171310;
		--ms-footer-text: #f1e9df;
	}
}

/* =====================================================================
   2. Reset + base
   ===================================================================== */
*,
*::before,
*::after {
	box-sizing: border-box;
}

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

body {
	margin: 0;
	background: var(--ms-bg);
	color: var(--ms-text);
	font-family: var(--ms-font-body);
	font-size: 17px;
	line-height: 1.6;
	-webkit-font-smoothing: antialiased;
}

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

/* WordPress core injects width/height attributes on almost every image it
   handles; keeping display:block + max-width:100% (above) means the
   intrinsic ratio still reserves layout space (no CLS) while never
   overflowing a narrow mobile viewport. */

figure {
	margin: 0;
}

a {
	color: var(--ms-accent-dark);
	text-decoration-thickness: 1px;
	text-underline-offset: 2px;
	transition: color 0.15s ease;
}

a:hover {
	color: var(--ms-accent);
}

/* A visible, high-contrast focus ring on every interactive element —
   deliberately NOT tied to the brand accent, so it stays legible
   regardless of what's behind it. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
summary:focus-visible {
	outline: 3px solid var(--ms-focus);
	outline-offset: 2px;
	border-radius: 2px;
}

h1,
h2,
h3,
h4,
h5,
h6 {
	font-family: var(--ms-font-heading);
	line-height: 1.25;
	font-weight: 700;
	margin: 0 0 0.5em;
	color: var(--ms-text);
}

h1 {
	font-size: clamp(1.85rem, 1.4rem + 1.8vw, 2.75rem);
	letter-spacing: -0.01em;
}

h2 {
	font-size: clamp(1.4rem, 1.2rem + 0.8vw, 1.9rem);
}

h3 {
	font-size: 1.25rem;
}

p {
	margin: 0 0 1.2em;
}

ul,
ol {
	padding-left: 1.4em;
}

button,
input,
textarea,
select {
	font-family: inherit;
	font-size: inherit;
	color: inherit;
}

/* Screen-reader-only utility, WP core convention (used by skip link and
   accessible labels that shouldn't render visually). */
.screen-reader-text {
	border: 0;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	height: 1px;
	width: 1px;
	overflow: hidden;
	position: absolute !important;
	word-wrap: normal !important;
	margin: -1px;
	padding: 0;
}

.screen-reader-text:focus {
	background: var(--ms-surface);
	border-radius: var(--ms-radius-sm);
	box-shadow: var(--ms-shadow-md);
	clip: auto !important;
	clip-path: none;
	color: var(--ms-text);
	display: block;
	font-size: 0.9rem;
	height: auto;
	left: var(--ms-gap-sm);
	line-height: normal;
	padding: 0.8em 1.2em;
	text-decoration: none;
	top: var(--ms-gap-sm);
	width: auto;
	z-index: 100000;
}

/* =====================================================================
   3. Layout / container
   ===================================================================== */
.ms-container {
	max-width: var(--ms-maxw);
	margin-inline: auto;
	/* 20px each side = 40px total on mobile — matches the site-wide
	   sizes_viewport_gutter_px reference value used across the plugin
	   stack, so any element that inherits this padding as its rendered
	   width stays consistent with how responsive `sizes` are computed
	   elsewhere. See README.md "Image sizing" note. */
	padding-inline: 20px;
}

@media (min-width: 782px) {
	.ms-container {
		padding-inline: 32px;
	}
}

.ms-container--narrow {
	max-width: var(--ms-maxw-narrow);
}

/* =====================================================================
   4. Site header + navigation (zero-JS <details>/<summary> disclosure)
   ===================================================================== */
/* Sticky, translucent header — a persistent, always-reachable
   nav/search is a real UX win on a long recipe article, and this is
   pure CSS (position: sticky), so it costs nothing on the JS/perf
   budget. Falls back to a fully opaque header wherever backdrop-filter
   isn't supported (the @supports block below) — never see-through text
   underneath if the blur itself isn't available. */
.site-header {
	background: var(--ms-surface);
	border-bottom: 1px solid var(--ms-border);
	position: sticky;
	top: 0;
	z-index: 40;
}

@supports ( backdrop-filter: blur( 1px ) ) or ( -webkit-backdrop-filter: blur( 1px ) ) {
	.site-header {
		/* rgba, not color-mix() — color-mix() support doesn't fully
		   overlap with backdrop-filter support across older-but-still-
		   common browser versions, so this avoids stacking two
		   bleeding-edge feature dependencies in one declaration.
		   Matches --ms-surface (#ffffff); the dark-mode @supports block
		   immediately below overrides this to dark mode's --ms-surface.
		   It has to come AFTER this one in source order to win: equal
		   selector specificity means source order decides, regardless
		   of which @media/@supports block either rule sits inside. */
		background: rgba(255, 255, 255, 0.88);
		-webkit-backdrop-filter: blur(10px);
		backdrop-filter: blur(10px);
	}
}

@media (prefers-color-scheme: dark) {
	@supports ( backdrop-filter: blur( 1px ) ) or ( -webkit-backdrop-filter: blur( 1px ) ) {
		.site-header {
			/* Matches dark mode's --ms-surface (#2c2420). */
			background: rgba(44, 36, 32, 0.85);
		}
	}
}

.site-header-inner {
	display: flex;
	align-items: center;
	gap: 18px;
	padding-block: 16px;
	flex-wrap: wrap;
}

.site-branding {
	display: flex;
	align-items: center;
	gap: 12px;
	min-width: 0;
	flex: 0 1 auto;
}

/* min-width:0 lets the branding actually shrink (and the tagline wrap)
   instead of forcing the header wider than the viewport and pushing the
   search/hamburger off-screen. */
.site-branding-text {
	min-width: 0;
}

.site-branding img {
	max-height: 46px;
	width: auto;
}

.site-title {
	font-family: var(--ms-font-heading);
	font-size: 1.5rem;
	font-weight: 700;
	margin: 0;
	line-height: 1.05;
	letter-spacing: -0.01em;
}

.site-title a {
	color: var(--ms-text);
	text-decoration: none;
}

.site-title a:hover {
	color: var(--ms-accent-dark);
}

.site-description {
	margin: 3px 0 0;
	font-size: 0.82rem;
	color: var(--ms-text-muted);
}

/* Keep the header compact on small phones — the tagline is decorative and
   its space is better spent on the logo + nav controls. */
@media (max-width: 600px) {
	.site-description {
		display: none;
	}
}

/* ---- Primary navigation (zero-JS checkbox toggle) ----
   The toggle checkbox is visually hidden but focusable; its <label> is the
   mobile hamburger. Desktop shows the menu as an always-visible horizontal
   bar (no reliance on any element's open/closed state); mobile collapses it
   to a dropdown revealed by :checked. See header.php for the markup. */
.ms-menu-toggle-cb {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.main-nav {
	min-width: 0;
}

.primary-menu {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	align-items: center;
	gap: 2px;
}

.primary-menu a {
	display: block;
	padding: 9px 14px;
	border-radius: var(--ms-radius-sm);
	color: var(--ms-text);
	text-decoration: none;
	font-weight: 600;
	font-size: 0.95rem;
	line-height: 1.2;
	position: relative;
	transition: color 0.15s ease, background-color 0.15s ease;
}

.primary-menu a:hover {
	color: var(--ms-accent-dark);
	background: var(--ms-surface-alt);
}

/* Active item — accent text + a short underline indicator on desktop. */
.primary-menu .current-menu-item > a,
.primary-menu .current-menu-ancestor > a,
.primary-menu .current_page_item > a {
	color: var(--ms-accent-dark);
}

/* Dropdown submenu (depth 2) — a small card on hover/focus, desktop only. */
.primary-menu .sub-menu {
	list-style: none;
	margin: 0;
	padding: 6px;
}

/* The hamburger button (a <label>) — hidden on desktop. */
.ms-menu-toggle-btn {
	display: none;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: var(--ms-radius-sm);
	cursor: pointer;
	color: var(--ms-text);
}

.ms-menu-toggle-btn:hover {
	background: var(--ms-surface-alt);
}

.ms-menu-toggle-cb:focus-visible + .main-nav + .header-actions .ms-menu-toggle-btn,
.ms-menu-toggle-btn:focus-visible {
	outline: 3px solid var(--ms-focus);
	outline-offset: 2px;
}

.ms-nav-icon {
	display: block;
	width: 22px;
	height: 2px;
	background: var(--ms-text);
	position: relative;
	transition: background-color 0.15s ease;
}

.ms-nav-icon::before,
.ms-nav-icon::after {
	content: "";
	position: absolute;
	left: 0;
	width: 22px;
	height: 2px;
	background: var(--ms-text);
}

.ms-nav-icon::before {
	top: -7px;
}

.ms-nav-icon::after {
	top: 7px;
}

.header-actions {
	display: flex;
	align-items: center;
	gap: 4px;
}

.header-search-link {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: var(--ms-radius-sm);
	color: var(--ms-text);
}

.header-search-link:hover {
	background: var(--ms-surface-alt);
}

/* ---- Desktop nav (>= 900px): horizontal bar, pushed to the right ---- */
@media (min-width: 900px) {
	.main-nav {
		margin-left: auto;
	}

	.primary-menu .current-menu-item > a::after,
	.primary-menu .current-menu-ancestor > a::after,
	.primary-menu .current_page_item > a::after {
		content: "";
		position: absolute;
		left: 14px;
		right: 14px;
		bottom: 3px;
		height: 2px;
		background: var(--ms-accent);
		border-radius: 1px;
	}

	/* Submenus appear on hover/focus as a floating card. */
	.primary-menu li {
		position: relative;
	}

	.primary-menu .sub-menu {
		position: absolute;
		top: calc(100% + 6px);
		left: 0;
		min-width: 200px;
		background: var(--ms-surface);
		border: 1px solid var(--ms-border);
		border-radius: var(--ms-radius);
		box-shadow: var(--ms-shadow-md);
		opacity: 0;
		visibility: hidden;
		transform: translateY(4px);
		transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
		z-index: 60;
	}

	.primary-menu li:hover > .sub-menu,
	.primary-menu li:focus-within > .sub-menu {
		opacity: 1;
		visibility: visible;
		transform: translateY(0);
	}

	.primary-menu .sub-menu a {
		white-space: nowrap;
	}
}

/* ---- Mobile nav (< 900px): hamburger + absolute dropdown ----
   The nav is taken out of the flex row entirely (absolute), so the header
   bar stays a simple [branding ........ search + hamburger] row and the
   menu drops down as an overlay card only when the checkbox is checked. */
@media (max-width: 899px) {
	.site-header-inner {
		position: relative;
	}

	.header-actions {
		margin-left: auto;
	}

	.ms-menu-toggle-btn {
		display: flex;
	}

	.main-nav {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		z-index: 55;
	}

	.primary-menu {
		display: none;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		margin-top: 8px;
		padding: 6px;
		background: var(--ms-surface);
		border: 1px solid var(--ms-border);
		border-radius: var(--ms-radius);
		box-shadow: var(--ms-shadow-md);
	}

	.ms-menu-toggle-cb:checked ~ .main-nav .primary-menu {
		display: flex;
	}

	.primary-menu a {
		padding: 13px 14px;
	}

	.primary-menu li + li {
		border-top: 1px solid var(--ms-border);
	}

	.primary-menu .current-menu-item > a,
	.primary-menu .current-menu-ancestor > a,
	.primary-menu .current_page_item > a {
		font-weight: 700;
	}

	.primary-menu .sub-menu {
		padding: 0 0 0 12px;
	}
}

/* =====================================================================
   5. Buttons / form controls
   ===================================================================== */
.ms-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 11px 20px;
	background: var(--ms-accent);
	color: var(--ms-accent-contrast);
	border: 0;
	border-radius: var(--ms-btn-radius, var(--ms-radius-sm));
	font-weight: 600;
	font-size: 0.95rem;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.15s ease, transform 0.15s ease;
}

.ms-btn:hover {
	background: var(--ms-accent-dark);
	color: var(--ms-accent-contrast);
	transform: translateY(-1px);
}

.ms-input {
	width: 100%;
	padding: 11px 14px;
	border: 1px solid var(--ms-border-strong);
	border-radius: var(--ms-radius-sm);
	background: var(--ms-surface);
	transition: border-color 0.15s ease;
}

.ms-search-form {
	display: flex;
	gap: 8px;
	max-width: 480px;
}

.ms-search-form .ms-input {
	flex: 1;
}

/* =====================================================================
   6. Recipe grid + card (used on front page, archives, search)
   ===================================================================== */
.recipe-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--ms-gap);
	margin: var(--ms-gap) 0;
	list-style: none;
	padding: 0;
}

@media (min-width: 560px) {
	.recipe-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (min-width: 1000px) {
	.recipe-grid {
		grid-template-columns: repeat(3, 1fr);
	}
}

.recipe-card {
	background: var(--ms-surface);
	border: 1px solid var(--ms-border);
	border-radius: var(--ms-radius);
	overflow: hidden;
	box-shadow: var(--ms-shadow);
	display: flex;
	flex-direction: column;
	transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

/* A subtle lift + the thumbnail's own gentle zoom (below) on hover — a
   tasteful, standard editorial-grid touch, pure CSS transforms/
   transitions so it costs nothing beyond what the browser's compositor
   already does for free. prefers-reduced-motion turns both off. */
.recipe-card:hover {
	transform: translateY(-4px);
	box-shadow: var(--ms-shadow-md);
	border-color: var(--ms-border-strong);
}

.recipe-card-thumb {
	position: relative;
	aspect-ratio: 1 / 1;
	overflow: hidden;
	background: var(--ms-surface-alt);
}

/* The image link fills the whole thumb box so the img's height:100% has a
   resolved height to size against; the category label sits on top of it as
   a separate real link (see template-parts/content.php for why they're
   layered rather than nested). */
.recipe-card-thumb-link {
	position: absolute;
	inset: 0;
	display: block;
}

.recipe-card-cat-overlay {
	position: absolute;
	left: 10px;
	bottom: 10px;
	z-index: 2;
	max-width: calc(100% - 20px);
	background: var(--ms-accent);
	color: var(--ms-accent-contrast);
	font-size: 0.7rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	padding: 4px 10px;
	border-radius: 999px;
	text-decoration: none;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	transition: background-color 0.15s ease;
}

.recipe-card-cat-overlay:hover {
	background: var(--ms-accent-dark);
	color: var(--ms-accent-contrast);
}

/* Sticky-post indicator (post_class() already adds a generic .sticky
   class WP core provides; this badge is the theme's own visible marker
   for it — is_sticky() gates the markup in template-parts/content.php). */
.recipe-card-sticky-badge {
	position: absolute;
	top: 10px;
	left: 10px;
	z-index: 2;
	background: var(--ms-accent);
	color: var(--ms-accent-contrast);
	font-size: 0.7rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	padding: 4px 10px;
	border-radius: 999px;
}

.recipe-card-thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.4s ease;
}

.recipe-card:hover .recipe-card-thumb img {
	transform: scale(1.05);
}

@media (prefers-reduced-motion: reduce) {
	.recipe-card,
	.recipe-card-thumb img,
	.ms-cat-card-media img,
	.ms-btn {
		transition: none;
	}

	.recipe-card:hover,
	.ms-btn:hover {
		transform: none;
	}

	.recipe-card:hover .recipe-card-thumb img,
	.ms-cat-card a:hover .ms-cat-card-media img {
		transform: none;
	}
}

.recipe-card-body {
	padding: 16px 18px 18px;
	display: flex;
	flex-direction: column;
	flex: 1;
}

.recipe-card-cats {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-bottom: 8px;
}

.recipe-card-cats a {
	font-size: 0.72rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	color: var(--ms-accent-dark);
	background: var(--ms-surface-alt);
	border-radius: 999px;
	padding: 3px 10px;
	text-decoration: none;
}

.recipe-card-title {
	font-size: 1.1rem;
	margin: 0 0 8px;
}

.recipe-card-title a {
	color: var(--ms-text);
	text-decoration: none;
}

.recipe-card-title a:hover {
	color: var(--ms-accent-dark);
}

.recipe-card-excerpt {
	color: var(--ms-text-muted);
	font-size: 0.92rem;
	margin: 0 0 12px;
	flex: 1;
}

.recipe-card-meta {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 0.8rem;
	color: var(--ms-text-muted);
	margin-top: auto;
}

/* =====================================================================
   7. Archive header + front-page grid spacing
   ===================================================================== */

/* Front page (is_home()): the header already carries the site title as
   an <h1> and the tagline right below it, so the grid just needs a
   little breathing room under the header rather than a second, larger
   repeat of the same two lines. */
.ms-container--front-grid {
	padding-top: 8px;
}

.archive-header {
	padding-block: 28px 8px;
}

.archive-header h1 {
	margin-bottom: 8px;
}

.archive-header .archive-description {
	color: var(--ms-text-muted);
}

/* =====================================================================
   8. Breadcrumbs
   ===================================================================== */
.ms-breadcrumbs {
	font-size: 0.82rem;
	color: var(--ms-text-muted);
	margin: 16px 0 0;
}

.ms-breadcrumbs a {
	color: var(--ms-text-muted);
	text-decoration: none;
}

.ms-breadcrumbs a:hover {
	color: var(--ms-accent-dark);
}

.ms-breadcrumbs .sep {
	margin: 0 6px;
	opacity: 0.6;
}

/* =====================================================================
   9. Single recipe article
   ===================================================================== */
.recipe-article {
	padding-block: 24px 48px;
}

.recipe-article-header {
	max-width: var(--ms-maxw-narrow);
	margin: 0 auto 24px;
}

/* Full Width page template (page-templates/template-full-width.php) —
   the same building blocks (.recipe-content/.recipe-featured-media/
   .recipe-article-header), just without the narrow reading-column cap,
   for landing pages or pages built from wide blocks/patterns. */
.recipe-content--full-width,
.recipe-featured-media--full-width,
.recipe-article-header--full-width {
	max-width: none;
	width: 100%;
}

.recipe-article-header--full-width h1 {
	text-align: left;
}

.recipe-article-header .recipe-card-cats {
	justify-content: center;
}

.recipe-article-header h1 {
	text-align: center;
}

.recipe-entry-meta {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	flex-wrap: wrap;
	color: var(--ms-text-muted);
	font-size: 0.88rem;
}

.recipe-entry-meta .avatar {
	border-radius: 50%;
	width: 24px;
	height: 24px;
	vertical-align: middle;
}

/* Row holding "Jump to Recipe" + the share links together, so they wrap
   as a unit on narrow screens instead of stacking awkwardly. */
.recipe-header-actions {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 14px;
}

/* "Jump to Recipe" — a common, expected recipe-blog pattern: MS Recipe
   Card appends its card at the very END of the_content(), often well
   below a long personal story, so a direct anchor link straight to it
   (href="#msseo-card-{ID}", see ms_recipes_recipe_card_anchor()) is a
   real UX win. Plain anchor navigation — no JS needed for the jump
   itself; scroll-margin-top on .msseo-card and the article headings
   (below) keeps the target from landing flush against the sticky
   header's top edge. */
.jump-to-recipe {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 9px 18px;
	background: var(--ms-surface-alt);
	border: 1px solid var(--ms-border-strong);
	border-radius: 999px;
	color: var(--ms-accent-dark);
	font-weight: 600;
	font-size: 0.88rem;
	text-decoration: none;
	transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.jump-to-recipe:hover {
	background: var(--ms-accent);
	border-color: var(--ms-accent);
	color: var(--ms-accent-contrast);
}

/* Share links (Pinterest/Facebook/email) — plain icon+label pills,
   visually consistent with the Jump-to-Recipe pill beside them. */
.recipe-share {
	display: flex;
	align-items: center;
	gap: 6px;
}

.recipe-share a {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	padding: 8px 12px;
	border: 1px solid var(--ms-border);
	border-radius: 999px;
	color: var(--ms-text-muted);
	font-size: 0.82rem;
	font-weight: 600;
	text-decoration: none;
	transition: border-color 0.15s ease, color 0.15s ease;
}

.recipe-share a:hover {
	border-color: var(--ms-accent);
	color: var(--ms-accent-dark);
}

.recipe-share svg {
	flex-shrink: 0;
}

/* width: fit-content (capped by max-width) makes this frame hug whatever
   resolution MS Image Optimizer actually serves for the featured image,
   rather than assuming a fixed number. Found via visual QA: with a plain
   max-width:900px frame around a plugin-served 768px-wide image (MSIMG's
   own default desktop display width), the shadow/rounded-corner frame
   rendered ~130px too wide on desktop — an empty gap next to the photo.
   Hugging the image's real width instead means this never needs updating
   if that plugin setting ever changes on the site. */
.recipe-featured-media {
	max-width: 900px;
	width: fit-content;
	margin: 0 auto 28px;
	border-radius: var(--ms-radius);
	overflow: hidden;
	box-shadow: var(--ms-shadow-md);
}

.recipe-featured-media img {
	display: block;
}

/* Deliberately no width/height/loading overrides on the <img> itself —
   MS Image Optimizer controls src/srcset/sizes/fetchpriority for the
   featured image; this class only shapes the CONTAINER. */

/* Table of contents — only rendered at all once a post has 3+ <h2>
   sections (see ms_recipes_render_content_with_toc()), so it never
   shows up as clutter on a short recipe. Plain anchor links to the
   ids ms_recipes_add_heading_ids() injects into the real content
   headings; no JS. */
.recipe-toc {
	max-width: var(--ms-maxw-narrow);
	margin: 0 auto 28px;
	padding: 18px 22px;
	background: var(--ms-surface-alt);
	border: 1px solid var(--ms-border);
	border-radius: var(--ms-radius);
}

.recipe-toc-title {
	margin: 0 0 8px;
	font-weight: 700;
	font-size: 0.9rem;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	color: var(--ms-text-muted);
}

.recipe-toc ol {
	margin: 0;
	padding-left: 1.2em;
	columns: 1;
}

@media (min-width: 560px) {
	.recipe-toc ol {
		columns: 2;
		column-gap: 24px;
	}
}

.recipe-toc li {
	break-inside: avoid;
	margin-bottom: 4px;
}

.recipe-toc a {
	text-decoration: none;
	font-size: 0.95rem;
}

/* Headings need their own scroll-margin too (not just .msseo-card) so a
   TOC link — or any deep link straight to a #heading-id — doesn't land
   flush against the sticky header's bottom edge. */
.recipe-content h2,
.recipe-content h3 {
	scroll-margin-top: 84px;
}

.recipe-content {
	max-width: var(--ms-maxw-narrow);
	margin: 0 auto;
	font-size: 1.05rem;
	/* A little extra breathing room specifically for long-form article
	   text (recipe stories routinely run to a dozen paragraphs+headings)
	   — the base 1.6 stays the tighter default everywhere else (cards,
	   nav, meta lines), where looser spacing would just look loose
	   rather than more readable. */
	line-height: 1.75;
}

.recipe-content > * + * {
	margin-top: 1.2em;
}

.recipe-content h2 {
	margin-top: 1.6em;
}

.recipe-content blockquote {
	margin: 0;
	padding: 4px 20px;
	border-left: 4px solid var(--ms-accent);
	color: var(--ms-text-muted);
	font-style: italic;
}

.recipe-content figure {
	margin: 1.4em 0;
}

.recipe-content figcaption {
	font-size: 0.85rem;
	color: var(--ms-text-muted);
	text-align: center;
	margin-top: 6px;
}

.recipe-content table {
	width: 100%;
	border-collapse: collapse;
}

.recipe-content th,
.recipe-content td {
	border: 1px solid var(--ms-border);
	padding: 8px 10px;
	text-align: left;
}

/* Gutenberg wide/full alignment (add_theme_support('align-wide'), see
   inc/setup.php) — without this CSS the alignment buttons appear in the
   editor but do nothing on the front end, since .recipe-content itself
   is capped at the narrow reading width. The negative-margin technique
   works here because nothing between body and .recipe-content sets
   overflow:hidden. */
.recipe-content .alignwide {
	max-width: 1100px;
	width: 100%;
	margin-left: calc(50% - 50vw + 10px);
	margin-right: calc(50% - 50vw + 10px);
}

.recipe-content .alignfull {
	max-width: 100vw;
	width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

.recipe-content .alignfull img {
	width: 100%;
}

.recipe-content .alignleft {
	float: left;
	margin: 0.4em 1.4em 1em 0;
	max-width: 50%;
}

.recipe-content .alignright {
	float: right;
	margin: 0.4em 0 1em 1.4em;
	max-width: 50%;
}

.recipe-content .aligncenter {
	margin-left: auto;
	margin-right: auto;
}

.recipe-tags {
	max-width: var(--ms-maxw-narrow);
	margin: 28px auto 0;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.recipe-tags a {
	font-size: 0.8rem;
	background: var(--ms-surface-alt);
	border: 1px solid var(--ms-border);
	border-radius: 999px;
	padding: 5px 12px;
	color: var(--ms-text-muted);
	text-decoration: none;
}

.recipe-tags a:hover {
	color: var(--ms-accent-dark);
	border-color: var(--ms-border-strong);
}

/* Targeted from theme CSS only for scroll positioning (see
   .jump-to-recipe above) — never anything that changes its appearance,
   which stays entirely owned by MS Recipe Card's own inline styling.
   84px, matching .recipe-content h2/h3 above, clears the sticky header. */
.msseo-card {
	scroll-margin-top: 84px;
}

/* Author bio */
.author-bio {
	max-width: var(--ms-maxw-narrow);
	margin: 32px auto 0;
	display: flex;
	gap: 14px;
	align-items: flex-start;
	padding: 18px 20px;
	background: var(--ms-surface-alt);
	border: 1px solid var(--ms-border);
	border-radius: var(--ms-radius);
}

.author-bio img {
	border-radius: 50%;
	flex-shrink: 0;
}

.author-bio-name {
	margin: 0 0 4px;
	font-weight: 700;
}

.author-bio-text {
	margin: 0;
	color: var(--ms-text-muted);
	font-size: 0.92rem;
}

/* Post navigation (prev/next) */
.recipe-nav {
	max-width: var(--ms-maxw-narrow);
	margin: 36px auto 0;
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--ms-gap-sm);
	border-top: 1px solid var(--ms-border);
	padding-top: 20px;
}

.recipe-nav .nav-next {
	text-align: right;
}

.recipe-nav a {
	display: block;
	text-decoration: none;
	color: var(--ms-text);
}

.recipe-nav .nav-label {
	display: block;
	font-size: 0.72rem;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--ms-text-muted);
	margin-bottom: 4px;
}

.recipe-nav a:hover .nav-title {
	color: var(--ms-accent-dark);
}

@media (max-width: 559px) {
	.recipe-nav {
		grid-template-columns: 1fr;
	}

	.recipe-nav .nav-next {
		text-align: left;
	}
}

/* Related recipes */
.related-recipes {
	background: var(--ms-surface-alt);
	padding-block: 40px;
	margin-top: 48px;
}

.related-recipes h2 {
	text-align: center;
}

/* =====================================================================
   10. Pagination
   ===================================================================== */
.ms-pagination {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 8px;
	margin: 32px 0;
}

.ms-pagination a,
.ms-pagination span {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	height: 40px;
	padding-inline: 10px;
	border-radius: var(--ms-radius-sm);
	border: 1px solid var(--ms-border);
	text-decoration: none;
	color: var(--ms-text);
	font-size: 0.9rem;
}

.ms-pagination a:hover {
	border-color: var(--ms-accent);
	color: var(--ms-accent-dark);
}

.ms-pagination .current {
	background: var(--ms-accent);
	border-color: var(--ms-accent);
	color: var(--ms-accent-contrast);
	font-weight: 700;
}

/* =====================================================================
   11. Comments
   ===================================================================== */
.comments-area {
	max-width: var(--ms-maxw-narrow);
	margin: 40px auto 0;
}

.comment-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.comment-body {
	padding: 16px 0;
	border-bottom: 1px solid var(--ms-border);
}

.comment-author {
	display: flex;
	align-items: center;
	gap: 10px;
	font-size: 0.9rem;
	margin-bottom: 6px;
}

.comment-author .avatar {
	border-radius: 50%;
	width: 32px;
	height: 32px;
}

.comment-metadata {
	color: var(--ms-text-muted);
	font-size: 0.8rem;
}

.comment-reply-link {
	font-size: 0.82rem;
}

.comment-respond {
	margin-top: 24px;
}

.comment-form p {
	margin-bottom: 14px;
}

.comment-form label {
	display: block;
	margin-bottom: 6px;
	font-size: 0.9rem;
	font-weight: 600;
}

/* =====================================================================
   12. Sidebar + widgets
   ===================================================================== */
.widget {
	margin-bottom: 32px;
}

.widget-title {
	font-size: 1.05rem;
	border-bottom: 2px solid var(--ms-border);
	padding-bottom: 8px;
	margin-bottom: 14px;
}

.widget ul {
	list-style: none;
	padding: 0;
	margin: 0;
}

.widget li {
	padding: 6px 0;
}

/* Sidebar widgets get a light card treatment (vs. the flat footer/inline
   widgets) so the sidebar column reads as a distinct, tidy rail. */
.ms-sidebar .widget {
	background: var(--ms-surface);
	border: 1px solid var(--ms-border);
	border-radius: var(--ms-radius);
	padding: 18px 20px;
	box-shadow: var(--ms-shadow);
}

.ms-sidebar .widget:last-child {
	margin-bottom: 0;
}

.ms-sidebar .widget-title {
	border-bottom-color: var(--ms-accent);
}

.ms-sidebar a {
	color: var(--ms-text);
	text-decoration: none;
}

.ms-sidebar a:hover {
	color: var(--ms-accent-dark);
}

/* =====================================================================
   12b. Layout system — optional sidebars (GeneratePress-inspired)
   Every content template opens the same .ms-layout wrapper; the modifier
   class (resolved in inc/layout.php) decides whether it's an inert block
   (no-sidebar — the default clean reading column) or a two-column grid.
   The main content is always FIRST in the DOM for accessibility/source
   order; a left sidebar is placed visually with grid `order`, not markup
   order.
   ===================================================================== */
.ms-layout--no-sidebar {
	display: block;
}

.ms-layout-content {
	min-width: 0;
}

.ms-sidebar {
	min-width: 0;
}

@media (min-width: 900px) {
	.ms-layout--right-sidebar,
	.ms-layout--left-sidebar {
		display: grid;
		grid-template-columns: minmax(0, 1fr) var(--ms-sidebar-w);
		gap: 40px;
		align-items: start;
	}

	.ms-layout--left-sidebar {
		grid-template-columns: var(--ms-sidebar-w) minmax(0, 1fr);
	}

	.ms-layout--left-sidebar .ms-layout-content {
		order: 2;
	}

	.ms-layout--left-sidebar .ms-sidebar {
		order: 1;
	}

	/* align-items:start (above) lets the sidebar actually stick; 84px
	   clears the sticky header the same as the heading scroll-margins. */
	.ms-sidebar {
		position: sticky;
		top: 84px;
	}

	/* A grid of cards in a narrowed content column shouldn't keep trying
	   to be 3–4 wide; cap it to 2 whenever a sidebar is present. Higher
	   specificity than the Customizer's inline .recipe-grid column rule,
	   so the sidebar cap always wins over the global column preference. */
	.ms-layout--right-sidebar .recipe-grid,
	.ms-layout--left-sidebar .recipe-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* With a sidebar present, the single-article internals stop being pinned
   to the narrow, centered reading column and instead fill the content
   column (left-aligned). Their viewport-breakout alignments also fold
   back to the column width — a full-bleed .alignfull computed from 100vw
   would be wrong inside a grid track. */
.ms-layout--right-sidebar .recipe-article-header,
.ms-layout--left-sidebar .recipe-article-header,
.ms-layout--right-sidebar .recipe-featured-media,
.ms-layout--left-sidebar .recipe-featured-media,
.ms-layout--right-sidebar .recipe-toc,
.ms-layout--left-sidebar .recipe-toc,
.ms-layout--right-sidebar .recipe-content,
.ms-layout--left-sidebar .recipe-content,
.ms-layout--right-sidebar .recipe-tags,
.ms-layout--left-sidebar .recipe-tags,
.ms-layout--right-sidebar .author-bio,
.ms-layout--left-sidebar .author-bio,
.ms-layout--right-sidebar .recipe-nav,
.ms-layout--left-sidebar .recipe-nav {
	max-width: none;
	margin-left: 0;
	margin-right: 0;
}

.ms-layout--right-sidebar .recipe-article-header h1,
.ms-layout--left-sidebar .recipe-article-header h1,
.ms-layout--right-sidebar .recipe-article-header .recipe-card-cats,
.ms-layout--left-sidebar .recipe-article-header .recipe-card-cats,
.ms-layout--right-sidebar .recipe-header-actions,
.ms-layout--left-sidebar .recipe-header-actions,
.ms-layout--right-sidebar .recipe-entry-meta,
.ms-layout--left-sidebar .recipe-entry-meta {
	text-align: left;
	justify-content: flex-start;
}

.ms-layout--right-sidebar .recipe-content .alignwide,
.ms-layout--left-sidebar .recipe-content .alignwide,
.ms-layout--right-sidebar .recipe-content .alignfull,
.ms-layout--left-sidebar .recipe-content .alignfull {
	max-width: 100%;
	width: 100%;
	margin-left: 0;
	margin-right: 0;
}

/* =====================================================================
   13. Footer
   ===================================================================== */
.site-footer {
	background: var(--ms-footer-bg);
	color: var(--ms-footer-text);
	margin-top: 56px;
}

.footer-widgets {
	display: grid;
	grid-template-columns: 1fr;
	gap: 32px;
	padding-block: 40px;
}

@media (min-width: 700px) {
	.footer-widgets {
		grid-template-columns: repeat(3, 1fr);
	}
}

.site-footer .widget-title {
	color: var(--ms-footer-text);
	border-bottom-color: rgba(255, 255, 255, 0.2);
}

.site-footer a {
	color: var(--ms-footer-text);
}

.site-footer a:hover {
	color: var(--ms-star);
}

.footer-bottom {
	border-top: 1px solid rgba(255, 255, 255, 0.12);
	padding-block: 18px;
	font-size: 0.82rem;
	color: rgba(244, 239, 232, 0.7);
	text-align: center;
}

.footer-bottom-inner {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 6px 20px;
}

.back-to-top {
	color: rgba(244, 239, 232, 0.7);
	text-decoration: none;
}

.back-to-top:hover {
	color: var(--ms-star);
}

/* =====================================================================
   14. 404 / no-results
   ===================================================================== */
.no-results {
	text-align: center;
	padding-block: 48px;
}

.no-results .ms-search-form {
	margin: 20px auto 0;
}

/* =====================================================================
   14b. Food-blog blocks (Blossom-inspired): decorative section headings,
   featured banner, category showcase, social icons, About widget.
   All zero-JS; all imagery here sits below the fold so it stays lazy and
   never touches the LCP budget.
   ===================================================================== */

/* --- Decorative centered section heading --- */
.ms-section-heading {
	text-align: center;
	margin: 4px 0 24px;
}

.ms-section-title {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 14px;
	margin: 0;
}

.ms-section-title::before,
.ms-section-title::after {
	content: "";
	width: 42px;
	height: 2px;
	background: var(--ms-accent);
	border-radius: 1px;
	opacity: 0.75;
}

.ms-section-subtitle {
	margin: 8px 0 0;
	color: var(--ms-text-muted);
}

/* --- Featured banner (blog home) --- */
.ms-feature-banner {
	display: grid;
	grid-template-columns: 1fr;
	margin: 4px 0 var(--ms-gap);
	background: var(--ms-surface);
	border: 1px solid var(--ms-border);
	border-radius: var(--ms-radius);
	overflow: hidden;
	box-shadow: var(--ms-shadow);
}

@media (min-width: 800px) {
	.ms-feature-banner {
		grid-template-columns: 1.35fr 1fr;
		align-items: stretch;
	}
}

.ms-feature-media {
	display: block;
	aspect-ratio: 16 / 10;
	overflow: hidden;
}

.ms-feature-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 0.4s ease;
}

.ms-feature-banner:hover .ms-feature-media img {
	transform: scale(1.04);
}

@media (min-width: 800px) {
	.ms-feature-media {
		aspect-ratio: auto;
		/* Keep the banner image from growing unbounded when the text
		   column is short — a balanced, editorial hero height. */
		max-height: 460px;
	}
}

.ms-feature-body {
	padding: 26px 28px;
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 10px;
}

.ms-feature-cat {
	align-self: flex-start;
	background: var(--ms-accent);
	color: var(--ms-accent-contrast);
	font-size: 0.72rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	padding: 4px 12px;
	border-radius: 999px;
	text-decoration: none;
}

.ms-feature-cat:hover {
	background: var(--ms-accent-dark);
	color: var(--ms-accent-contrast);
}

.ms-feature-title {
	font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.2rem);
	margin: 0;
}

.ms-feature-title a {
	color: var(--ms-text);
	text-decoration: none;
}

.ms-feature-title a:hover {
	color: var(--ms-accent-dark);
}

.ms-feature-excerpt {
	color: var(--ms-text-muted);
	margin: 0;
}

.ms-feature-meta {
	display: flex;
	align-items: center;
	gap: 10px;
	color: var(--ms-text-muted);
	font-size: 0.85rem;
}

.ms-feature-btn {
	align-self: flex-start;
	margin-top: 6px;
}

/* --- Category showcase --- */
.ms-cat-showcase {
	background: var(--ms-surface-alt);
	padding-block: 44px;
	margin-top: 8px;
}

.ms-cat-grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
	gap: var(--ms-gap);
}

.ms-cat-card a {
	position: relative;
	display: block;
	aspect-ratio: 4 / 3;
	border-radius: var(--ms-radius);
	overflow: hidden;
	text-decoration: none;
	background: var(--ms-border-strong);
	box-shadow: var(--ms-shadow);
}

.ms-cat-card-media {
	position: absolute;
	inset: 0;
}

.ms-cat-card-media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.4s ease;
}

.ms-cat-card a:hover .ms-cat-card-media img {
	transform: scale(1.06);
}

.ms-cat-card a::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0.05) 62%);
}

.ms-cat-card-body {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 1;
	padding: 12px 14px;
	color: #fff;
}

.ms-cat-card-name {
	display: block;
	font-family: var(--ms-font-heading);
	font-weight: 700;
	font-size: 1.05rem;
	line-height: 1.2;
}

.ms-cat-card-count {
	display: block;
	font-size: 0.78rem;
	opacity: 0.9;
	margin-top: 2px;
}

/* --- Social icon lists (footer, widgets, About box, author bio) --- */
.ms-social {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.ms-social a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	background: var(--ms-surface-alt);
	border: 1px solid var(--ms-border);
	color: var(--ms-text-muted);
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.ms-social a:hover {
	background: var(--ms-accent);
	border-color: var(--ms-accent);
	color: var(--ms-accent-contrast);
}

.ms-social--about,
.ms-social--widget {
	justify-content: center;
}

.ms-social--bio a {
	width: 32px;
	height: 32px;
}

/* Footer social sits on the dark footer, so its idle pills are translucent
   light rather than the light surface used elsewhere. */
.footer-social {
	display: flex;
	justify-content: center;
	padding: 26px 20px 2px;
}

.ms-social--footer a {
	background: rgba(255, 255, 255, 0.08);
	border-color: rgba(255, 255, 255, 0.18);
	color: var(--ms-footer-text);
}

.ms-social--footer a:hover {
	background: var(--ms-accent);
	border-color: var(--ms-accent);
	color: var(--ms-accent-contrast);
}

/* --- About Me widget --- */
.ms-about-widget {
	text-align: center;
}

.ms-about-img {
	width: 110px;
	height: 110px;
	border-radius: 50%;
	object-fit: cover;
	margin: 0 auto 12px;
	display: block;
}

.ms-about-name {
	font-family: var(--ms-font-heading);
	font-weight: 700;
	font-size: 1.15rem;
	margin: 0 0 2px;
}

.ms-about-subtitle {
	color: var(--ms-text-muted);
	font-size: 0.85rem;
	margin: 0 0 10px;
}

.ms-about-text {
	color: var(--ms-text-muted);
	font-size: 0.92rem;
}

.ms-about-widget .ms-social {
	margin-top: 12px;
}

.ms-about-btn {
	margin-top: 14px;
}

/* --- Enhanced author bio foot (archive link + social) --- */
.author-bio-body {
	flex: 1;
	min-width: 0;
}

.author-bio-foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 12px;
}

.author-bio-more {
	font-weight: 600;
	font-size: 0.88rem;
	text-decoration: none;
	color: var(--ms-accent-dark);
}

.author-bio-more:hover {
	color: var(--ms-accent);
}

/* --- Share row label --- */
.recipe-share-label {
	font-size: 0.78rem;
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--ms-text-muted);
	align-self: center;
	margin-right: 2px;
}

/* =====================================================================
   14c. Custom background image (boxed content)
   When a background image/color is set (Appearance → Background Image),
   WordPress adds the .custom-background body class. Lift the main content
   onto an opaque panel so text stays readable over any background — the
   header, footer, featured banner, showcase and related bands already
   carry their own solid backgrounds. The background is a CSS
   background-image (never an <img>), so it is not the LCP element and
   doesn't affect the performance score.
   ===================================================================== */
body.custom-background .ms-layout-content,
body.site-layout-content-boxed .ms-layout-content {
	background: var(--ms-surface);
	border: 1px solid var(--ms-border);
	border-radius: var(--ms-radius);
	padding: clamp(18px, 3vw, 36px);
	box-shadow: var(--ms-shadow);
}

body.custom-background .ms-breadcrumbs,
body.site-layout-content-boxed .ms-breadcrumbs {
	display: inline-block;
	background: var(--ms-surface);
	border-radius: var(--ms-radius-sm);
	padding: 4px 12px;
}

body.custom-background .comments-area,
body.site-layout-content-boxed .comments-area {
	background: var(--ms-surface);
	border: 1px solid var(--ms-border);
	border-radius: var(--ms-radius);
	padding: clamp(18px, 3vw, 32px);
}

/* Hide the header actions row entirely when both Jump-to-Recipe and share
   are disabled (Customizer), so it never leaves an empty gap. */
.recipe-header-actions:empty {
	display: none;
}

/* Smooth in-page scrolling for TOC / Jump-to-Recipe / back-to-top anchors
   — only when the visitor hasn't asked to reduce motion. */
@media (prefers-reduced-motion: no-preference) {
	html {
		scroll-behavior: smooth;
	}
}

/* =====================================================================
   14d. Site-wide options (Astra/GeneratePress-inspired): site layout,
   top bar, scroll-to-top button, sticky-header + underline-links toggles.
   All driven by body classes / markup, so they add no per-request CSS.
   ===================================================================== */

/* ---- Site Layout: Boxed ----
   The whole site sits in a centered box; the page gutter shows html's
   background behind it. The box shadow does the visual separation, so the
   effect reads even though the gutter tone is deliberately subtle. */
html {
	background: var(--ms-surface-alt);
}

body.site-layout-boxed {
	max-width: calc(var(--ms-maxw) + 80px);
	margin-inline: auto;
	background: var(--ms-bg);
	box-shadow: 0 0 40px rgba(0, 0, 0, 0.09);
	min-height: 100vh;
}

/* ---- Sticky-header + underline-links toggles ---- */
body.no-sticky-header .site-header {
	position: static;
}

body.no-underline-links .recipe-content a {
	text-decoration: none;
}

/* ---- Top bar (optional slim bar above the header) ---- */
.ms-top-bar {
	background: var(--ms-footer-bg);
	color: var(--ms-footer-text);
	font-size: 0.82rem;
}

.ms-top-bar-inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding-block: 8px;
	min-height: 38px;
}

.ms-top-bar-text {
	color: var(--ms-footer-text);
}

.ms-social--topbar {
	gap: 4px;
}

.ms-social--topbar a {
	width: 30px;
	height: 30px;
	background: transparent;
	border-color: rgba(255, 255, 255, 0.22);
	color: var(--ms-footer-text);
}

.ms-social--topbar a:hover {
	background: var(--ms-accent);
	border-color: var(--ms-accent);
	color: var(--ms-accent-contrast);
}

/* ---- Scroll-to-top button ----
   A fixed anchor to #top. On browsers that support scroll-driven
   animations it stays hidden until the page is scrolled ~300px (zero-JS
   progressive enhancement); elsewhere it's simply always visible. */
.ms-scroll-top {
	position: fixed;
	right: 20px;
	bottom: 20px;
	z-index: 60;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background: var(--ms-accent);
	color: var(--ms-accent-contrast);
	box-shadow: var(--ms-shadow-md);
	text-decoration: none;
	transition: background-color 0.15s ease, transform 0.15s ease;
}

.ms-scroll-top:hover {
	background: var(--ms-accent-dark);
	color: var(--ms-accent-contrast);
	transform: translateY(-2px);
}

@supports (animation-timeline: scroll()) {
	.ms-scroll-top {
		opacity: 0;
		visibility: hidden;
		animation: ms-reveal-scrolltop linear both;
		animation-timeline: scroll(root block);
		animation-range: 300px 420px;
	}

	@keyframes ms-reveal-scrolltop {
		to {
			opacity: 1;
			visibility: visible;
		}
	}
}

/* Never leave it stuck hidden for reduced-motion users on supporting
   browsers — just show it. */
@media (prefers-reduced-motion: reduce) {
	.ms-scroll-top {
		animation: none;
		opacity: 1;
		visibility: visible;
		transition: none;
	}
}

/* =====================================================================
   14e. Ad/promo widget zones + Recipe Index page
   ===================================================================== */
.ms-below-header {
	padding-block: 16px;
	text-align: center;
}

/* Ad / promo slots (managed in MS Recipes → Ad Positions). Centered, spaced,
   and width-capped to the reading column so a wide banner never blows out the
   layout. The reserved min-height on template slots keeps CLS at 0 while a
   slow ad script paints; the in-content variant omits it (its size is known
   from the surrounding text flow). Empty slots render no element at all, so
   these rules only ever apply when an ad is actually present. */
.ms-ad {
	margin: 24px auto;
	max-width: 100%;
	text-align: center;
	line-height: 0;
}

.ms-ad--before_article,
.ms-ad--before_content,
.ms-ad--after_content,
.ms-ad--after_article,
.ms-ad--before_featured,
.ms-ad--after_featured,
.ms-ad--in-content,
.ms-ad--element {
	max-width: var(--ms-maxw-narrow);
}

.ms-ad--below_header {
	margin-block: 16px;
	padding-inline: var(--ms-gap, 20px);
}

.ms-ad :is(img, iframe, ins) {
	max-width: 100%;
	height: auto;
}

.ms-below-header .widget,
.ms-after-content .widget {
	margin-bottom: 0;
}

/* After-content zone aligns with the reading column, centered. */
.ms-after-content {
	max-width: var(--ms-maxw-narrow);
	margin: 28px auto 0;
	text-align: center;
}

.recipe-index-intro {
	margin-bottom: 4px;
}

.ms-recipe-index-search {
	max-width: 480px;
	margin: 0 auto 8px;
}

/* Recipe Index — category image cards (reusing the showcase card styling)
   and, below them, the lightweight tag tiles + tag search. */
.ms-index-cats {
	margin-bottom: 20px;
}

/* Tag search form on the Recipe Index. */
.ms-tag-search {
	display: flex;
	gap: 8px;
	max-width: 480px;
	margin: 0 0 10px;
}

.ms-tag-search input[type="search"] {
	flex: 1;
	min-width: 0;
}

.ms-tag-search button {
	flex-shrink: 0;
	padding: 8px 16px;
	border: 1px solid var(--ms-accent);
	background: var(--ms-accent);
	color: var(--ms-accent-contrast);
	border-radius: var(--ms-radius-sm);
	font-weight: 600;
	cursor: pointer;
}

.ms-tag-search button:hover {
	background: var(--ms-accent-dark);
	border-color: var(--ms-accent-dark);
}

.ms-index-tagnote,
.ms-index-notag {
	color: var(--ms-text-muted);
	font-size: 0.9rem;
	margin: 0 0 10px;
}

/* Category directory — lightweight text tiles, used for the tag list, so the
   Recipe Index page loads instantly even with thousands of tags. */
.ms-index-tiles {
	list-style: none;
	margin: 0 0 8px;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
	gap: 12px;
}

.ms-index-tiles a {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
	padding: 14px 18px;
	background: var(--ms-surface);
	border: 1px solid var(--ms-border);
	border-radius: var(--ms-radius-sm);
	text-decoration: none;
	color: var(--ms-text);
	font-weight: 600;
	transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}

.ms-index-tiles a:hover {
	border-color: var(--ms-accent);
	color: var(--ms-accent-dark);
	background: var(--ms-surface-alt);
}

.ms-index-tile-count {
	color: var(--ms-text-muted);
	font-weight: 500;
	font-size: 0.85rem;
	flex-shrink: 0;
}

/* =====================================================================
   15. Print (recipe card already ships its own print affordance via its
   "Imprimer" button + window.print(); this keeps the surrounding chrome
   out of a printed page for anyone who prints via the browser directly)
   ===================================================================== */
@media print {
	.site-header,
	.site-footer,
	.footer-social,
	.related-recipes,
	.ms-cat-showcase,
	.recipe-nav,
	.recipe-share,
	.comments-area,
	.ms-breadcrumbs,
	.msseo-print {
		display: none !important;
	}
}
