/*
Theme Name:       Yoya Fun
Theme URI:        https://yoyafun.net/
Author:           Yoya Fun
Description:      Premium travel editorial block theme for yoyafun.net. FSE-native, theme.json-first.
Version:          0.1.9
Requires at least: 6.4
Tested up to:     7.0
Requires PHP:     7.4
Requires Plugins: polylang, advanced-custom-fields
License:          GNU General Public License v2 or later
License URI:      http://www.gnu.org/licenses/gpl-2.0.html
Text Domain:      yoyafun
Tags:             block-theme, full-site-editing, editorial, magazine
*/

/* ============================================================
   Yoya Fun — Batch 1 stylesheet.
   Scope: minimal global CSS needed to support the approved
   visual direction (Hero B only). All design tokens live in
   theme.json; this file holds only what theme.json cannot
   express — background-clip:text gradient, pseudo-elements,
   and the hero-scoped colour flip for the header.
   ============================================================ */

/* ============================================================
   FOUNDATION — Global page-shell sticky-footer.

   Pins the footer template-part to the viewport's bottom edge
   whenever document height < viewport height (404, search
   no-results, sparse archives, any other short page rendered
   in a tall window). Without this rule the body's `paper`
   background propagates to the root canvas below the footer's
   `paper-deep` background, producing a visible blank band
   below the footer.

   Mechanism: `.wp-site-blocks` becomes a flex column with a
   min-height tied to the actual viewport (100dvh, 100vh
   fallback for older browsers). The footer's outer template-
   part wrapper gets `margin-top: auto`, which absorbs any
   leftover vertical space — the footer hits the viewport
   edge on short pages, and flows naturally on tall pages.

   Admin-bar offset: WP-core sets `html { margin-top: 32px }`
   when logged in (46 px below 782 px viewport width). The
   `.admin-bar` selectors subtract those values from the
   min-height so the shell never forces overscroll on logged-
   in short pages. The 782 px breakpoint is WordPress's own
   admin-bar breakpoint — not a device-targeted breakpoint.

   Selector precision: `.wp-site-blocks > footer` matches only
   the outer footer template-part wrapper. `<header>` and
   `<footer>` both carry .wp-block-template-part, so we do not
   key off that class.
   ============================================================ */
.wp-site-blocks {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100dvh;
}
.wp-site-blocks > footer {
	margin-top: auto;
}
.admin-bar .wp-site-blocks {
	min-height: calc(100vh - 32px);
	min-height: calc(100dvh - 32px);
}
@media screen and (max-width: 782px) {
	.admin-bar .wp-site-blocks {
		min-height: calc(100vh - 46px);
		min-height: calc(100dvh - 46px);
	}
}

/* Header colour flip when nested inside the Hero B image.
   The hero-scoped colour swap for the logo + nav now happens
   on the project's own classes (`.yf-header__logo-yoya`,
   `.yf-header__logo-fun`, `.yf-header__nav-item a`) further
   down in this file. The legacy fallback rules that targeted
   `.wp-block-site-title` / `.wp-block-navigation` here were
   removed because the header no longer uses either of those
   blocks: the logo is a hardcoded two-span paragraph and the
   nav is six `wp:paragraph.yf-header__nav-item` elements. */

/* ============================================================
   BATCH 13 — Homepage hero corrected to STRICT V5 Hero B.

   Per the V4-vs-V5 reconciliation in `handoff/11-design-source-
   reconciliation.md` (now answered by user direction: V5 is
   canonical for the homepage hero), the homepage uses the V5
   Hero B mechanic: a single H1 with `background-clip: text`
   paper→ink gradient that straddles the image/page boundary
   via `margin-top: -180px` on the title-zone.

   Source: `SharedV5.jsx` `function HeroB(...)` and
   `assets/system-v5.css` `.yf-hero5b__*` rules.

   Composition is CSS-locked per the user's priority hierarchy
   (source-faithful > FSE-valid > editor controls only for
   content surfaces). Content surfaces that remain editable in
   Gutenberg: kicker text, title text, dek text, hero image,
   BigMediaCTA text labels, byline name + meta. Geometry —
   image height, title size, title-zone straddle margin, plane
   paddings, row positioning — is locked here in CSS.

   Title-zone / title / below / general dek rules are SHARED
   with single.html, single-gallery.html, page.html and live in
   the Cross-template hero block below this one. The Batch 13
   rules here only cover the homepage-specific image area,
   image-content wrapper, kicker, and row composition.
   ============================================================ */

/* Outer hero section — paper background per V5 source spec.
   Scoped to `.yf-hero5b` parent so other templates' hero classes
   (which don't sit inside `.yf-hero5b`) are unaffected.         */
.yf-hero5b {
	position: relative;
	width: 100%;
	background: var(--wp--preset--color--paper);
}

/* Image area — fixed 540 px height (V5 source default). The
   `.yf-hero5b__image` class is also used by single.html / single-
   gallery.html / page.html on their wp:cover hero — the height
   rule is scoped to direct children of `.yf-hero5b` so it only
   applies to the homepage wp:group implementation.              */
.yf-hero5b > .yf-hero5b__image {
	position: relative;
	width: 100%;
	height: 540px;
	overflow: hidden;
	isolation: isolate;
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--on-image);
}

/* Background image (wp:image absolutely positioned to fill the
   image area). Keeps the image editor-replaceable through the
   wp:image block's standard Replace UI.                         */
.yf-hero5b > .yf-hero5b__image > .wp-block-image.yf-hero5b__bg,
.yf-hero5b__bg {
	position: absolute;
	inset: 0;
	margin: 0;
	z-index: 0;
	pointer-events: none;
}
.yf-hero5b > .yf-hero5b__image > .wp-block-image.yf-hero5b__bg img,
.yf-hero5b__bg img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	display: block;
}

/* Vignette overlay — V5 strict spec: single 3-stop linear
   gradient (top dark → mid transparent → bottom subtle dark).
   Scoped via `.yf-hero5b` parent so it only fires on the
   homepage hero.                                               */
.yf-hero5b > .yf-hero5b__image::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		rgba(28, 24, 20, 0.4) 0%,
		rgba(28, 24, 20, 0)   30%,
		rgba(28, 24, 20, 0.18) 100%
	);
	pointer-events: none;
	z-index: 1;
}

/* Image-content wrapper — z-index 3 layer above bg + overlay.
   Holds the integrated header template-part + the kicker.      */
.yf-hero5b__image-content {
	position: relative;
	z-index: 3;
}

/* Kicker — V5 strict: 11 px / weight 700 / letter-spacing
   0.22em / 28×1 rule line / gap 14 / padding 12-64-0. The
   rule line is drawn via `::before` on the kicker so no extra
   markup span is needed. Typography lives on the class itself
   AND on the cross-template `.yf-hero5b__kicker-text` child
   (used by single-gallery.html); both arrive at V5 specs.      */
.yf-hero5b__kicker {
	display: inline-flex;
	align-items: center;
	gap: 14px;
	margin: 0 !important;
	padding: 12px 64px 0;
	color: var(--wp--preset--color--on-image);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}
.yf-hero5b__kicker::before {
	content: "";
	display: inline-block;
	flex-shrink: 0;
	width: 28px;
	height: 1px;
	background: var(--wp--preset--color--on-image);
	opacity: 0.75;
}
.yf-hero5b__kicker-text {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--wp--preset--color--on-image);
	text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}

/* Dek inside the homepage hero's `__below` — V5 source has
   `marginTop: 8` inline. Scoped under `.yf-hero5b__below` so
   single.html's post-excerpt dek (which lives in its own
   `__below` outside `.yf-hero5b`) is not affected.             */
.yf-hero5b__below .yf-hero5b__dek {
	margin: 8px 0 0 !important;
	max-width: 720px;
}

/* Row beneath the dek — flex composition of two BigMediaCTAs +
   byline. V5 source has `marginTop: 40` inline; locked here in
   CSS. The flex behaviour (`display: flex; align-items: center;
   gap: 24; flex-wrap: wrap`) comes from the wp:group's
   block-native `layout: flex` + blockGap 24.                   */
.yf-hero5b__row {
	margin-top: 40px !important;
	width: 100%;
}
.yf-hero5b__row > * {
	max-width: none !important;
	margin: 0 !important;
}

/* Responsive — image height + kicker padding shrink at narrower
   viewports. Title sizing and title-zone straddle margin scale
   in the cross-template responsive block below.                */
@media (max-width: 1199px) {
	.yf-hero5b > .yf-hero5b__image { height: 460px; }
}
@media (max-width: 900px) {
	.yf-hero5b > .yf-hero5b__image { height: 380px; }
	.yf-hero5b__kicker { padding: 12px 32px 0; }
}
@media (max-width: 600px) {
	.yf-hero5b > .yf-hero5b__image { height: 300px; }
	.yf-hero5b__kicker {
		padding-top: 12px;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px);
		padding-bottom: 0;
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px);
	}
}

/* ============================================================
   Cross-template hero rules — used by `single.html`,
   `single-gallery.html`, and `page.html`. These templates were
   built with a Hero B (gradient text-clip + title-straddles-
   boundary) variant in earlier batches. Batch 11.7 reconciled
   the homepage hero to HeroBandV4 (frosted plane) but did NOT
   touch the single / page / single-gallery templates (out of
   this batch's allow-list). The rules below preserve the legacy
   single-post hero behaviour so those templates do not regress.

   When a future batch reconciles the single-post hero against
   the design source (SinglePostV4 / SinglePostV5), this block
   should be revisited.
   ============================================================ */
/* Batch 27.1 — pixel-exact title gradient stop.

   The title-zone sits in the paper section by DOM order but is
   pulled UP by `margin-top: -|N|px` so the H1 visually overlaps
   the dark hero. The hero/paper boundary therefore lives exactly
   |N| pixels below the top of the title's bounding box.

   In Batch 27 we tried percentage stops (38 % / 32 % / 26 %).
   Those numbers were only valid for one specific title length per
   breakpoint — any change in line count or wrap moved the
   percentage off the boundary. The new approach drops percentages
   entirely: the gradient stop is the literal pixel offset of the
   boundary inside the title box, exposed as
   `--yf-hero-boundary`, which is always paired with the
   title-zone's `margin-top`. As long as both numbers stay equal
   (in absolute value), the cream/ink split lands on the visual
   boundary regardless of how the title wraps.

   The default unit is `px`, the same coordinate space as
   `margin-top`, so there is no conversion error. */
.yf-hero5b__title-zone {
	position: relative;
	z-index: 4;
	margin-top: -180px;
	--yf-hero-boundary: 180px;
}
.yf-hero5b__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	/* MW3.16 — BUG-HERO-001 clamp + balance refinement.
	   Replaces font-size:160px with viewport-responsive clamp; max preserves
	   desktop visual at ~10rem. text-wrap:balance already present below. */
	font-size: clamp(2.5rem, 8vw + 1rem, 10rem);
	line-height: 0.9;
	letter-spacing: -0.025em;
	text-wrap: balance;
	/* Batch 27.2 — the top stripe is now `on-image` (#FFFFFF)
	   instead of `paper` (#F4EEE3). Reason: on the dark hero,
	   cream paper-on-dark reads softer than ink-on-paper does
	   on the paper section, so the straddling line looked
	   visually unbalanced (small soft cap of cream, then a
	   strong block of ink). White-on-dark matches the visual
	   weight of ink-on-paper, so both halves of the split
	   read at the same intensity and the boundary truly looks
	   locked instead of just being mathematically locked.
	   Pixel position of the stop is unchanged — still anchored
	   to `--yf-hero-boundary`, still equal in absolute value
	   to the title-zone's `margin-top`. */
	background: linear-gradient(
		180deg,
		var(--wp--preset--color--on-image) 0,
		var(--wp--preset--color--on-image) var(--yf-hero-boundary),
		var(--wp--preset--color--ink)      var(--yf-hero-boundary),
		var(--wp--preset--color--ink)      100%
	);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	color: transparent;
	filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.32));
	text-rendering: geometricPrecision;
}
.yf-hero5b__below {
	background: var(--wp--preset--color--paper);
}
/* Generic dek rule for single-post / page templates. The
   homepage's dek inside the frosted plane is scoped above via
   `.yf-hero5b__plane .yf-hero5b__dek` so the two contexts don't
   collide. */
.yf-hero5b__dek {
	margin: 0;
	max-width: 720px;
	font-family: var(--wp--preset--font-family--body);
	font-size: 22px;
	line-height: 1.5;
	font-style: italic;
	color: var(--wp--preset--color--ink-soft);
}
/* Cross-template hero responsive — single / page / single-gallery.
   At each breakpoint, `--yf-hero-boundary` mirrors the absolute
   value of `margin-top` exactly, so the gradient stop stays
   locked to the literal hero/paper boundary in pixels. */
@media (max-width: 900px) {
	.yf-hero5b__title       { font-size: 96px; }
	.yf-hero5b__title-zone  {
		margin-top: -110px;
		--yf-hero-boundary: 110px;
	}
}
@media (max-width: 600px) {
	.yf-hero5b__title       { font-size: 60px; }
	.yf-hero5b__title-zone  {
		margin-top: -72px;
		--yf-hero-boundary: 72px;
	}
	.yf-hero5b__title-zone,
	.yf-hero5b__below {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
	}
	.yf-hero5b__dek         { font-size: 18px; }
}

/* ============================================================
   Batch 2 — Single post layout (structural foundation).
   Hero B is reused from above; the rules below add only
   single-specific surface: hero byline, post-excerpt dek
   adapter, two-column body+rail layout, rail v4 modules,
   and the end-of-article region. All visuals; no behaviour.
   ============================================================ */

/* Single hero — post-terms kicker reuses the Hero B kicker
   group's `::before` rule line. The terms block renders as
   <div><a>…</a></div>; reset its anchor decoration so the
   kicker reads as a label, not a link list. */
.yf-hero5b__kicker .wp-block-post-terms,
.yf-hero5b__kicker-terms {
	color: var(--wp--preset--color--on-image);
	text-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
}
.yf-hero5b__kicker .wp-block-post-terms a {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
/* HMTB Item 5 — in-hero breadcrumb (post-terms kicker) hover colour.
   Desktop hover lifts each crumb to accent-soft. (The new body
   breadcrumb bar gets the same hover in its own rule block below.) */
.yf-hero5b__kicker .wp-block-post-terms a:hover,
.yf-hero5b__kicker .wp-block-post-terms a:focus-visible {
	color: var(--wp--preset--color--accent-soft);
}

/* ============================================================
 * HMTB Item 6 — site-wide body breadcrumb bar (yoyafun/breadcrumbs).
 * Rendered below the hero, above body content, on every non-single
 * surface. Calm muted trail on the paper body; the separator is a CSS
 * ::before chevron (logical inline margin => RTL-safe), so it is not in
 * the markup. Item-5 hover (--accent-soft) is applied to the body crumbs
 * here too. The block render emits a <nav><ol><li> structure + the
 * BreadcrumbList JSON-LD.
 * ============================================================ */
.yf-breadcrumbs-bar {
	padding-block: 14px;
	padding-inline: var(--wp--custom--yf--gutter, 64px);
	background-color: var(--wp--preset--color--paper);
	border-block-end: var(--wp--custom--yf--hairline, 1px) solid var(--wp--preset--color--rule);
}
.yf-breadcrumbs__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.04em;
	line-height: 1.4;
}
.yf-breadcrumbs__item {
	display: inline-flex;
	align-items: center;
}
/* Separator before every item except the first (logical margin = RTL-safe). */
.yf-breadcrumbs__item + .yf-breadcrumbs__item::before {
	content: "\203A"; /* › */
	margin-inline: 8px;
	color: var(--wp--preset--color--ink-mute);
	pointer-events: none;
}
[dir="rtl"] .yf-breadcrumbs__item + .yf-breadcrumbs__item::before {
	content: "\2039"; /* ‹ */
}
.yf-breadcrumbs__link {
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
	transition: color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-breadcrumbs__link:hover,
.yf-breadcrumbs__link:focus-visible {
	color: var(--wp--preset--color--accent-soft);
}
.yf-breadcrumbs__current {
	color: var(--wp--preset--color--ink);
	font-weight: 600;
}
@media (max-width: 781px) {
	.yf-breadcrumbs-bar {
		padding-inline: var(--wp--custom--yf--gutter-mobile, 24px);
	}
}

/* Single hero — byline row sits on the image area, so
   colours flow from the on-image palette. */
.yf-single__byline {
	color: var(--wp--preset--color--on-image);
}
.yf-single__byline .wp-block-avatar img,
.yf-single__byline-avatar img {
	border-radius: 50%;
	display: block;
}
.yf-single__byline-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 13px;
	font-weight: 600;
	color: var(--wp--preset--color--on-image);
}
.yf-single__byline-date {
	margin: 0;
	color: rgba(244, 238, 227, 0.7);
}

/* Hide the post-excerpt block's "Read more" link when the
   excerpt is acting as the hero dek. */
.yf-hero5b__below .wp-block-post-excerpt {
	margin: 0;
}
.yf-hero5b__below .wp-block-post-excerpt__more-link {
	display: none;
}
.yf-hero5b__below .wp-block-post-excerpt__excerpt,
.yf-hero5b__below .wp-block-post-excerpt p {
	margin: 0;
	max-width: 720px;
	font-family: var(--wp--preset--font-family--body);
	font-size: 22px;
	line-height: 1.5;
	font-style: italic;
	color: var(--wp--preset--color--ink-soft);
}

/* ─── Body + rail two-column layout ───────────── */
.yf-single__body {
	background: var(--wp--preset--color--paper);
}
/* Post-content typography (font-family/size/line-height) is
   set in theme.json under styles.blocks.core/post-content so
   the post editor and Site Editor see the same body size as
   the front end. Only the in-content spacing (which theme.json
   cannot scope per child) lives here.
   Descendant — not direct-child — selectors so editors can
   wrap content in groups, columns, or covers without breaking
   the rhythm. */
.yf-single__main .wp-block-post-content p {
	margin: 0 0 32px;
}
.yf-single__main .wp-block-post-content .wp-block-heading {
	margin-top: 56px;
	margin-bottom: 24px;
}

/* ─── Rail v4 — sticky, inline in single.html ─── */
.yf-rail4 {
	display: flex;
	flex-direction: column;
	gap: 64px;
	position: sticky;
	top: 32px;
	counter-reset: yf-rail-modules;
}
.yf-rail4__module {
	position: relative;
	counter-increment: yf-rail-modules;
}
.yf-rail4__label {
	margin: 0 0 22px;
	padding-bottom: 14px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 17px;
	font-style: italic;
	font-weight: 400;
	color: var(--wp--preset--color--ink);
	letter-spacing: -0.01em;
	border-bottom: 1.5px solid var(--wp--preset--color--ink);
}
/* Generate the numeric prefix (i/ii/iii/iv/v/vi) via CSS counter
   rather than an inline <span> baked into the heading content.
   Keeps the heading block's editable text clean ("Contents",
   not "iContents"), and re-orderings auto-renumber. */
.yf-rail4__label::before {
	content: counter(yf-rail-modules, lower-roman);
	display: inline-block;
	margin-right: 10px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 11px;
	font-style: italic;
	color: var(--wp--preset--color--accent);
	letter-spacing: 0;
	text-transform: lowercase;
	vertical-align: baseline;
}
.yf-rail4__placeholder {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: 14px;
	line-height: 1.55;
	font-style: italic;
	color: var(--wp--preset--color--ink-mute);
}
.yf-rail4__author .wp-block-avatar img {
	border-radius: 50%;
	display: block;
}
.yf-rail4__author-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 13px;
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}
.yf-rail4__slot {
	margin: 0;
	padding: 28px 16px;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 12px;
	background: var(--wp--preset--color--paper-soft);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
	text-align: center;
}
.yf-rail4__share-item {
	margin: 0;
	padding: 10px 16px;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-soft);
	line-height: 1;
}

/* ─── Endmatter inline within main column ───────
   Per Batch 14: per user direction, tags + author bio
   are template-managed surfaces placed directly after
   `wp:post-content` inside the main column of the
   body grid — they are part of the continuous reading
   flow, not a detached endmatter wrapper. Spacing
   uses `margin-top` rather than a parent container's
   padding so post-content's own bottom margin
   collapses cleanly into the gap.                       */
.yf-endmatter__kicker {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-single__main .yf-single__tags-row {
	margin-top: 80px;
	padding-top: 28px;
	border-top: 1px solid var(--wp--preset--color--rule);
}
.yf-single__tags-row .wp-block-post-terms {
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
}
.yf-single__tags-row .wp-block-post-terms a {
	display: inline-block;
	margin-right: 4px;
	padding: 6px 12px;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 999px;
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
}
.yf-single__main .yf-single__author-box {
	margin-top: 56px;
	padding-top: 40px;
	border-top: 1px solid var(--wp--preset--color--rule);
}
.yf-single__author-avatar img {
	width: 76px;
	height: 76px;
	border-radius: 50%;
	display: block;
	flex-shrink: 0;
}
.yf-single__author-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 28px;
	font-style: italic;
	font-weight: 400;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}
.yf-single__author-bio {
	margin: 0;
	max-width: 580px;
	font-family: var(--wp--preset--font-family--body);
	font-size: 17px;
	line-height: 1.6;
	color: var(--wp--preset--color--ink-soft);
}

/* ─── Inline (post-content-end) monetization slot ───
   Per user direction in Batch 14: monetization
   placeholders are planned but must not destroy
   editorial flexibility. This single template-level
   ad slot sits between `wp:post-content` and the
   tags row so editors retain a fully free article
   body. Authored in-content ads can additionally use
   `.yf-ad` / `.yf-ad__slot` (defined below).            */
.yf-single__main .yf-single__inline-ad {
	margin-top: 64px;
	padding: 28px 0 20px;
	border-top: 1px solid var(--wp--preset--color--rule);
	border-bottom: 1px solid var(--wp--preset--color--rule);
	text-align: center;
}
.yf-single__inline-ad-label {
	margin: 0 0 16px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 600;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-single__inline-ad-slot {
	margin: 0;
	padding: 56px 16px;
	background: var(--wp--preset--color--paper-deep);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--ink-faint);
}

/* ─── Single hero variant (Hero B at 520 px height
   per V5 SinglePostV5.jsx imageHeight=520) ─────────── */
.yf-hero5b--single > .yf-hero5b__image {
	position: relative;
	width: 100%;
	/* BATCH-C-CORE-REMAINDER Family C: inner-height axis var-ized (fallback = baseline
	   520/420/320 → 0px even with no variant). is-style-hero-inner-* on the section sets
	   --yf-hero-inner-h{,-t,-m} so the editor controls the inner image height across all
	   3 breakpoints (op-clarif #3). */
	height: var(--yf-hero-inner-h, 520px);
	overflow: hidden;
	isolation: isolate;
	background-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--on-image);
	/* Phase 7C-R3-FS Item A: flex column so the over-image content (header at
	   top, kicker + relocated title docked at the bottom) fills the hero height
	   regardless of the per-breakpoint image height. */
	display: flex;
	flex-direction: column;
}
.yf-hero5b--single > .yf-hero5b__image > .wp-block-post-featured-image.yf-hero5b__bg {
	position: absolute;
	inset: 0;
	margin: 0;
	z-index: 0;
	pointer-events: none;
}
.yf-hero5b--single > .yf-hero5b__image > .wp-block-post-featured-image.yf-hero5b__bg img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	display: block;
}
.yf-hero5b--single > .yf-hero5b__image::after {
	content: "";
	position: absolute;
	inset: 0;
	/* Phase 7C-R3-FS Item A: ONE coherent single-hero scrim. Top band keeps the
	   header legible; the strengthened BOTTOM band (0.62) keeps the relocated
	   over-image title readable over BOTH light and dark featured images. */
	background: linear-gradient(
		180deg,
		rgba(28, 24, 20, 0.45) 0%,
		rgba(28, 24, 20, 0)    35%,
		rgba(28, 24, 20, 0.62) 100%
	);
	pointer-events: none;
	z-index: 1;
}

/* Phase 7C-R3-FS · Item A — relocated single post-title, OVER the featured image.
   The post-title now lives inside .yf-hero5b__image-content (single only). The
   image-content fills the hero (flex column): header at the top; kicker + title
   docked at the bottom via margin-block-start:auto, over the strengthened scrim.
   Scoped to .yf-hero5b--single so the shared .yf-hero5b__title base rules (used
   nowhere else now) and other templates are untouched. Logical props → RTL safe. */
.yf-hero5b--single .yf-hero5b__image-content {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	min-height: 0;
}
.yf-hero5b--single .yf-hero5b__image-content .yf-hero5b__kicker {
	/* !important required to beat the base `.yf-hero5b__kicker { margin:0 !important }`
	   so the flex auto-margin can dock kicker + title to the bottom of the image,
	   over the strengthened bottom scrim (best legibility), matching F3 page hero. */
	margin-block-start: auto !important;
}
.yf-hero5b--single .yf-hero5b__image-content .yf-hero5b__title {
	margin: 2px 0 0;
	padding-inline: clamp(24px, 5vw, 64px);
	padding-block-end: clamp(20px, 3vw, 44px);
	font-size: clamp(2rem, 4.5vw + 1rem, 4.75rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	text-wrap: balance;
	/* Solid on-image white — override the straddle split-gradient text-clip. */
	background: none;
	-webkit-background-clip: border-box;
	background-clip: border-box;
	-webkit-text-fill-color: var(--wp--preset--color--on-image);
	color: var(--wp--preset--color--on-image);
	filter: drop-shadow(0 2px 14px rgba(0, 0, 0, 0.5));
	pointer-events: none; /* decorative display title never intercepts header/control clicks */
}

/* Hero row separator — V5 source places a 1×36 vertical
   rule between BigMediaCTA group and the byline group
   inside the hero row. Implemented as a `::before` on
   the byline so no extra empty paragraph is needed in
   the markup. Hidden when the row wraps to a single
   column on mobile. */
.yf-hero5b__row > .yf-single__byline::before {
	content: "";
	display: block;
	width: 1px;
	height: 36px;
	background: var(--wp--preset--color--rule);
	flex-shrink: 0;
}

/* ─── Body grid width override — refined per Batch 16.
   Reading column stays the priority surface (cap 760px);
   rail is narrower than the V5 source spec so it stays
   supportive, not dominant. The 240 px desktop rail is
   wide enough to host the CrossCard (4:5 aspect-ratio
   image), the rail-author cluster (avatar 56 + meta
   stack), the 4 × 40 px share icon row (≈184 px), and
   the rail labels — but ~25 % narrower than V5's 320 px
   and matches typical editorial-site rail widths (NYT
   ~250 / Medium ~228 / The Verge ~272). Tablet collapses
   the rail further to 200 px and disengages the sticky
   behaviour (see media query below). Body and rail still
   stack on mobile via the ≤900 px block. */
/* Batch 27.2 — rail position + width.
   The rail sits on the RIGHT of the body grid in both LTR and
   RTL pages. The two-column wp:columns block is forced to LTR
   visual order via `direction: ltr` on the container so RTL
   pages (Arabic) do not flip the rail to the left; the children
   keep their own RTL direction so the text inside both columns
   still flows right-to-left in Arabic. Width changes:
     - rail narrowed 240 px → 200 px
     - main reading column widened 760 px → 820 px
     - column-gap is supplied by the wp:columns block (96 px)
   Net effect: article content gains ~60 px of horizontal space
   for body text and inline images, while the rail loses ~40 px;
   the rail's visual centre of mass moves toward the right edge
   of the body grid. */
.yf-single__columns.wp-block-columns {
	max-width: 1280px;
	margin-left: auto;
	margin-right: auto;
	align-items: flex-start;
	direction: ltr;
}
[dir="rtl"] .yf-single__main.wp-block-column,
[dir="rtl"] .yf-single__rail-col.wp-block-column {
	direction: rtl;
}
.yf-single__main.wp-block-column {
	flex: 1 1 auto;
	flex-basis: auto;
	max-width: 820px;
	min-width: 0;
}
.yf-single__rail-col.wp-block-column {
	flex: 0 0 200px;
	flex-basis: 200px;
	max-width: 200px;
}

/* ─── Rail v4 — Written by author meta line ─── */
.yf-rail4__author-meta {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ink-mute);
}

/* ─── Rail v4 — Save & share — V5 circle-icon
   buttons (40×40 round, 1 px ink-rule border, CSS
   mask-image icons on `::before`). Markup is plain
   `wp:paragraph` per share-item to stay KSES-safe;
   the icon glyph is supplied by CSS so no inline
   `<svg>` survives the editor save round-trip.       */
.yf-rail4__share {
	gap: 8px !important;
}
.yf-rail4__share-item {
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	text-transform: none;
	letter-spacing: 0;
	font-weight: 400;
	line-height: 1;
}
.yf-rail4__share-item a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 50%;
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
	font-size: 0;
	line-height: 0;
	letter-spacing: 0;
	transition:
		color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		background-color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-rail4__share-item a::before {
	content: "";
	display: block;
	width: 14px;
	height: 14px;
	background-color: currentColor;
	-webkit-mask-position: center;
	        mask-position: center;
	-webkit-mask-repeat: no-repeat;
	        mask-repeat: no-repeat;
	-webkit-mask-size: contain;
	        mask-size: contain;
}
.yf-rail4__share-item a:hover {
	background: var(--wp--preset--color--ink);
	border-color: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
}
.yf-rail4__share-item--save a::before {
	-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><path d='M3 1.5h8v11l-4-3-4 3z'/></svg>");
	        mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><path d='M3 1.5h8v11l-4-3-4 3z'/></svg>");
}
.yf-rail4__share-item--share a::before {
	-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><circle cx='10.5' cy='3' r='2'/><circle cx='3.5' cy='7' r='2'/><circle cx='10.5' cy='11' r='2'/><path d='M5.3 6l3.4-2M5.3 8l3.4 2'/></svg>");
	        mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><circle cx='10.5' cy='3' r='2'/><circle cx='3.5' cy='7' r='2'/><circle cx='10.5' cy='11' r='2'/><path d='M5.3 6l3.4-2M5.3 8l3.4 2'/></svg>");
}
.yf-rail4__share-item--print a::before {
	-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><path d='M3.5 5.5V1.5h7v4M3 5.5h8v5H3zM4.5 9.5h5v3h-5z'/></svg>");
	        mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><path d='M3.5 5.5V1.5h7v4M3 5.5h8v5H3zM4.5 9.5h5v3h-5z'/></svg>");
}
.yf-rail4__share-item--copy a::before {
	-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><rect x='2' y='4' width='7' height='8'/><path d='M5 2h7v8'/></svg>");
	        mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><rect x='2' y='4' width='7' height='8'/><path d='M5 2h7v8'/></svg>");
}

/* ─── End-of-article: Cross-category band (ink) ─── */
.yf-single__cross-band {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--on-image);
}
.yf-single__cross-band__inner {
	max-width: 1280px;
	margin: 0 auto;
}
.yf-single__cross-band__header {
	margin: 0 0 36px;
}
.yf-single__cross-band__heading {
	margin: 0;
}
.yf-single__cross-band__kicker {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent-quiet);
}
.yf-single__cross-band__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 44px;
	font-style: italic;
	font-weight: 400;
	line-height: 1.05;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--paper);
}
.yf-single__cross-band__count {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	color: rgba(244, 238, 227, 0.5);
}
.yf-single__cross-band__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 28px;
}

/* CrossCard — full-bleed image + scrim + bottom-anchored
   from-line / title / meta. Used in the side rail's
   "From elsewhere" module AND in the end-of-article ink
   band's 3-up grid. Identical shape across both. */
.yf-cross {
	position: relative;
	border-radius: 16px;
	overflow: hidden;
	background: var(--wp--preset--color--ink);
	aspect-ratio: 4 / 5;
}
.yf-cross__img {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	background-color: var(--wp--preset--color--paper-deep);
}
.yf-cross__scrim {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(28, 24, 20, 0.15) 0%, rgba(28, 24, 20, 0.85) 100%);
	pointer-events: none;
}
.yf-cross__content {
	position: absolute;
	left: 22px;
	right: 22px;
	bottom: 22px;
	color: var(--wp--preset--color--on-image);
}
.yf-cross__from {
	margin: 0 0 12px;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent-soft);
}
.yf-cross__from::before {
	content: "";
	display: inline-block;
	width: 14px;
	height: 1.5px;
	background: var(--wp--preset--color--accent-soft);
}
.yf-cross__title {
	margin: 0 0 6px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 24px;
	line-height: 1.12;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--on-image);
}
.yf-cross__meta {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	letter-spacing: 0.06em;
	color: rgba(244, 238, 227, 0.7);
}

/* ─── End-of-article: Same-category Related band (paper-deep) ─── */
.yf-single__related-band {
	background: var(--wp--preset--color--paper-deep);
}
.yf-single__related-band__inner {
	max-width: 1280px;
	margin: 0 auto;
}
.yf-single__related-band__header {
	margin: 0 0 48px;
}
.yf-single__related-band__heading {
	margin: 0;
}
.yf-single__related-band__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 48px;
	font-style: italic;
	font-weight: 400;
	line-height: 1.05;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}
.yf-single__related-band__count {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ink-mute);
}
.yf-single__related-band__grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 32px;
}

/* Card System 2 — caption block + stamp + accent reveal
   (V5 `Card5_2` in `SharedV5.jsx` / `.yf-card5-2__*` in
   `system-v5.css`). Used in the same-category band AND
   available for editors to author inline inside post
   content via the standard wp:group + classes pattern. */
.yf-card5-2 {
	position: relative;
	display: flex;
	flex-direction: column;
	cursor: pointer;
	transition: transform 0.45s var(--wp--custom--yf--easing--glide, cubic-bezier(.22,.61,.36,1));
}
.yf-card5-2::after {
	content: "";
	position: absolute;
	left: 0;
	right: 100%;
	bottom: -10px;
	height: 2px;
	background: var(--wp--preset--color--accent);
	transition: right 0.55s var(--wp--custom--yf--easing--glide, cubic-bezier(.22,.61,.36,1));
}
.yf-card5-2:hover {
	transform: translateY(-3px);
}
.yf-card5-2:hover::after {
	right: 0;
}
.yf-card5-2__img {
	width: 100%;
	aspect-ratio: 4 / 5;
	background-size: cover;
	background-position: center;
	background-color: var(--wp--preset--color--paper-deep);
	border-radius: 14px;
	overflow: hidden;
	transition: transform 1.4s var(--wp--custom--yf--easing--glide, cubic-bezier(.22,.61,.36,1));
}
.yf-card5-2:hover .yf-card5-2__img {
	transform: scale(1.04);
}
.yf-card5-2__caption {
	position: relative;
	margin: -28px 16px 0;
	padding: 22px 22px 18px;
	background: var(--wp--preset--color--paper);
	border-radius: 12px;
	box-shadow: 0 12px 28px rgba(28, 24, 20, 0.08);
	transition:
		transform 0.45s var(--wp--custom--yf--easing--glide, cubic-bezier(.22,.61,.36,1)),
		box-shadow 0.45s var(--wp--custom--yf--easing--glide, cubic-bezier(.22,.61,.36,1));
}
.yf-card5-2:hover .yf-card5-2__caption {
	transform: translateY(-4px);
	box-shadow: 0 20px 44px rgba(28, 24, 20, 0.12);
}
.yf-card5-2__stamp {
	position: absolute;
	top: -14px;
	right: 14px;
	margin: 0;
	padding: 6px 12px;
	background: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 9px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	border-radius: 999px;
	transform: rotate(-3deg);
	transition: transform 0.35s var(--wp--custom--yf--easing--snap, cubic-bezier(.34,1.16,.44,1));
	box-shadow: 0 4px 12px rgba(160, 59, 42, 0.3);
	z-index: 2;
}
.yf-card5-2:hover .yf-card5-2__stamp {
	transform: rotate(0deg) translateY(-2px);
}
.yf-card5-2__kicker {
	margin: 0 0 10px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}
.yf-card5-2__title {
	margin: 0 0 10px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 24px;
	line-height: 1.14;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}
.yf-card5-2__meta {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ink-mute);
}

/* ─── Editor-authored body patterns ─────────────────────
   The article body (`wp:post-content`) remains fully
   editable; these classes give editors styled hooks for
   the inline patterns the V5 source demonstrates (drop
   cap, section heading rhythm, pull quote, FAQ details,
   in-article ad, captions, accent links, pills). Editors
   add them via the standard wp:group / wp:paragraph /
   wp:heading + custom-class workflow — the template does
   NOT pre-slot them so editorial composition stays free.
   ────────────────────────────────────────────────────── */
.yf-single__main .wp-block-post-content .yf-dropcap::first-letter,
.yf-single__main .wp-block-post-content p.yf-dropcap::first-letter {
	font-family: var(--wp--preset--font-family--display);
	font-size: 5.2em;
	float: left;
	line-height: 0.86;
	padding: 8px 12px 0 0;
	color: var(--wp--preset--color--ink);
	font-weight: 400;
}
.yf-single__main .wp-block-post-content .yf-section-h2 {
	margin: 56px 0 24px;
}
.yf-single__main .wp-block-post-content .yf-section-h2 .yf-section-h2__kicker {
	display: flex;
	align-items: center;
	gap: 12px;
	margin-bottom: 16px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-single__main .wp-block-post-content .yf-section-h2 .yf-section-h2__kicker::before {
	content: "";
	display: block;
	flex-shrink: 0;
	width: 24px;
	height: 1px;
	background: var(--wp--preset--color--accent);
}
.yf-single__main .wp-block-post-content .yf-section-h2 h2 {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 36px;
	line-height: 1.12;
	font-style: italic;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}
.yf-single__main .wp-block-post-content .yf-pullquote {
	margin: 64px 0;
	padding: 56px 72px;
	background: var(--wp--preset--color--accent-soft);
	border-radius: 18px;
	text-align: center;
	position: relative;
	overflow: hidden;
}
.yf-single__main .wp-block-post-content .yf-pullquote::before {
	content: "";
	position: absolute;
	top: -60px;
	left: -40px;
	width: 200px;
	height: 200px;
	border: 1.5px solid var(--wp--preset--color--accent);
	border-radius: 50%;
	opacity: 0.25;
	pointer-events: none;
}
.yf-single__main .wp-block-post-content .yf-pullquote p {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 38px;
	font-style: italic;
	line-height: 1.18;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
	text-wrap: balance;
	position: relative;
}
.yf-single__main .wp-block-post-content .yf-pullquote cite,
.yf-single__main .wp-block-post-content .yf-pullquote figcaption {
	display: block;
	margin-top: 28px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	font-style: normal;
	color: var(--wp--preset--color--ink-soft);
	position: relative;
}
.yf-single__main .wp-block-post-content .yf-ad {
	margin: 64px 0;
	padding: 32px 0 24px;
	border-top: 1px solid var(--wp--preset--color--rule);
	border-bottom: 1px solid var(--wp--preset--color--rule);
	text-align: center;
}
.yf-single__main .wp-block-post-content .yf-ad .yf-ad__label {
	margin: 0 0 20px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 600;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-single__main .wp-block-post-content .yf-ad .yf-ad__slot {
	margin: 0;
	padding: 96px 16px;
	background: var(--wp--preset--color--paper-deep);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--ink-faint);
}
.yf-single__main .wp-block-post-content figcaption.yf-caption,
.yf-single__main .wp-block-post-content .yf-caption {
	margin-top: 12px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.04em;
	color: var(--wp--preset--color--ink-mute);
}
.yf-single__main .wp-block-post-content .yf-meta {
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ink-mute);
}
.yf-single__main .wp-block-post-content a.yf-link,
.yf-single__main .wp-block-post-content .yf-link {
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	transition: color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-single__main .wp-block-post-content a.yf-link:hover,
.yf-single__main .wp-block-post-content .yf-link:hover {
	color: var(--wp--preset--color--accent-hover);
}
.yf-single__main .wp-block-post-content .yf-pill {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 14px;
	background: var(--wp--preset--color--paper);
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 500;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--ink-soft);
}
.yf-single__main .wp-block-post-content details.yf-faq,
.yf-single__main .wp-block-post-content .yf-faq {
	border-bottom: 1px solid var(--wp--preset--color--rule);
}
.yf-single__main .wp-block-post-content details.yf-faq:first-of-type,
.yf-single__main .wp-block-post-content .yf-faq:first-of-type {
	border-top: 1px solid var(--wp--preset--color--rule);
}
.yf-single__main .wp-block-post-content details.yf-faq > summary {
	padding: 24px 36px 24px 0;
	cursor: pointer;
	list-style: none;
	position: relative;
	font-family: var(--wp--preset--font-family--display);
	font-size: 24px;
	line-height: 1.25;
	font-style: italic;
	color: var(--wp--preset--color--ink);
}
.yf-single__main .wp-block-post-content details.yf-faq > summary::-webkit-details-marker {
	display: none;
}
.yf-single__main .wp-block-post-content details.yf-faq > summary::after {
	content: "+";
	position: absolute;
	right: 4px;
	top: 24px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 22px;
	font-weight: 300;
	color: var(--wp--preset--color--ink-mute);
	line-height: 1;
}
.yf-single__main .wp-block-post-content details.yf-faq[open] > summary::after {
	content: "\2013";
}

/* ============================================================
   Checkpoint 2 — single-post integration surfaces.

   CSS for the new structural pieces wired in this checkpoint:
   - Hero byline meta-row (date + reading-time badge + fact-
     checked badge)
   - Rail TOC (yf-toc) rendered by [yoyafun_toc] shortcode
   - Front-of-article FTC affiliate disclosure block
   - End-of-article sources list
   - AdSense slot placeholder visual + sticky-mobile footer ad
   - Footer 3-column nav + brand block + bottom row

   All scoped to either the single-post body (.yf-single__main),
   the rail (.yf-rail4), the hero byline (.yf-single__byline),
   or the footer (.yf-footer) — no leakage into other surfaces.
   ============================================================ */

/* ─── Hero byline — meta row ───────────────────── */
.yf-single__byline-meta-row {
	color: rgba(244, 238, 227, 0.7);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	line-height: 1.2;
}
.yf-single__byline-meta-row .wp-block-post-date,
.yf-single__byline-meta-row .yf-single__byline-date {
	color: inherit;
}
.yf-meta-badge {
	display: inline-flex;
	align-items: center;
	color: inherit;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	line-height: 1.2;
}
.yf-meta-badge--reading-time::before,
.yf-meta-badge--fact-checked::before {
	content: "·";
	margin-right: 10px;
	opacity: 0.5;
}
.yf-meta-badge--fact-checked {
	font-style: italic;
}

/* ─── Rail TOC — emitted by [yoyafun_toc] inside the
   "Contents" rail module. Pure HTML (no block markup),
   so we target the raw <nav>/<details>/<summary>/<ol>
   directly inside the rail's `--toc` modifier scope.   */
.yf-rail4__module--toc .yf-toc {
	margin: 0;
}
.yf-rail4__module--toc .yf-toc__details {
	margin: 0;
}
.yf-rail4__module--toc .yf-toc__h {
	display: none;
	/* Hidden because the rail label heading ("Contents") already
	   provides the title; <summary> is required by <details> so we
	   keep it semantically present but visually suppressed. */
}
.yf-rail4__module--toc .yf-toc__list {
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: yf-toc;
	display: flex;
	flex-direction: column;
	gap: 8px;
}
.yf-rail4__module--toc .yf-toc__list li {
	counter-increment: yf-toc;
	display: grid;
	grid-template-columns: 28px 1fr;
	gap: 8px;
	align-items: baseline;
	padding: 6px 0;
	border-bottom: 1px solid var(--wp--preset--color--rule);
}
.yf-rail4__module--toc .yf-toc__list li:last-child {
	border-bottom: 0;
}
.yf-rail4__module--toc .yf-toc__list li::before {
	content: counter(yf-toc, decimal-leading-zero);
	font-family: var(--wp--preset--font-family--display);
	font-size: 11px;
	font-style: italic;
	color: var(--wp--preset--color--accent);
}
.yf-rail4__module--toc .yf-toc__list a {
	font-family: var(--wp--preset--font-family--body);
	font-size: 14px;
	line-height: 1.4;
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
	transition: color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-rail4__module--toc .yf-toc__list a:hover {
	color: var(--wp--preset--color--accent);
}

/* ─── FTC affiliate disclosure (front-of-article).
   Auto-injected via the_content filter when ACF
   `yoya_is_affiliate` is truthy. Lives inside
   `wp:post-content` so the existing scope
   `.yf-single__main .wp-block-post-content …` selectors
   compose with it. */
.yf-single__main .wp-block-post-content .yf-ftc-disclosure {
	margin: 0 0 40px;
	padding: 18px 22px;
	background: var(--wp--preset--color--accent-soft);
	border-left: 3px solid var(--wp--preset--color--accent);
	border-radius: 8px;
}
[dir="rtl"] .yf-single__main .wp-block-post-content .yf-ftc-disclosure {
	border-left: 0;
	border-right: 3px solid var(--wp--preset--color--accent);
}
.yf-single__main .wp-block-post-content .yf-ftc-disclosure__text {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 13px;
	line-height: 1.55;
	color: var(--wp--preset--color--ink);
}
.yf-single__main .wp-block-post-content .yf-ftc-disclosure__text strong {
	font-weight: 700;
	color: var(--wp--preset--color--accent);
	margin-right: 6px;
}
[dir="rtl"] .yf-single__main .wp-block-post-content .yf-ftc-disclosure__text strong {
	margin-right: 0;
	margin-left: 6px;
}

/* ─── End-of-article sources list (auto-injected
   when ACF `yoya_sources` repeater is non-empty). */
.yf-single__main .wp-block-post-content .yf-sources {
	margin: 56px 0 0;
	padding: 32px 0 0;
	border-top: 1px solid var(--wp--preset--color--rule);
}
.yf-single__main .wp-block-post-content .yf-sources__title {
	margin: 0 0 18px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-single__main .wp-block-post-content .yf-sources__list {
	margin: 0;
	padding: 0;
	padding-inline-start: 22px;
	list-style: decimal;
	font-family: var(--wp--preset--font-family--body);
	font-size: 15px;
	line-height: 1.6;
	color: var(--wp--preset--color--ink-soft);
}
.yf-single__main .wp-block-post-content .yf-sources__list li {
	margin-bottom: 8px;
}
.yf-single__main .wp-block-post-content .yf-sources__list li:last-child {
	margin-bottom: 0;
}
.yf-single__main .wp-block-post-content .yf-sources__list a {
	color: var(--wp--preset--color--accent);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	word-break: break-word;
}

/* ─── AdSense slot — generic placeholder visual.
   The `data-yf-slot-id` attribute is injected at
   render time by inc/adsense.php based on the
   className marker `yf-ad-slot--<id>` on the wp:group.
   Visual: centered slot box with dashed border + small
   ink-mute label, calm enough to read as a structural
   placeholder until a real ad unit ships. */
.yf-ad-slot.yf-adsense {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 12px;
	min-height: 120px;
	margin: 32px 0;
	padding: 20px;
	background: var(--wp--preset--color--paper-soft);
	border: 1px dashed var(--wp--preset--color--rule-strong);
	border-radius: 8px;
	text-align: center;
}
.yf-ad-slot.yf-adsense .yf-ad-slot__label,
.yf-ad-slot.yf-adsense p {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
/* Rail-context override: the rail Sponsored module uses
   `.yf-ad-slot--sidebar-mid` and lives inside `.yf-rail4`.
   Match the rail's calmer vertical rhythm and remove the
   redundant outer dashed border (the rail module's own
   label provides the boundary). */
.yf-rail4__module--sponsored.yf-ad-slot {
	display: block;
	min-height: 0;
	margin: 0;
	padding: 0;
	background: transparent;
	border: 0;
}
.yf-rail4__module--sponsored .yf-rail4__slot {
	margin: 0;
	min-height: 220px;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px 12px;
	background: var(--wp--preset--color--paper-soft);
	border: 1px dashed var(--wp--preset--color--rule-strong);
	border-radius: 8px;
}

/* ---------------------------------------------------------------
   Manual sticky-mobile-footer AdSense rules: REMOVED at Mega-Wave-3
   sub-phase MW3.19 per OQ-SS04-01 + OQ-SS04-03. Both the
   inc/adsense.php render function and the corresponding CSS
   compound selectors + dismiss-button styles were deleted. AdSense
   Auto Ads Anchor (configured at the dashboard, M1-F2 manual phase
   MW3.37) provides the equivalent mobile sticky behavior.
   --------------------------------------------------------------- */

/* ─── Footer (real 3-column nav port from old theme).
   V5 visual treatment: paper-deep background, ink type,
   compact UI font for nav lists, two-span brand mark in
   the brand block, calm bottom rule for copyright row. */
.yf-footer {
	color: var(--wp--preset--color--ink);
}
.yf-footer__top {
	max-width: 1280px;
	margin: 0 auto;
}
/* Brand block — logo + tagline + Subscribe CTA. */
.yf-footer__logo {
	margin: 0 0 14px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 32px;
	font-weight: 400;
	letter-spacing: -0.02em;
	line-height: 1;
}
.yf-footer__logo a {
	display: inline-flex;
	align-items: baseline;
	gap: 2px;
	color: inherit;
	text-decoration: none;
}
.yf-footer__logo-yoya {
	font-style: italic;
	color: var(--wp--preset--color--ink);
}
.yf-footer__logo-fun {
	font-style: normal;
	color: var(--wp--preset--color--accent);
}
.yf-footer__tag {
	margin: 0 0 24px;
	max-width: 36ch;
	font-family: var(--wp--preset--font-family--body);
	font-size: 15px;
	line-height: 1.5;
	font-style: italic;
	color: var(--wp--preset--color--ink-soft);
}
.yf-footer__cta-row.wp-block-buttons {
	margin: 0;
}
.yf-footer__cta.wp-block-button .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--ink);
	border: 1px solid var(--wp--preset--color--ink);
	padding: 10px 18px;
	border-radius: var(--wp--custom--yf--radius--pill, 999px);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	line-height: 1;
	transition:
		background-color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-footer__cta.wp-block-button .wp-block-button__link:hover {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
}

/* Nav columns — 3 inline columns inside the 60% nav-col. */
.yf-footer__cols.wp-block-columns {
	gap: 32px;
}
.yf-footer__col-title {
	margin: 0 0 18px;
	padding-bottom: 12px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink);
	border-bottom: 1px solid var(--wp--preset--color--rule);
}
.yf-footer__nav.wp-block-list {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: 10px;
}
.yf-footer__nav.wp-block-list li {
	margin: 0;
}
.yf-footer__nav.wp-block-list a {
	font-family: var(--wp--preset--font-family--ui);
	font-size: 13px;
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
	transition: color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-footer__nav.wp-block-list a:hover {
	color: var(--wp--preset--color--accent);
}

/* Bottom row — copyright + disclosure. */
.yf-footer__bottom {
	max-width: 1280px;
	margin: 56px auto 0;
}
.yf-footer__copyright,
.yf-footer__disclosure {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--ink-mute);
	text-transform: uppercase;
}
.yf-footer__disclosure {
	font-style: italic;
	text-transform: none;
	letter-spacing: 0.04em;
}

@media (max-width: 900px) {
	/* Content-derived responsive logic — one layout breakpoint,
	   fluid scaling within.
	   Anchors: vw=360 (narrow floor) → vw=900 (just-before-desktop).
	   Every magnitude (paddings, type, gaps, CTA size) interpolates
	   smoothly between those endpoints via clamp(MIN, fluid, MAX),
	   so the same logic adapts at any width — not just preset device
	   sizes. Layout structure (outer stacks, inner 3-col grid, bottom
	   stacks) does not change inside this band; only magnitudes do. */
	.yf-footer {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-top: clamp(40px, 3vw + 28px, 56px) !important;
		padding-bottom: clamp(24px, 1.5vw + 18px, 32px) !important;
	}
	/* Outer brand|nav-col split: brand stacks above nav-col across
	   this whole band. The gap between them flows from 16px @360
	   to 28px @900 — tight on phones, more generous on tablets. */
	.yf-footer__columns.wp-block-columns {
		flex-wrap: wrap;
		gap: clamp(16px, 2.2vw + 8px, 28px);
	}
	.yf-footer__columns > .wp-block-column {
		flex-basis: 100% !important;
	}
	/* Inner nav: 3 adjacent columns at every viewport in this band.
	   Dropping to 2 cols (forcing one item to wrap to row 2) is what
	   reintroduces the stacked-list silhouette — so we hold 3-up and
	   absorb any tightness via fluid type below. Some 2-line wrap on
	   the longest two-word labels at the narrowest widths is the
	   accepted content cost. */
	.yf-footer__cols.wp-block-columns {
		display: grid;
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: clamp(12px, 1.5vw + 7px, 20px);
	}
	.yf-footer__cols > .wp-block-column {
		flex-basis: auto !important;
		width: auto !important;
	}
	/* Brand block — quieter at narrow widths, breathes at tablet. */
	.yf-footer__logo {
		font-size: clamp(20px, 1.5vw + 15px, 28px);
		margin-bottom: clamp(4px, 1.1vw, 10px);
	}
	.yf-footer__tag {
		font-size: clamp(12px, 0.5vw + 10px, 14px);
		line-height: 1.4;
		max-width: 44ch;
		margin-bottom: clamp(8px, 1.5vw + 3px, 16px);
	}
	.yf-footer__cta.wp-block-button .wp-block-button__link {
		font-size: clamp(9px, 0.3vw + 8px, 10px);
		padding: clamp(6px, 0.5vw + 4px, 8px) clamp(12px, 1.3vw + 7px, 18px);
		letter-spacing: 0.12em;
	}
	/* Col titles — drop the per-column rule on mobile/tablet.
	   Multiple stacked kicker-rules read as separate sections; binding
	   the three columns into one visual band is what makes the nav
	   feel like a single block. */
	.yf-footer__col-title {
		font-size: clamp(9px, 0.3vw + 8px, 10px);
		letter-spacing: 0.16em;
		margin-bottom: clamp(6px, 0.85vw + 3px, 10px);
		padding-bottom: 0;
		border-bottom: 0;
	}
	.yf-footer__nav.wp-block-list {
		gap: clamp(4px, 0.7vw + 1.5px, 8px);
	}
	.yf-footer__nav.wp-block-list a {
		font-size: clamp(11px, 0.3vw + 10px, 12.5px);
		line-height: 1.3;
	}
	.yf-footer__bottom {
		flex-direction: column;
		align-items: flex-start;
		gap: clamp(2px, 0.5vw + 1px, 6px);
		margin-top: clamp(20px, 2.2vw + 12px, 32px);
	}
	.yf-footer__copyright,
	.yf-footer__disclosure {
		font-size: clamp(9px, 0.4vw + 7.5px, 10.5px);
		letter-spacing: 0.06em;
	}
}
@media (min-width: 901px) and (max-width: 1199px) {
	.yf-footer__cols.wp-block-columns {
		gap: 24px;
	}
}

/* Stack body+rail on narrower viewports and disengage the
   sticky rail so the modules read as a flat sequence after
   the article. The cross/related bands collapse to a single
   column on the same breakpoint.

   Batch 27 fix: `flex-wrap` here previously had no `!important`.
   WP's block library ships `.wp-block-columns { flex-wrap:
   nowrap !important }` inside its own `(min-width: 782px)`
   media block, which keeps the two columns side-by-side under
   shrink, forcing each to ~50% of the row even when we set
   `flex-basis: 100% !important` on the children. Adding
   `!important` here makes Yoya's wrap rule win, so the
   children actually move to two stacked rows instead of
   shrinking to a half-width pair. */
@media (max-width: 900px) {
	.yf-single__body {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-top: 64px !important;
	}
	.yf-single__columns.wp-block-columns {
		flex-wrap: wrap !important;
	}
	.yf-single__main.wp-block-column,
	.yf-single__rail-col.wp-block-column {
		flex: 1 1 100% !important;
		flex-basis: 100% !important;
		max-width: 100%;
	}
	.yf-rail4 {
		position: static;
		margin-top: 64px;
	}
	.yf-single__main .yf-single__author-box {
		flex-wrap: wrap;
	}
	.yf-single__main .wp-block-post-content {
		font-size: 18px;
	}
	.yf-single__cross-band,
	.yf-single__related-band {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
	}
	.yf-single__cross-band__grid,
	.yf-single__related-band__grid {
		grid-template-columns: 1fr;
	}
	.yf-single__cross-band__title { font-size: 34px; }
	.yf-single__related-band__title { font-size: 36px; }
	.yf-hero5b--single > .yf-hero5b__image { height: var(--yf-hero-inner-h-t, 420px); }
	.yf-hero5b__row > .yf-single__byline::before { display: none; }
	.yf-single__main .wp-block-post-content .yf-pullquote {
		margin: 48px 0;
		padding: 40px 28px;
	}
	.yf-single__main .wp-block-post-content .yf-pullquote p {
		font-size: 28px;
	}
	.yf-single__main .wp-block-post-content .yf-section-h2 h2 {
		font-size: 28px;
	}
}

/* ─── Tablet single-post — between mobile collapse (≤900 px) and
   full desktop (≥1200 px).

   Batch 27 reset: the previous tablet rule kept the two columns
   side-by-side and only narrowed the rail to 200 px. With the
   wp-block-columns block-gap of 96 px coming from the template
   and the body's 64 px side padding, the body column ended up at
   roughly 280 px on a 820 px viewport — about half the comfortable
   reading width. Tablet now stacks on the same axis as mobile:
   reading column gets the full content width, the rail follows as
   a flat sequence of modules. The rail's sticky behaviour stays
   disengaged so the modules read naturally below the body. Side
   padding lifts to 48 px so the tablet doesn't inherit the very
   tight mobile gutter, and a slightly larger top padding keeps
   the hero/body gap proportional. */
@media (min-width: 901px) and (max-width: 1199px) {
	.yf-single__body {
		padding-left: 48px !important;
		padding-right: 48px !important;
		padding-top: 80px !important;
	}
	.yf-single__columns.wp-block-columns {
		flex-wrap: wrap !important;
		gap: 64px !important;
		column-gap: 64px !important;
	}
	.yf-single__main.wp-block-column,
	.yf-single__rail-col.wp-block-column {
		flex: 1 1 100% !important;
		flex-basis: 100% !important;
		max-width: 100%;
	}
	.yf-rail4 {
		position: static;
		top: auto;
		gap: 48px;
	}
}

@media (max-width: 600px) {
	.yf-hero5b--single > .yf-hero5b__image { height: var(--yf-hero-inner-h-m, 320px); }
	.yf-single__cross-band__title { font-size: 28px; }
	.yf-single__related-band__title { font-size: 30px; }
}

/* ============================================================
   Batch 3 — Gallery foundation (structural).
   Single-gallery uses the existing Hero B classes (same as
   single.html). This section only adds:
   - calm body shell for single-gallery
   - archive page header
   - gallery card structural styling (NOT Card System 3
     choreography — that direction is chosen but deferred)
   - responsive grid breakpoints
   ============================================================ */

.yf-gallery-single__body {
	background: var(--wp--preset--color--paper);
}

/* ─── Archive page header ──────────────────────── */
.yf-gallery-archive {
	background: var(--wp--preset--color--paper);
}
.yf-gallery-archive__header {
	background: var(--wp--preset--color--paper);
}
.yf-gallery-archive__title {
	margin: 12px 0 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 60px;
	font-weight: 400;
	line-height: 1.05;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--ink);
}

/* ─── Archive grid + cards ─────────────────────── */
.yf-gallery-card {
	display: flex;
	flex-direction: column;
}
.yf-gallery-card__media img,
.yf-gallery-card .wp-block-post-featured-image img {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: 14px;
	display: block;
	background-color: var(--wp--preset--color--paper-deep);
}
.yf-gallery-card__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 24px;
	font-weight: 400;
	line-height: 1.18;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}
.yf-gallery-card__title a {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-gallery-card__title a:hover {
	color: var(--wp--preset--color--accent);
}
.yf-gallery-card__date {
	margin: 0;
}

/* Responsive grid override. wp:post-template renders an inline
   `grid-template-columns: repeat(N, minmax(0, 1fr))`, so we
   need !important to step it down at smaller viewports. */
@media (max-width: 900px) {
	.yf-gallery-archive__header {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-top: 80px !important;
		padding-bottom: 48px !important;
	}
	.yf-gallery-archive__title {
		font-size: 44px;
	}
	.yf-gallery-archive__list {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-bottom: 96px !important;
	}
	.yf-gallery-archive__grid.is-layout-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}
}
@media (max-width: 600px) {
	.yf-gallery-archive__title {
		font-size: 36px;
	}
	.yf-gallery-archive__grid.is-layout-grid {
		grid-template-columns: 1fr !important;
	}
	.yf-gallery-card__title {
		font-size: 22px;
	}
}

/* ============================================================
   Batch 4 — Page foundation (structural).
   page.html reuses the existing Hero B class system (cover,
   title-zone with gradient text-clip, below with excerpt-as-dek);
   this section only adds the page body shell + a responsive
   padding override. Page-specific typography is inherited from
   theme.json (styles.blocks.core/post-content).
   ============================================================ */

.yf-page__body {
	position: relative;
	z-index: 2;
	background: var(--wp--preset--color--paper);
}

@media (max-width: 900px) {
	.yf-page__body {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-top: 64px !important;
		padding-bottom: 96px !important;
	}
}

/* ============================================================
   Phase 7C-R3-F · F1 — Page-body align:full breakout reconciliation.
   CAUSE (not symptom): page.html renders `wp:post-content {align:full}`
   inside article.yf-page__body. The align:full post-content carries a
   fixed breakout of margin-inline:-64px (matching the 64px desktop body
   gutter). The mobile rule ABOVE drops .yf-page__body padding-inline to
   var(--wp--custom--yf--gutter-mobile,24px) at <=900px, but the breakout
   stayed at -64px, so the content extended 64-24 = 40px beyond the
   viewport at <=768 (RTL + LTR, all 17 languages; measured in
   phase7c-r3-f0 computed-CSS evidence).
   FIX: bind the breakout to the SAME gutter token the padding uses, so
   the invariant `breakout === -1 * body-padding-inline` holds at EVERY
   width — 0 overflow at any width, NOT a fixed-point hack:
     • base / desktop (>=901px): -64px == 64px inline padding (byte-identical to prior render)
     • mobile (<=900px):          -24px == 24px gutter-mobile padding (reconciled)
   Both the padding rule and this breakout rule switch at the SAME 900px
   boundary, so no viewport has a mismatched pair; the relationship holds
   continuously across the whole range, including between probe widths.
   Logical property (margin-inline) → RTL/LTR safe. No overflow hidden,
   no overflow-x:hidden, no clipping, no template/PHP/DB/content edit. */
.yf-page__body > .wp-block-post-content.alignfull {
	margin-inline: calc(-1 * var(--wp--custom--yf--gutter, 64px)) !important;
}
@media (max-width: 900px) {
	.yf-page__body > .wp-block-post-content.alignfull {
		margin-inline: calc(-1 * var(--wp--custom--yf--gutter-mobile, 24px)) !important;
	}
}

/* ============================================================
   Phase 7C-R3-F · F3 follow-up Item B — page-body content inline gutter
   on mobile/tablet. The post-content is align:full (F1 gives it
   margin-inline:-gutter so its BORDER box spans the viewport). Its
   CONSTRAINED children (paragraphs/headings, max-width 680px) collapse
   their auto side-margins to 0 once the viewport < content-size, so on
   narrow screens the text sat against the screen edges. Restore a
   comfortable gutter by padding the post-content CONTENT box at <=900px,
   and re-break any align:full child INSIDE post-content back out to the
   viewport so full-bleed blocks stay full-bleed. The F1 invariant
   (body padding === -1 * post-content breakout; 0 overflow) is untouched:
   this padding sits INSIDE post-content's border box, which still spans
   the viewport. Same 900px boundary as F1; logical props → RTL/LTR safe. */
@media (max-width: 900px) {
	.yf-page__body > .wp-block-post-content {
		padding-inline: var(--wp--custom--yf--gutter-mobile, 24px);
	}
	.yf-page__body > .wp-block-post-content > .alignfull {
		margin-inline: calc(-1 * var(--wp--custom--yf--gutter-mobile, 24px));
	}
}

/* ============================================================
   Batch 5 — Team grid pattern (calm editorial).
   Pattern lives in patterns/team-grid.php and is inserted into
   page bodies. CSS targets the pattern's BEM classes only;
   no coupling to core block class names beyond what the
   pattern's wp:group / wp:image markup already emits.
   Card System 3 choreography is deliberately NOT used here —
   Team is a calm masthead, not a marketing surface.
   ============================================================ */

.yf-team__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 44px;
	font-style: italic;
	font-weight: 400;
	line-height: 1.1;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--ink);
	max-width: 720px;
}

.yf-team-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 48px 32px;
}

.yf-team-card {
	display: flex;
	flex-direction: column;
}
.yf-team-card__portrait {
	margin: 0;
}
.yf-team-card__portrait img {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: 14px;
	display: block;
	background-color: var(--wp--preset--color--paper-deep);
}
.yf-team-card__role {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}
.yf-team-card__name {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 28px;
	font-weight: 400;
	line-height: 1.15;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}
.yf-team-card__bio {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: 16px;
	line-height: 1.6;
	color: var(--wp--preset--color--ink-soft);
	max-width: 38ch;
}
.yf-team-card__links {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-team-card__links a {
	color: inherit;
	text-decoration: none;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	padding-bottom: 1px;
	transition: color 0.2s var(--wp--custom--yf--easing--glide, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-team-card__links a:hover {
	color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

@media (max-width: 900px) {
	.yf-team__title {
		font-size: 34px;
	}
	.yf-team-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 40px 24px;
	}
}
@media (max-width: 600px) {
	.yf-team__title {
		font-size: 28px;
	}
	.yf-team-grid {
		grid-template-columns: 1fr;
		gap: 40px 0;
	}
	.yf-team-card__name {
		font-size: 24px;
	}
}

/* ============================================================
   Batch 6 — Archive foundation (structural).
   Calm editorial listing. Each archive item is a media + text
   flex row; mobile collapses to a media-over-text stack.
   No hero, no taxonomy branding, no filters, no JS.
   ============================================================ */

.yf-archive {
	background: var(--wp--preset--color--paper);
}
.yf-archive__header {
	background: var(--wp--preset--color--paper);
}
.yf-archive__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 60px;
	font-weight: 400;
	line-height: 1.05;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--ink);
}
.yf-archive__description {
	margin: 0;
	max-width: 720px;
	font-family: var(--wp--preset--font-family--body);
	font-size: 20px;
	line-height: 1.5;
	font-style: italic;
	color: var(--wp--preset--color--ink-soft);
}

/* ─── Listing items ─────────────────────────── */
.yf-archive__item {
	align-items: flex-start;
}
.yf-archive__item-media {
	flex: 0 0 320px;
}
.yf-archive__item-image img,
.yf-archive__item-media .wp-block-post-featured-image img {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: 14px;
	display: block;
	background-color: var(--wp--preset--color--paper-deep);
}
.yf-archive__item-text {
	flex: 1 1 0;
	min-width: 0;
}
.yf-archive__item-meta {
	gap: 14px;
}
.yf-archive__item-kicker .wp-block-post-terms a {
	color: inherit;
	text-decoration: none;
}
.yf-archive__item-title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 36px;
	font-weight: 400;
	line-height: 1.15;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--ink);
	max-width: 24ch;
}
.yf-archive__item-title a {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-archive__item-title a:hover {
	color: var(--wp--preset--color--accent);
}
.yf-archive__item-excerpt {
	margin: 0;
}
.yf-archive__item-excerpt p {
	margin: 0;
	max-width: 56ch;
	font-family: var(--wp--preset--font-family--body);
	font-size: 17px;
	line-height: 1.6;
	color: var(--wp--preset--color--ink-soft);
}
.yf-archive__item-excerpt .wp-block-post-excerpt__more-link {
	display: none;
}
/* wp:read-more renders as a single <a> element with the class
   attached directly to the anchor (not a wrapping paragraph), so
   all visual styling lives on the class itself and the :hover
   selector is on the anchor, not on a descendant. */
.yf-archive__item-readmore {
	display: inline-block;
	margin: 0;
	padding-bottom: 2px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	border-bottom: 1px solid var(--wp--preset--color--ink);
	transition: color 0.2s var(--wp--custom--yf--easing--glide, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-archive__item-readmore:hover {
	color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

/* Mobile: collapse each item to media-over-text. */
@media (max-width: 900px) {
	.yf-archive__header {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-top: 80px !important;
		padding-bottom: 48px !important;
	}
	.yf-archive__title {
		font-size: 44px;
	}
	.yf-archive__description {
		font-size: 18px;
	}
	.yf-archive__list {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-bottom: 96px !important;
	}
	.yf-archive__item {
		flex-wrap: wrap !important;
	}
	.yf-archive__item-media,
	.yf-archive__item-text {
		flex-basis: 100% !important;
	}
	.yf-archive__item-media {
		flex-grow: 0;
		max-width: 420px;
	}
	.yf-archive__item-title {
		font-size: 30px;
	}
}
@media (max-width: 600px) {
	.yf-archive__title {
		font-size: 36px;
	}
	.yf-archive__item-title {
		font-size: 26px;
	}
	.yf-archive__item-excerpt p {
		font-size: 16px;
	}
}

/* ============================================================
   INDEX SURFACE — post-list fallback at /topics/ (WP Posts page).

   Extends the archive editorial composition to `templates/
   index.html`. Same horizontal-card grammar as `.yf-archive*`:
   320 px featured-image column + meta / title / excerpt /
   read-more text column.

   Diverges from `.yf-archive*` only on responsive logic — index
   is built under the Batch 40 standing rule (content-driven,
   not device-named) and uses fluid clamps + a single content-
   derived breakpoint. The 800 px threshold below is derived
   from the row layout's own constraint: 64 (gutter) + 320
   (image) + 32 (gap) + 280 (min readable text column) + 64
   (gutter) = 760 px. Below that, the row visibly breaks down.
   800 = 760 + a 40-px comfort buffer. It is NOT a device
   target; it is the layout's own break-point.

   Missing-featured-image behavior: WP's `core/post-featured-
   image` renders an empty `<figure>` with no `<img>`
   descendant when a post has no `_thumbnail_id`. The
   `:has(img)` selector below detects that absence and removes
   the media column from layout flow entirely — the text
   column then flexes to full available width. No fake
   fallback image, no fixed manual image, no broken empty box.

   No-results copy: `.yf-index__no-results` carries the literal
   English source string "Nothing to read yet." The render-
   time text translator already registered as Filter 2 in
   `inc/render-block-i18n.php` routes every paragraph's inner
   text through `__()` against the `yoyafun` text domain, so
   this string translates per current locale via the `.po` /
   `.mo` files shipped in `languages/`. No PHP change was
   needed inside this batch — the existing filter already
   covers this case.
   ============================================================ */

.yf-index {
	background: var(--wp--preset--color--paper);
}
.yf-index__header {
	background: var(--wp--preset--color--paper);
}
.yf-index__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(36px, 2.5vw + 24px, 60px);
	font-weight: 400;
	line-height: 1.05;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--ink);
}

/* ─── Listing items ─────────────────────────── */
.yf-index__item {
	align-items: flex-start;
}
.yf-index__item-media {
	flex: 0 0 320px;
}
.yf-index__item-image img,
.yf-index__item-media .wp-block-post-featured-image img {
	width: 100%;
	aspect-ratio: 4 / 5;
	object-fit: cover;
	border-radius: 14px;
	display: block;
	background-color: var(--wp--preset--color--paper-deep);
}
/* Suppress the media column when WP rendered an empty featured-
   image figure (post without thumbnail). The text column flexes
   into the freed space because of `flex: 1 1 0; min-width: 0` on
   `.yf-index__item-text`. No fake fallback, no fixed image. */
.yf-index__item-media:not(:has(img)) {
	display: none;
}
.yf-index__item-text {
	flex: 1 1 0;
	min-width: 0;
}
.yf-index__item-meta {
	gap: 14px;
}
.yf-index__item-kicker .wp-block-post-terms a {
	color: inherit;
	text-decoration: none;
}
.yf-index__item-title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(26px, 1.5vw + 18px, 36px);
	font-weight: 400;
	line-height: 1.15;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--ink);
	max-width: 24ch;
}
.yf-index__item-title a {
	color: inherit;
	text-decoration: none;
	transition: color 0.2s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-index__item-title a:hover {
	color: var(--wp--preset--color--accent);
}
.yf-index__item-excerpt {
	margin: 0;
}
.yf-index__item-excerpt p {
	margin: 0;
	max-width: 56ch;
	font-family: var(--wp--preset--font-family--body);
	font-size: clamp(16px, 0.25vw + 15px, 17px);
	line-height: 1.6;
	color: var(--wp--preset--color--ink-soft);
}
.yf-index__item-excerpt .wp-block-post-excerpt__more-link {
	display: none;
}
/* wp:read-more renders as a single <a> with the class on the
   anchor itself (not a wrapping paragraph), so visual styling
   sits on the class and :hover targets the anchor directly. */
.yf-index__item-readmore {
	display: inline-block;
	margin: 0;
	padding-bottom: 2px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	border-bottom: 1px solid var(--wp--preset--color--ink);
	transition: color 0.2s var(--wp--custom--yf--easing--glide, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-index__item-readmore:hover {
	color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}
.yf-index__no-results {
	margin: 0;
}

/* Narrow-viewport branch — derived from the layout's own break
   point (see comment block above). Below ~800 px the row card
   layout cannot host a readable text column alongside the 320-px
   image, so the card flips to a column stack (image above text)
   and the page gutters contract to the theme's mobile gutter.
   Type sizes are already fluid via the clamp() values above —
   no separate font-size step is needed inside this media query. */
@media (max-width: 800px) {
	.yf-index__header {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-top: clamp(72px, 6vw + 48px, 120px) !important;
		padding-bottom: clamp(40px, 4vw + 24px, 64px) !important;
	}
	.yf-index__list {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-bottom: clamp(80px, 12vw + 32px, 144px) !important;
	}
	.yf-index__item {
		flex-wrap: wrap !important;
	}
	.yf-index__item-media,
	.yf-index__item-text {
		flex-basis: 100% !important;
	}
	.yf-index__item-media {
		flex-grow: 0;
		max-width: 420px;
	}
}

/* ============================================================
   GALLERY SUBSYSTEM — archive-gallery + single-gallery.

   Editorial composition for the gallery CPT family. The
   `archive-gallery.html` template is forced to render even for
   `gallery_type` and `gallery_region` taxonomy archives via
   the `taxonomy_template_hierarchy` filter in
   `inc/cpt-gallery.php` (Plan A routing). Filter pill labels,
   counts, hrefs, and active-state are resolved server-side by
   the pill-router filter in the same PHP file. Card type
   badges and sidebar stats are also rendered server-side per
   classname-scoped filters.

   Missing-featured-image behavior: cards without an inner
   <img> (no `_thumbnail_id` on the post) collapse via
   `:has(img)` detection to a text-only card on paper-deep
   background; the hero of a single-gallery without featured
   image collapses to a paper-deep solid block with ink text
   in full contrast. Same idiom as the index surface's
   `:has(img)` collapse.

   Content-driven responsive: type clamps + one content-derived
   row→column breakpoint at ~800 vw (where the asymmetric
   grid's 8-col featured card can no longer host a readable
   title alongside the scrim). No device-named targeting.
   ============================================================ */

.yf-gallery-archive {
	background: var(--wp--preset--color--paper);
}
.yf-gallery-archive__breadcrumb {
	margin: 0;
	padding: 32px 64px 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}
.yf-gallery-archive__breadcrumb a {
	color: var(--wp--preset--color--ink-soft);
	text-decoration: none;
}
.yf-gallery-archive__breadcrumb a:hover {
	color: var(--wp--preset--color--accent);
}
.yf-gallery-archive__header-grid.wp-block-columns {
	gap: 64px;
}
.yf-gallery-archive__kicker {
	margin: 0 0 16px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}
.yf-gallery-archive__title {
	margin: 0 0 20px;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(48px, 5vw + 24px, 84px);
	font-style: italic;
	font-weight: 400;
	line-height: 0.98;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--ink);
}
.yf-gallery-archive__dek {
	margin: 0;
	max-width: 580px;
	font-family: var(--wp--preset--font-family--body);
	font-size: clamp(18px, 0.5vw + 16px, 22px);
	line-height: 1.5;
	color: var(--wp--preset--color--ink-soft);
}
.yf-gallery-archive__sidebar {
	padding-top: 20px;
	border-top: 1.5px solid var(--wp--preset--color--ink);
}
.yf-gallery-archive__sidebar-label {
	margin: 0 0 12px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-gallery-archive__sidebar-stats {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(20px, 1vw + 16px, 28px);
	line-height: 1.25;
	color: var(--wp--preset--color--ink);
}

/* ─── Filter pill row ─── */
.yf-gallery-archive__filter-row {
	gap: 10px !important;
	align-items: center;
}
.yf-gallery-archive__filter-pill {
	margin: 0;
}
.yf-gallery-archive__filter-pill a {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 14px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	font-weight: 500;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	background: transparent;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 999px;
	transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.yf-gallery-archive__filter-pill a:hover {
	background: var(--wp--preset--color--paper-deep);
	border-color: var(--wp--preset--color--rule-strong);
}
.yf-gallery-archive__filter-pill a.is-active {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
	border-color: var(--wp--preset--color--ink);
}
.yf-gallery-archive__filter-count {
	font-size: 11px;
	opacity: 0.6;
	font-variant-numeric: tabular-nums;
}
.yf-gallery-archive__filter-pill a.is-active .yf-gallery-archive__filter-count {
	opacity: 0.7;
}
.yf-gallery-archive__filter-divider {
	margin: 0 4px;
	color: var(--wp--preset--color--rule-strong);
	font-size: 14px;
	user-select: none;
}

/* ─── Asymmetric card grid ─── */
.yf-gallery-archive__grid.wp-block-post-template {
	display: grid !important;
	grid-template-columns: repeat(12, 1fr);
	gap: 24px;
	list-style: none;
	padding: 0;
}
.yf-gallery-archive__grid.wp-block-post-template > li {
	grid-column: span 4;
}
/* Featured card = first post in the loop. spans 8 cols. */
.yf-gallery-archive__grid.wp-block-post-template > li:first-child {
	grid-column: span 8;
}
.yf-gallery-archive__grid.wp-block-post-template > li:first-child .yf-gallery-card__media img {
	height: 620px;
}
.yf-gallery-archive__grid.wp-block-post-template > li:first-child .yf-gallery-card__title {
	font-size: clamp(28px, 2vw + 20px, 56px);
}
/* Mid row: items 6 and 7 (0-indexed 5,6) span 6 cols each. */
.yf-gallery-archive__grid.wp-block-post-template > li:nth-child(6),
.yf-gallery-archive__grid.wp-block-post-template > li:nth-child(7) {
	grid-column: span 6;
}
.yf-gallery-archive__grid.wp-block-post-template > li:nth-child(6) .yf-gallery-card__media img,
.yf-gallery-archive__grid.wp-block-post-template > li:nth-child(7) .yf-gallery-card__media img {
	height: 460px;
}

/* ─── Card itself ─── */
.yf-gallery-card {
	position: relative;
	overflow: hidden;
	border-radius: 14px;
	background: var(--wp--preset--color--paper-deep);
	transition: transform 0.3s var(--wp--custom--yf--easing--glide, ease-out),
		box-shadow 0.3s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-gallery-card:hover {
	transform: translateY(-4px);
	box-shadow: 0 12px 30px -8px rgba(0, 0, 0, 0.22);
}
.yf-gallery-card__media {
	margin: 0;
	display: block;
}
.yf-gallery-card__media img,
.yf-gallery-card .wp-block-post-featured-image img {
	width: 100%;
	height: 480px;
	object-fit: cover;
	display: block;
	background-color: var(--wp--preset--color--paper-deep);
	transition: transform 0.45s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-gallery-card:hover .yf-gallery-card__media img {
	transform: scale(1.06);
}
.yf-gallery-card__content {
	position: absolute;
	inset: auto 0 0 0;
	padding: 28px;
	color: var(--wp--preset--color--on-image);
	z-index: 2;
	background: linear-gradient(to top,
		rgba(0, 0, 0, 0.6) 0%,
		rgba(0, 0, 0, 0.3) 50%,
		rgba(0, 0, 0, 0) 100%);
}
.yf-gallery-card:hover .yf-gallery-card__content {
	background: linear-gradient(to top,
		rgba(0, 0, 0, 0.72) 0%,
		rgba(0, 0, 0, 0.42) 50%,
		rgba(0, 0, 0, 0) 100%);
}
.yf-gallery-card__badge {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: 0 0 10px;
	padding: 5px 10px;
	background: rgba(255, 255, 255, 0.18);
	backdrop-filter: blur(8px);
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--wp--preset--color--on-image);
}
.yf-gallery-card__title {
	margin: 0 0 8px;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(20px, 0.8vw + 16px, 26px);
	font-weight: 400;
	line-height: 1.1;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--on-image);
}
.yf-gallery-card__title a {
	color: inherit;
	text-decoration: none;
}
.yf-gallery-card__date {
	margin: 0;
	color: rgba(255, 255, 255, 0.7);
}

/* Missing-featured-image: collapse to text-only card on paper-deep. */
.yf-gallery-card:not(:has(img)) {
	background: var(--wp--preset--color--paper-deep);
	min-height: 240px;
	display: flex;
	align-items: flex-end;
}
.yf-gallery-card:not(:has(img)) .yf-gallery-card__media {
	display: none;
}
.yf-gallery-card:not(:has(img)) .yf-gallery-card__content {
	position: static;
	width: 100%;
	background: transparent;
	color: var(--wp--preset--color--ink);
	padding: 32px;
}
.yf-gallery-card:not(:has(img)) .yf-gallery-card__badge {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
	backdrop-filter: none;
}
.yf-gallery-card:not(:has(img)) .yf-gallery-card__title {
	color: var(--wp--preset--color--ink);
}
.yf-gallery-card:not(:has(img)) .yf-gallery-card__date {
	color: var(--wp--preset--color--ink-mute);
}

/* ─── Pagination ─── */
.yf-gallery-archive__pagination-info {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-gallery-archive__pagination .wp-block-query-pagination-numbers .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 36px;
	padding: 8px 12px;
	border-radius: 999px;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	transition: background 0.2s, color 0.2s;
}
.yf-gallery-archive__pagination .wp-block-query-pagination-numbers .current {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
}
.yf-gallery-archive__pagination .wp-block-query-pagination-numbers .page-numbers:hover {
	background: var(--wp--preset--color--paper-deep);
}
.yf-gallery-archive__no-results {
	margin: 0;
	padding: 32px 0;
}

/* ─── Single gallery — bespoke hero per Gallery.jsx design ─── */
.yf-gallery-single__hero {
	position: relative;
	color: var(--wp--preset--color--on-image);
}
.yf-gallery-single__hero-serial-text {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.2em;
	text-transform: uppercase;
	color: var(--wp--preset--color--on-image);
	display: flex;
	align-items: center;
	gap: 16px;
}
.yf-gallery-single__hero-serial-text::before {
	content: "";
	width: 28px;
	height: 1px;
	background: var(--wp--preset--color--on-image);
	opacity: 0.7;
}
.yf-gallery-single__hero-kicker {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent-soft);
	max-width: 880px;
}
.yf-gallery-single__hero-title {
	margin: 0;
	max-width: 880px;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(40px, 4vw + 24px, 84px);
	font-weight: 400;
	line-height: 0.98;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--on-image);
}
.yf-gallery-single__hero-title em {
	font-style: italic;
}

/* Missing-featured-image: collapse hero to paper-deep with ink text. */
.yf-gallery-single__hero:not(:has(img)) {
	background: var(--wp--preset--color--paper-deep);
}
.yf-gallery-single__hero:not(:has(img)) .yf-gallery-single__hero-serial-text,
.yf-gallery-single__hero:not(:has(img)) .yf-gallery-single__hero-title {
	color: var(--wp--preset--color--ink);
}
.yf-gallery-single__hero:not(:has(img)) .yf-gallery-single__hero-kicker {
	color: var(--wp--preset--color--accent);
}
.yf-gallery-single__hero:not(:has(img)) .yf-gallery-single__hero-serial-text::before {
	background: var(--wp--preset--color--ink);
}

/* ─── Single gallery — intro + byline ─── */
.yf-gallery-single__intro {
	text-align: center;
}
.yf-gallery-single__dek p {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: clamp(18px, 0.4vw + 16px, 22px);
	line-height: 1.55;
	font-style: italic;
	color: var(--wp--preset--color--ink-soft);
}
.yf-gallery-single__byline {
	gap: 14px !important;
	justify-content: center;
}
.yf-gallery-single__byline-avatar img {
	border-radius: 50%;
	background: var(--wp--preset--color--accent-quiet);
}
.yf-gallery-single__byline-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 13px;
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}
.yf-gallery-single__byline-date {
	margin: 0;
}

/* ─── Narrow viewport — content-driven collapse ─── */
@media (max-width: 800px) {
	.yf-gallery-archive__breadcrumb,
	.yf-gallery-archive__header,
	.yf-gallery-archive__filters,
	.yf-gallery-archive__list {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
	}
	.yf-gallery-archive__header-grid.wp-block-columns {
		gap: 32px;
		flex-direction: column;
	}
	.yf-gallery-archive__header-grid.wp-block-columns > .wp-block-column {
		flex-basis: 100% !important;
	}
	.yf-gallery-archive__grid.wp-block-post-template {
		grid-template-columns: 1fr;
	}
	.yf-gallery-archive__grid.wp-block-post-template > li,
	.yf-gallery-archive__grid.wp-block-post-template > li:first-child,
	.yf-gallery-archive__grid.wp-block-post-template > li:nth-child(6),
	.yf-gallery-archive__grid.wp-block-post-template > li:nth-child(7) {
		grid-column: span 1;
	}
	.yf-gallery-card__media img,
	.yf-gallery-archive__grid.wp-block-post-template > li:first-child .yf-gallery-card__media img,
	.yf-gallery-archive__grid.wp-block-post-template > li:nth-child(6) .yf-gallery-card__media img,
	.yf-gallery-archive__grid.wp-block-post-template > li:nth-child(7) .yf-gallery-card__media img {
		height: clamp(320px, 60vw, 480px);
	}
	.yf-gallery-archive__pagination-row {
		flex-direction: column;
		align-items: stretch;
		gap: 16px;
	}
	.yf-gallery-single__hero-serial,
	.yf-gallery-single__hero-body,
	.yf-gallery-single__intro,
	.yf-gallery-single__body {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
	}
}

/* ============================================================
   Batch 7 — Search foundation (structural).
   Calm editorial search surface. Hero B is NOT used. Each
   result row reuses the Batch-6 `.yf-archive__item*` BEM
   classes for editorial consistency between archive and
   search listings; this section only carries search-shell
   and form-block styling.
   English microcopy on `wp:search` attributes (placeholder /
   buttonText / label) and on the no-results paragraph are
   provisional carry-overs flagged for the Polylang batch.
   ============================================================ */

.yf-search {
	background: var(--wp--preset--color--paper);
}
.yf-search__header {
	background: var(--wp--preset--color--paper);
}
.yf-search__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 60px;
	font-weight: 400;
	line-height: 1.05;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--ink);
}
.yf-search__title span {
	font-style: italic;
}

/* ─── Search form ─── */
.yf-search__form-wrapper {
	max-width: 640px;
}
.yf-search__form {
	margin: 0;
}
.yf-search__form .wp-block-search__inside-wrapper {
	gap: 12px;
	align-items: stretch;
	border-bottom: 1.5px solid var(--wp--preset--color--ink);
	padding-bottom: 6px;
}
.yf-search__form .wp-block-search__input {
	flex: 1 1 auto;
	min-width: 0;
	padding: 8px 0;
	background: transparent;
	border: 0;
	outline: none;
	font-family: var(--wp--preset--font-family--display);
	font-size: 28px;
	font-style: italic;
	font-weight: 400;
	line-height: 1.2;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}
.yf-search__form .wp-block-search__input::placeholder {
	color: var(--wp--preset--color--ink-mute);
	opacity: 1;
}
.yf-search__form .wp-block-search__input:focus {
	outline: none;
}
.yf-search__form .wp-block-search__button {
	flex: 0 0 auto;
	padding: 10px 18px;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
	border: 0;
	border-radius: 999px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	cursor: pointer;
	transition: background-color 0.2s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-search__form .wp-block-search__button:hover {
	background: var(--wp--preset--color--accent);
}

/* Hide the visually-hidden label slot's residual whitespace when
   showLabel is false — the block emits an empty label container
   that some WP versions style with margin. */
.yf-search__form .wp-block-search__label {
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	height: 1px;
	overflow: hidden;
	position: absolute;
	white-space: nowrap;
	width: 1px;
}

/* ─── No-results message ─── */
.yf-search__no-results {
	margin: 0;
	max-width: 56ch;
}

/* ─── Responsive ─── */
@media (max-width: 900px) {
	.yf-search__header {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-top: 80px !important;
		padding-bottom: 48px !important;
	}
	.yf-search__title {
		font-size: 44px;
	}
	.yf-search__list {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-bottom: 96px !important;
	}
	.yf-search__form .wp-block-search__input {
		font-size: 22px;
	}
}
@media (max-width: 600px) {
	.yf-search__title {
		font-size: 36px;
	}
	.yf-search__form .wp-block-search__input {
		font-size: 18px;
	}
	.yf-search__form .wp-block-search__inside-wrapper {
		flex-wrap: wrap;
	}
	.yf-search__form .wp-block-search__button {
		flex-basis: 100%;
	}
}

/* ============================================================
   Batch 8 — 404 foundation (structural).
   Calm editorial centred intro. Hero B is NOT used. The
   inline search form reuses the `.yf-search__form` block
   styling from Batch 7 — no new form CSS.
   English microcopy on the H1, body paragraph, search-block
   attributes, and recovery anchor are provisional carry-overs
   flagged for the Polylang batch.
   ============================================================ */

.yf-404 {
	background: var(--wp--preset--color--paper);
}
.yf-404__inner {
	max-width: 720px;
}
.yf-404__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 96px;
	font-weight: 400;
	line-height: 0.95;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--ink);
}
.yf-404__body {
	margin: 0;
	max-width: 56ch;
	font-family: var(--wp--preset--font-family--body);
	font-size: 22px;
	line-height: 1.5;
	font-style: italic;
	color: var(--wp--preset--color--ink-soft);
}
.yf-404__form-wrapper {
	max-width: 640px;
}
.yf-404__recovery {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-404__recovery a {
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	border-bottom: 1px solid var(--wp--preset--color--ink);
	padding-bottom: 1px;
	transition: color 0.2s var(--wp--custom--yf--easing--glide, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--glide, ease-out);
}
.yf-404__recovery a:hover {
	color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

@media (max-width: 900px) {
	.yf-404 {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-top: 96px !important;
		padding-bottom: 112px !important;
	}
	.yf-404__title {
		font-size: 68px;
	}
	.yf-404__body {
		font-size: 19px;
	}
}
@media (max-width: 600px) {
	.yf-404__title {
		font-size: 48px;
	}
	.yf-404__body {
		font-size: 17px;
	}
}

/* ============================================================
   Batch 11 — Header v4 + Hero B cinematic + Homepage editorial
   sections + CardV4 family.
   - Header v4: real designed header (logo, nav, search, subscribe)
     with hero-scoped colour flip carried over from Batch 1.
   - Hero B cinematic: same gradient text-clip primitive (Batch 1)
     plus byline, BigMediaCTA pair, and animated scroll cue.
   - CardV4 family: feature, standard, text, pick variants per
     `system-v4.css` `.yf-card4*`. Hover choreography is CSS only
     (no JS). All animations are @keyframes / transitions.
   - Six homepage editorial sections (Editor's Picks, Destinations,
     Galleries & films, Stories rail, Guides band, Newsletter band).
   - Empty `wp:image` placeholders render as paper-deep aspect-ratio
     rectangles via CSS — block-native, editor-replaceable, no
     remote URLs anywhere in the template.
   ============================================================ */

/* ─── Batch 11.1 — Width / scale corrections (kept for the
   homepage editorial section grid AND for the single / page /
   single-gallery hero zones which still use `.yf-hero5b__title-zone`
   and `.yf-hero5b__below`). Inner content gets 1440 px content-size
   instead of the sitewide 680 px (theme.json default for reading
   columns). Batch 11.7 added the homepage hero rebuild but left
   these legacy class names in the selector so the other templates
   are not regressed.                                              */
.yf-hero5b__title-zone,
.yf-hero5b__below,
.yf-home-section {
	--wp--style--global--content-size: 1440px;
	--wp--style--global--wide-size: 1440px;
}

/* (`.yf-hero5b__image--cinematic { min-height: 920px }` was here in
   earlier batches; moved into the Batch 11.7 hero CSS block at the
   top of this file to colocate with the rest of the hero rules.) */

/* ─── Header v4 ──────────────────────────────────────── */
.yf-header {
	padding: 28px 64px;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	background: var(--wp--preset--color--paper);
}
/* Logo — structural two-span brand mark per V3 `IntegratedHeader`
   / baseline `Header()`. The design source renders the brand as
   two `<span>` elements with different `font-style` ("yoya"
   italic + ".fun" non-italic) and different colours. A single
   `wp:site-title` text node cannot carry two `font-style`
   values, so the logo is a hardcoded `wp:paragraph` with two
   spans inside the home link. The brand mark is therefore not
   driven by Settings → General → Site Title. */
.yf-header__logo {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 28px;
	font-weight: 400;
	letter-spacing: -0.02em;
	line-height: 1;
}
.yf-header__logo a {
	display: inline-flex;
	align-items: baseline;
	gap: 2px;
	color: inherit;
	text-decoration: none;
}
.yf-header__logo-yoya {
	font-style: italic;
	color: var(--wp--preset--color--ink);
}
.yf-header__logo-fun {
	font-style: normal;
	color: var(--wp--preset--color--accent);
}
/* Brand logo: force LTR so the two-span composition
   `<span>yoya</span><span>.fun</span>` always renders as
   `yoya.fun` regardless of page direction. Latin brand text
   inside an Arabic page should follow Latin-script direction
   (standard bidi practice). `unicode-bidi: isolate` is not
   enough on its own here because the parent `<a>` is
   `display: inline-flex`, which makes the two spans flex items
   whose visual order reverses under `direction: rtl`. Forcing
   `direction: ltr` on the `<a>` keeps flex order LTR. */
.yf-header__logo a {
	direction: ltr;
	unicode-bidi: isolate;
}
/* Navigation — real wp:navigation block with inline nav-links /
   nav-submenus mapped to live category + page IDs (Batch 15: replaces
   the hardcoded 6 paragraph items from Batch 13.1, which were
   placeholder slugs that did not resolve against the real site).
   render_block filters in inc/render-block-i18n.php translate the
   labels and rewrite the hrefs per current language at render time,
   so the saved markup stays language-agnostic source-of-truth.

   CSS below styles the block at the V5 visual level — fonts, sizing,
   spacing, hover — without hard-overriding the layout primitives the
   navigation block provides (responsive overlay, submenu open/close,
   etc.). Selectors are scoped under `.yf-header__nav` so other
   `wp:navigation` blocks elsewhere on the site (e.g. in the footer
   or in custom patterns) are unaffected.                                */
.yf-header__nav.wp-block-navigation {
	flex: 1;
	justify-content: center;
}
.yf-header__nav .wp-block-navigation__container {
	gap: 32px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 13px;
	font-weight: 500;
	letter-spacing: 0.04em;
	line-height: 1;
}
.yf-header__nav .wp-block-navigation-item__content {
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	transition: color 0.2s var(--wp--custom--yf--easing--air, ease-out);
	padding: 0;
}
.yf-header__nav .wp-block-navigation-item__content:hover,
.yf-header__nav .wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--accent);
}
.yf-header__nav .wp-block-navigation__submenu-icon {
	margin-inline-start: 4px;
}
/* Submenu — paper card on hover/focus, calm shadow, no border-radius
   surprises. The block renders it as a `<ul>` positioned by core CSS;
   we just paint the surface. */
.yf-header__nav .wp-block-navigation__submenu-container {
	background-color: var(--wp--preset--color--paper);
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 8px;
	box-shadow: 0 12px 28px rgba(28, 24, 20, 0.08);
	padding: 8px 0;
	min-width: 200px;
}
.yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	padding: 8px 18px;
	font-size: 12px;
	/* Submenu sits on paper (cream) — items must use ink color, not the
	   white parent navbar text colour they would otherwise inherit when
	   the navbar overlays a dark hero. Closure §7f finding: dropdown
	   items were white-on-white on the front-page hero before this rule. */
	color: var(--wp--preset--color--ink);
}
.yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover,
.yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus {
	color: var(--wp--preset--color--accent);
}

/* ============================================================
 * HMTB Item 2 — Desktop dropdown gets the single-post Subscribe
 * GLASS BACKGROUND. The Subscribe glass surface (source of truth,
 * 3620–3627) is: bg rgba(255,255,255,.12), backdrop-filter blur(10px),
 * border 1px solid rgba(255,255,255,.25). We apply that glass surface
 * to the submenu card. The card SHAPE is preserved (8px radius +
 * floating shadow) — a pill radius would clip the multi-item list;
 * "glass background" = the translucent fill/blur/border, not the pill
 * geometry. Desktop only (≥1200): at ≤1199 the nav lives in the mobile
 * overlay where the submenu is already restyled transparent (3931).
 * Item text/link COLOUR is UNCHANGED (ink rules 3345/3561/5371 stay).
 *
 * Specificity: WP core paints the card via
 * `.wp-block-navigation:not(.has-background) …__submenu-container`
 * = (0,3,0) {bg #fff; border rgba(0,0,0,.15)} (verified live via CDP),
 * which beats a plain (0,2,0) theme rule. We anchor on the nav's
 * compound classes + `:not(.has-background)` to reach (0,4,0) and win.
 * ============================================================ */
@media (min-width: 1200px) {
	.wp-block-navigation.yf-header__nav:not(.has-background) .wp-block-navigation__submenu-container {
		background-color: rgba(255, 255, 255, 0.12);
		border: 1px solid rgba(255, 255, 255, 0.25);
		-webkit-backdrop-filter: blur(10px);
		        backdrop-filter: blur(10px);
	}

	/* ========================================================
	 * HMTB-2 Part B — desktop dropdown ITEMS on the glass card.
	 * REVISES the prior batch (items were ink): on the translucent
	 * glass card the items are now WHITE (matching the white header
	 * controls over the hero). Anchored on the nav compound classes +
	 * :not(.has-background) for (0,5,0) so it beats the theme ink rules
	 * (base 0,3,0; over-hero .yf-hero5b__image and :is() families both
	 * 0,4,0) and any WP-core :not(.has-background) paint. Desktop only —
	 * at <=1199 the submenu lives in the mobile overlay (unaffected).
	 * ======================================================== */
	/* B1 — default item text = white (on-image). position:relative
	   anchors the B3 underline pseudo-element. */
	.wp-block-navigation.yf-header__nav:not(.has-background) .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
		position: relative;
		color: var(--wp--preset--color--on-image);
	}
	/* B2 — hover/focus text = accent-soft. (0,6,0) beats the over-hero
	   ink-hover rule at 0,5,0.) */
	.wp-block-navigation.yf-header__nav:not(.has-background) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover,
	.wp-block-navigation.yf-header__nav:not(.has-background) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus-visible {
		color: var(--wp--preset--color--accent-soft);
	}
	/* B3 — red (accent) underline that GROWS from the inline-start edge.
	   Logical properties (inset-inline-start + width) make it grow
	   left->right in LTR and right->left in RTL automatically. The 18px
	   inset matches the item's inline padding so the bar tracks the text. */
	.wp-block-navigation.yf-header__nav:not(.has-background) .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
		content: "";
		position: absolute;
		inset-block-end: 2px;
		inset-inline-start: 18px;
		width: 0;
		height: 2px;
		background-color: var(--wp--preset--color--accent);
		transition: width 0.25s var(--wp--custom--yf--easing--air, ease-out);
		pointer-events: none;
	}
	.wp-block-navigation.yf-header__nav:not(.has-background) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover::after,
	.wp-block-navigation.yf-header__nav:not(.has-background) .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus-visible::after {
		width: calc(100% - 36px);
	}
}

.yf-header__util {
	gap: 16px;
}

/* Polylang language switcher — V5-aligned compact select. The block
   renders as `<div class="wp-block-polylang-language-switcher …">
   <select class="lang-choice-pll">…</select></div>` when dropdown=true.
   Styling keeps the chrome calm (paper background, ink-soft border,
   small UI font) and uses `appearance: none` so each browser's native
   select chrome doesn't override the V5 typography. Custom chevron
   supplied via CSS mask-image so no inline SVG is shipped.            */
.yf-header__lang.wp-block-polylang-language-switcher {
	display: inline-flex;
	align-items: center;
	margin: 0;
}
.yf-header__lang .lang-choice-pll,
.yf-header__lang select {
	appearance: none;
	-webkit-appearance: none;
	-moz-appearance: none;
	margin: 0;
	padding: 6px 26px 6px 12px;
	background-color: transparent;
	background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none' stroke='currentColor' stroke-width='1.4'><path d='M1 1l4 4 4-4'/></svg>");
	background-repeat: no-repeat;
	background-position: right 8px center;
	background-size: 10px 6px;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: var(--wp--custom--yf--radius--pill, 999px);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.06em;
	line-height: 1.2;
	cursor: pointer;
	transition:
		color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-header__lang select:hover,
.yf-header__lang select:focus-visible {
	color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
	outline: none;
}
/* RTL: flip the chevron padding side. */
[dir="rtl"] .yf-header__lang select,
:root[lang^="ar"] .yf-header__lang select {
	padding: 6px 12px 6px 26px;
	background-position: left 8px center;
}

/* Search button — V5 `IntegratedHeader` glass circle treatment.
   Outside the hero, falls back to a naked icon (no frame), per
   the baseline `Header()` in Shared.jsx. Over the hero, becomes
   the 36×36 glass circle. The icon glyph is supplied via CSS
   `mask-image: url("data:image/svg+xml;…")` on `::before` so the
   markup stays as a plain `wp:paragraph` with a link — no
   inline `<svg>` that would be KSES-stripped on save. */
.yf-header__search {
	margin: 0;
	display: inline-flex;
	align-items: center;
}
.yf-header__search a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	background: transparent;
	border: 0;
	border-radius: 50%;
	font-size: 0;
	line-height: 0;
	letter-spacing: 0;
	transition:
		color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		background-color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-header__search a::before {
	content: "";
	display: block;
	width: 14px;
	height: 14px;
	background-color: currentColor;
	-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><circle cx='6' cy='6' r='4'/><path d='M9.5 9.5L13 13'/></svg>");
	        mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4'><circle cx='6' cy='6' r='4'/><path d='M9.5 9.5L13 13'/></svg>");
	-webkit-mask-position: center;
	        mask-position: center;
	-webkit-mask-repeat: no-repeat;
	        mask-repeat: no-repeat;
	-webkit-mask-size: contain;
	        mask-size: contain;
}
.yf-header__search a:hover {
	color: var(--wp--preset--color--accent);
}

/* Subscribe button — outside the hero, outline-ghost (baseline
   `Header()` `.yf-btn--ghost` variant). Over the hero, becomes
   the V5 `.yf-btn3--glass` variant. Both base and over-hero
   use 10/18 padding + 11 px / 600 / 0.14em letter-spacing per
   V5 source. */
.yf-header__subscribe-wrapper.wp-block-buttons {
	margin: 0;
}
.yf-header__subscribe.wp-block-button.is-style-outline > .wp-block-button__link,
.yf-header__subscribe .wp-block-button__link {
	background: transparent;
	color: var(--wp--preset--color--ink);
	border: 1px solid var(--wp--preset--color--ink);
	padding: 10px 18px;
	border-radius: var(--wp--custom--yf--radius--pill, 999px);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	line-height: 1;
	transition:
		background-color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-header__subscribe .wp-block-button__link:hover {
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
}

/* Header colour flip + glass surfaces when nested inside the
   homepage hero. Outside the hero the header keeps the
   default paper-on-ink chrome. */
.yf-hero5b__image .yf-header {
	background: transparent;
	border-bottom: 0;
}

/* Logo over hero — paper "yoya" + accent-soft ".fun" per the V3
   `IntegratedHeader` source. The structural two-span split (set
   up in the base `.yf-header__logo-*` rules) lets each span
   carry its own colour, so the over-hero treatment is just a
   colour swap. No gradient text-clip is needed. */
.yf-hero5b__image .yf-header__logo-yoya {
	color: var(--wp--preset--color--on-image);
}
.yf-hero5b__image .yf-header__logo-fun {
	color: var(--wp--preset--color--accent-soft);
}

/* Nav items over hero — paper-on-image. Targets the wp:navigation
   block's anchor + submenu glyph. The over-hero submenu itself keeps
   its paper card surface (set on the outside-hero rule above) so the
   dropdown stays legible when it expands over the photo. */
.yf-hero5b__image .yf-header__nav .wp-block-navigation-item__content {
	color: var(--wp--preset--color--on-image);
}
.yf-hero5b__image .yf-header__nav .wp-block-navigation-item__content:hover,
.yf-hero5b__image .yf-header__nav .wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--accent-soft);
}
.yf-hero5b__image .yf-header__nav .wp-block-navigation__submenu-icon {
	color: var(--wp--preset--color--on-image);
}

/* Mobile overlay color reset — when WP's responsive container opens
   (`.is-menu-open` modifier class added by the Interactivity API),
   the overlay is rendered with a near-white background but the
   nav items + chevron icons are DOM descendants of `.yf-hero5b__image`,
   so the three over-hero rules above paint white-on-white = invisible.
   These three paired rules override with one extra ancestor class on
   the path (`.wp-block-navigation__responsive-container.is-menu-open`),
   bumping specificity from 0,3,0 to 0,5,0 — unconditional win over
   the over-hero rules. No `!important`. Applies only while the
   overlay is open. (Note: a `.yf-header__nav:not(:has(.is-menu-open))`
   narrowing was tried first — but Chrome's selector engine has a real
   bug where `:not(:has())` in the middle of a descendant chain is
   silently ignored. Anchored-from-root `:has()` does work, but the
   specificity-override below is simpler.) */
.yf-hero5b__image .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	color: var(--wp--preset--color--ink);
}
.yf-hero5b__image .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:hover,
.yf-hero5b__image .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--accent);
}
.yf-hero5b__image .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon {
	color: var(--wp--preset--color--ink);
}

/* Desktop dropdown submenu — paper-card surface needs ink-on-cream items
   even when the navbar lives over the dark hero (where the outer
   `.yf-hero5b__image .yf-header__nav .wp-block-navigation-item__content`
   rule paints all items in `on-image` white). Override scoped to the
   submenu container only so the always-visible top-level items still
   inherit the over-hero white color. Closure §7f defect: dropdown
   items were white-on-cream and effectively invisible before this rule. */
.yf-hero5b__image .yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	color: var(--wp--preset--color--ink);
}
.yf-hero5b__image .yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover,
.yf-hero5b__image .yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content:focus-visible {
	color: var(--wp--preset--color--accent);
}

/* Polylang switcher over hero — glass treatment matching the search
   button frame. */
.yf-hero5b__image .yf-header__lang select {
	background-color: rgba(255, 255, 255, 0.12);
	border-color: rgba(255, 255, 255, 0.25);
	color: var(--wp--preset--color--on-image);
	-webkit-backdrop-filter: blur(10px);
	        backdrop-filter: blur(10px);
}
.yf-hero5b__image .yf-header__lang select:hover,
.yf-hero5b__image .yf-header__lang select:focus-visible {
	background-color: rgba(255, 255, 255, 0.22);
	border-color: rgba(255, 255, 255, 0.4);
	color: var(--wp--preset--color--on-image);
}
/* The native <option> popup is drawn by the OS and ignores most CSS,
   but Chromium honours `color` + `background-color` set on the
   <select> for the closed pill. The opened option list will use the
   OS default — that's a platform constraint, not a styling miss. */
.yf-hero5b__image .yf-header__lang select option {
	color: var(--wp--preset--color--ink);
	background-color: var(--wp--preset--color--paper);
}

/* Search button over hero — glass circle (36×36, white-12 % bg,
   white-25 % border, backdrop-blur 10). The mask icon stays
   the same; only the frame becomes glass. */
.yf-hero5b__image .yf-header__search a {
	background: rgba(255, 255, 255, 0.12);
	border: 1px solid rgba(255, 255, 255, 0.25);
	-webkit-backdrop-filter: blur(10px);
	        backdrop-filter: blur(10px);
	color: var(--wp--preset--color--on-image);
}
.yf-hero5b__image .yf-header__search a:hover {
	background: rgba(255, 255, 255, 0.22);
	border-color: rgba(255, 255, 255, 0.4);
	color: var(--wp--preset--color--on-image);
}

/* Subscribe over hero — glass pill (same colour values as
   search button glass treatment, but rectangular pill shape). */
/* Specificity note: the base Subscribe rule at line ~2570 is
   `.yf-header__subscribe.wp-block-button.is-style-outline >
   .wp-block-button__link` (0,4,0), which sets color: ink and
   border-color: ink. The previous version of THIS over-hero rule
   used `.yf-hero5b__image .yf-header__subscribe .wp-block-button__link`
   (0,3,0), losing the cascade — Subscribe rendered with dark text
   and a dark border over the hero photo (the "awkward black-text/
   black-border treatment" the user flagged). The compound selector
   below restores parity at 0,5,0 so the glass treatment wins. */
.yf-hero5b__image .yf-header__subscribe.wp-block-button.is-style-outline > .wp-block-button__link,
.yf-hero5b__image .yf-header__subscribe .wp-block-button__link {
	background: rgba(255, 255, 255, 0.12);
	color: var(--wp--preset--color--on-image);
	border-color: rgba(255, 255, 255, 0.25);
	-webkit-backdrop-filter: blur(10px);
	        backdrop-filter: blur(10px);
}
.yf-hero5b__image .yf-header__subscribe.wp-block-button.is-style-outline > .wp-block-button__link:hover,
.yf-hero5b__image .yf-header__subscribe .wp-block-button__link:hover {
	background: rgba(255, 255, 255, 0.22);
	border-color: rgba(255, 255, 255, 0.4);
	color: var(--wp--preset--color--on-image);
}

/* Hero stacking-context escape when WP's responsive overlay is open.
   `.yf-hero5b__image` has `isolation: isolate` (so its image + scrim +
   image-content layers stack correctly within the hero). That isolate
   creates a stacking context that TRAPS WP's overlay — even though
   WP renders the overlay at `position:fixed; z-index:100000`, the
   overlay is a DOM descendant of the hero, so the hero's later
   siblings (`.yf-hero5b__below` BigMediaCTAs, then homepage sections)
   paint ABOVE the overlay.

   Verified live in-iframe at 412 px: opening the hamburger showed
   "PHOTO ESSAY" / "VIDEO STORY" pills painting through the overlay
   container.

   Fix: when WP's Interactivity API toggles `html.has-modal-open`
   (only set while a nav-block overlay is open), raise the hero's
   z-index in the root stacking context. The hero already has
   `position: relative`, so a positive z-index applies cleanly.
   `1000` is the smallest value that beats the default 0 of later
   siblings without needing higher. Scoped to `html.has-modal-open`
   so it has zero effect at any other time. */
html.has-modal-open .yf-hero5b__image {
	z-index: 1000;
}

/* Scroll lock while the overlay is open. WP's Interactivity API
   sets `has-modal-open` on `<html>` (since WP 6.5); some legacy
   modal plugins set it on `<body>` instead. Targeting both is
   safe — they never both fire on the same page. */
html.has-modal-open,
body.has-modal-open {
	overflow: hidden;
}

/* Tablet hamburger — extend WP's overlay-mode breakpoint from
   the default `overlayMenu: "mobile"` (≤600) to ≤1199 so 601–1199
   widths get the hamburger button + native overlay instead of an
   inline nav that doesn't fit (6 nav items + util cluster collide
   at 768/820/853/912/1024 — verified live: at 768 the inline nav
   wraps `Luxury Travel` / `Travel Guide` to 2 lines each).

   Two minimum rules:
     (a) hide WP's inline display of the responsive container,
     (b) show WP's hamburger button.
   Everything else (overlay open/close state, focus trap, vertical
   item layout, close button) is handled by WP's Interactivity API
   natively. No `!important`. No flex `order` reposition. No drawer
   custom styling. No fighting WP's overlay CSS.

   Hamburger for the WHOLE tablet/mobile range (≤1199). Originally this
   started at min-width:601 assuming WP core collapses ≤600 — but core
   collapses at <600, leaving a 1px GAP at exactly 600px where the full
   desktop nav showed and forced horizontal overflow (~761px). Dropping
   the lower bound closes that gap (core's <600 behaviour is harmless to
   duplicate). Desktop ≥1200 sees no rule from this block — preserved. */
@media (max-width: 1199px) {
	.yf-header__nav .wp-block-navigation__responsive-container:not(.is-menu-open) {
		display: none;
	}
	.yf-header__nav .wp-block-navigation__responsive-container-open {
		display: flex;
	}
}

/* Subscribe at tablet (601–1199) — VISIBLE with compact sizing.
   Mobile (≤600) hides Subscribe (rule in the @media (max-width: 600px)
   block below). The full-size desktop Subscribe applies at ≥1200.
   At tablet the inline-nav has been replaced by the hamburger, so
   there is enough horizontal room for a compact Subscribe pill in
   the util cluster alongside search and the (also compact) lang
   switcher.

   Compact = reduced padding + smaller font + tighter letter-spacing.
   Specificity 0,4,1 (selector mirrors the base Subscribe rule at
   line ~2570 so it beats the base rule from inside this media
   query). */
@media (min-width: 601px) and (max-width: 1199px) {
	.yf-header__subscribe.wp-block-button.is-style-outline > .wp-block-button__link,
	.yf-header__subscribe .wp-block-button__link {
		padding: 6px 12px;
		font-size: 10px;
		letter-spacing: 0.1em;
	}
}

/* Subscribe hidden ONLY at mobile (≤600). Below this width the
   util cluster is already tight (hamburger + search + compact lang)
   and a Subscribe pill cannot fit cleanly. Footer "Get Updates"
   CTA remains the alternative path on mobile. */
@media (max-width: 600px) {
	.yf-header__subscribe-wrapper.wp-block-buttons {
		display: none;
	}
}

/* ============================================================
   COHERENT HEADER RESPONSIVE SYSTEM — Batch 23
   Addresses (per user spec, live-evidenced):
     1. Visual element order at <1200:
          [hamburger] [logo] [utilities]   (LTR)
          mirrored automatically under RTL via flex `order` +
          writing-mode-aware row direction.
     2. V5 paint of the open overlay panel (paper bg, ink text,
        V5 ui-font items, separator rules between top-level
        items, indented submenu items, RTL-aware close glyph).
     3. Compact language switcher pill at ≤600.

   Subscribe replacement at <1200: footer "Get Updates" CTA
   (already shipped in `parts/footer.html` line 15, pointing to
   /en/newsletter/ with Polylang URL-rewrite for AR).
   `parts/header.html` is intentionally NOT modified in this
   batch — pure CSS for everything below. If the design later
   requires Subscribe INSIDE the overlay menu, that needs a
   wp:navigation-link addition to parts/header.html and is a
   follow-up batch.
   ============================================================ */

/* (1) Visual order at <1200 — flex `order` reorders without
   touching DOM. At ≥1200 desktop, no order rule fires, so the
   natural DOM order (logo · nav · util) gives the correct
   desktop flow. At <1200 the wp:navigation collapses to its
   hamburger button (per the 601–1199 hamburger media query
   above + WP's native ≤600 mobile mode), so giving `.yf-header
   __nav` order:1 places the hamburger first.

   Under RTL, flex container `flex-direction: row` is logical
   and visually reverses — so order:1 becomes "first in inline
   flow" which is the right edge for RTL. No `[dir="rtl"]`
   override needed. */
@media (max-width: 1199px) {
	.yf-header {
		gap: 12px;
	}
	.yf-header__nav {
		order: 1;
		flex: 0 0 auto;
		/* anchor the hamburger to the inline-start edge */
		margin-inline-end: 0;
	}
	.yf-header__logo {
		order: 2;
		flex: 1 1 auto;
		text-align: center;
	}
	.yf-header__util {
		order: 3;
		flex: 0 0 auto;
		/* `margin-inline-start: auto` redundantly pushes the util
		   cluster hard to the inline-end edge (LTR: right edge;
		   RTL: left edge). Without this the cluster sits at the
		   end of flex flow but can look loosely centered when the
		   logo absorbs the extra space. Forcing auto-margin gives
		   the search + switcher group an explicit edge anchor. */
		margin-inline-start: auto;
		/* Tighter internal spacing so search + switcher feel
		   grouped, not floating apart. */
		gap: 6px;
	}
}

/* (3) Compact language switcher at mobile (≤600) — the pill
   was consuming ~25% of header width on a 412 viewport because
   the chevron uses 26 px right-padding + the full word
   ("English" / "العربية"). Reduce padding + font-size at ≤600
   only — desktop and tablet pill sizes preserved.

   IMPORTANT: the existing RTL chevron-flip rule at line ~2506
   uses BOTH `[dir="rtl"]` (0,2,1) AND `:root[lang^="ar"]`
   (0,3,1) as selectors. Browsers pick the higher of the two
   matching specificities for the cascade. At our test page
   the html has `lang="ar"`, so `:root[lang^="ar"]` matches and
   wins at 0,3,1. To beat it, the RTL compact rule below must
   include both forms with at least the same specificity, AND
   come later in source order. */
@media (max-width: 600px) {
	/* Mobile compact lang switcher — 35% smaller than the prior
	   "first-pass" compact (which was already smaller than the
	   desktop pill). Combined target: pill total ~50 px wide vs.
	   desktop ~110 px. Padding tightened, font dropped from 10 → 9,
	   letter-spacing zeroed so the language word is dense.
	   Background size of the chevron arrow also reduced to match. */
	.yf-header__lang .lang-choice-pll,
	.yf-header__lang select {
		padding: 3px 14px 3px 5px;
		font-size: 9px;
		letter-spacing: 0;
		background-size: 8px 5px;
		background-position: right 6px center;
		/* Explicit width to force the pill narrower than its
		   natural intrinsic width. Mobile-only (inside @media
		   max-width: 600px). At 412 viewport before this line
		   the rendered width was 96 px (measured live). */
		width: 60px;
	}
	[dir="rtl"] .yf-header__lang .lang-choice-pll,
	[dir="rtl"] .yf-header__lang select,
	:root[lang^="ar"] .yf-header__lang .lang-choice-pll,
	:root[lang^="ar"] .yf-header__lang select {
		padding: 3px 5px 3px 14px;
		background-position: left 6px center;
	}
}

/* (2) V5 paint of the open overlay panel.
   Scope: every rule below is gated on
   `.wp-block-navigation__responsive-container.is-menu-open`.
   The closed-overlay state and the desktop inline nav are
   completely untouched.

   Specificity strategy: WP's wp-block-library ships
   `.wp-block-navigation:not(.has-background) .wp-block-
   navigation__responsive-container.is-menu-open` at 0,4,0
   specificity (verified live via styleSheets walk). To win
   without `!important`, every paint rule below is anchored on
   `.wp-block-navigation.yf-header__nav` (compound on the same
   element — the wp:navigation block carries both classes) for
   0,4,0 specificity matched; theme stylesheet loads after the
   block library so source-order tie-break favours theme. */

/* Outer container = SCRIM (semi-transparent ink wash that
   dims the page behind the drawer). The actual visible menu
   panel is the `.responsive-dialog` child below — sized
   ~50 vw with min/max clamps and anchored to the inline-start
   edge so it slides in from the same side as the hamburger
   (LTR: left; RTL: right). Clicking the scrim closes the
   overlay (handled natively by WP's Interactivity API).

   HMTB Item 3 — white-fill fix. A newer WP core raised its overlay-paint
   selector to `.wp-block-navigation:not(.has-background) …is-menu-open
   :not(.disable-default-overlay)` = (0,5,0) {background:#fff} (verified
   live via CDP), defeating this scrim rule's former (0,4,0) — so the
   container rendered SOLID WHITE full-viewport (the "white fill beside/
   under the menu"). Appending `:not(.disable-default-overlay)` lifts this
   rule to (0,5,0); theme loads after core so source-order wins → the
   intended translucent ink scrim shows, the page dims behind the paper
   drawer, and no white panel appears. Mobile + tablet both fixed. */
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open:not(.disable-default-overlay) {
	background-color: rgba(28, 24, 20, 0.45);
}

/* Visible drawer panel — paper bg, narrow column, anchored to
   inline-start of the viewport. Width is clamp-bounded so it
   stays readable (≥260 px) and never becomes a wide panel on
   tablet (≤380 px). At 412 viewport this resolves to 260 px
   (50 vw = 206 clamped up to 260). At 768 it resolves to
   384 px clamped to 380. */
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-dialog {
	background-color: var(--wp--preset--color--paper);
	width: clamp(260px, 50vw, 380px);
	max-width: 100vw;
	height: 100vh;
	height: 100dvh;
	margin: 0;
	padding: 0;
	position: absolute;
	inset-block-start: 0;
	inset-block-end: 0;
	inset-inline-start: 0;
	overflow-y: auto;
	box-shadow: 0 0 24px rgba(28, 24, 20, 0.18);
}

/* Inner content padding — comfortable thumb-reach + breathing
   room from the close glyph at the top corner. */
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__responsive-container-content {
	padding: 64px 24px 32px;
	color: var(--wp--preset--color--ink);
}

/* Top-level item typography — V5 ui font, 600 weight,
   touch-friendly padding, ink color (already set by Fix 2
   from Batch 22 via the 5-class specificity override, kept). */
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > .wp-block-navigation-item__content,
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item > button.wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--ui);
	font-size: 18px;
	font-weight: 600;
	letter-spacing: 0.04em;
	line-height: 1.2;
	padding: 14px 0;
}

/* Top-level item separator — calm rule between items, picks
   up V5 rule color. Last item has no border (the close
   button area is below). */
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item {
	border-bottom: 1px solid var(--wp--preset--color--rule);
}
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__container > .wp-block-navigation-item:last-child {
	border-bottom: 0;
}

/* Submenu items inside the open overlay — slightly smaller,
   indented (logical inline-start so RTL-safe), lighter weight. */
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	font-family: var(--wp--preset--font-family--ui);
	font-size: 14px;
	font-weight: 400;
	letter-spacing: 0.02em;
	padding: 10px 0;
	padding-inline-start: 18px;
}

/* Submenu in overlay = no card, no border, no shadow — just
   inline indented items. The card surface (from the desktop
   submenu rule at line 2445) is overridden here for overlay
   context only. */
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
	background-color: transparent;
	border: 0;
	border-radius: 0;
	box-shadow: none;
	padding: 0;
	min-width: 0;
	position: static;
}

/* Close button — V5 weight, sized for thumb, ink color,
   placed at the inline-end of the dialog header for both
   LTR (top-right) and RTL (top-left). Logical property does
   the direction switch automatically. */
.wp-block-navigation.yf-header__nav .wp-block-navigation__responsive-container-close {
	width: 36px;
	height: 36px;
	top: 20px;
	inset-inline-end: 20px;
	inset-inline-start: auto;
	color: var(--wp--preset--color--ink);
}

/* ─── Hero byline — used inside the homepage hero's frosted
   plane (Batch 11.7) as the byline component (avatar circle +
   stacked name + meta). The `.yf-hero5b__byline-row` rule
   previously here referenced the old below-row layout and was
   removed when the hero was rebuilt to HeroBandV4.            */
.yf-hero5b__byline {
	color: var(--wp--preset--color--ink);
}
.yf-hero5b__byline-portrait {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	margin: 0;
	background: var(--wp--preset--color--accent-quiet);
	color: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--display);
	font-size: 18px;
	font-style: italic;
	flex-shrink: 0;
}
.yf-hero5b__byline-text {
	gap: 4px;
}
.yf-hero5b__byline-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 13px;
	font-weight: 600;
	color: var(--wp--preset--color--ink);
}
.yf-hero5b__byline-meta {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}

/* BigMediaCTA (v4) — block-native wp:group wrapper with
   nested icon + body groups. Icon is an empty wp:group; its
   SVG glyph is supplied via CSS ::before mask-image (driven
   by `--photo` / `--video` modifier). No wp:html.            */
.yf-media-cta4 {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 18px;
	padding: 14px 22px 14px 16px;
	background: var(--wp--preset--color--paper);
	border-radius: var(--wp--custom--yf--radius--pill, 999px);
	box-shadow: 0 8px 24px rgba(28, 24, 20, 0.12);
	cursor: pointer;
	transition: transform 0.35s var(--wp--custom--yf--easing--air, ease-out),
		box-shadow 0.35s var(--wp--custom--yf--easing--air, ease-out);
	width: max-content;
}
.yf-media-cta4:hover {
	transform: translateY(-2px);
	box-shadow: 0 14px 36px rgba(28, 24, 20, 0.18);
}
/* Stretched-link pattern — the `<a>` inside `.yf-media-cta4__label`
   carries the click target, and its `::after` invisible overlay
   makes the whole CTA pill clickable. The link text remains
   editor-editable in the label paragraph via the rich-text Link
   toolbar; no extra markup is required for clickability.       */
.yf-media-cta4__label a {
	color: inherit;
	text-decoration: none;
}
.yf-media-cta4__label a::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}
.yf-media-cta4__icon {
	width: 48px;
	height: 48px;
	border-radius: 50%;
	background: var(--wp--preset--color--ink);
	color: var(--wp--preset--color--paper);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
}
.yf-media-cta4__icon::before {
	content: "";
	display: block;
	width: 18px;
	height: 18px;
	background-color: currentColor;
	-webkit-mask-position: center;
	        mask-position: center;
	-webkit-mask-repeat: no-repeat;
	        mask-repeat: no-repeat;
	-webkit-mask-size: contain;
	        mask-size: contain;
}
.yf-media-cta4--photo .yf-media-cta4__icon::before {
	-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18' fill='none' stroke='black' stroke-width='1.6'><rect x='2' y='3' width='14' height='11'/><path d='M2 11l4-4 3 3 3-3 5 4'/></svg>");
	        mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18' fill='none' stroke='black' stroke-width='1.6'><rect x='2' y='3' width='14' height='11'/><path d='M2 11l4-4 3 3 3-3 5 4'/></svg>");
}
.yf-media-cta4--video .yf-media-cta4__icon::before {
	-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><path d='M6 4l9 5-9 5z'/></svg>");
	        mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 18 18'><path d='M6 4l9 5-9 5z'/></svg>");
}
.yf-media-cta4__body {
	display: flex;
	flex-direction: column;
	gap: 4px;
	color: var(--wp--preset--color--ink);
}
.yf-media-cta4__kicker {
	margin: 0 !important;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 9px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}
.yf-media-cta4__label {
	margin: 0 !important;
	font-family: var(--wp--preset--font-family--display);
	font-size: 17px;
	font-style: italic;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}

/* (Scroll-cue rules and `@keyframes yfScrollPulse` removed in
   Batch 13.1 — the homepage hero no longer carries a scroll cue
   per the V5 Hero B source. The cross-template editor.css
   override that disabled the pulse animation in the Site Editor
   has also been removed.)                                       */

/* ─── BtnV4 — RETIRED in BATCH B / B4 ─────────────────────
 * The primary pill button (.yf-btn4) and its dormant paper-on-ink
 * per-button override (.yf-home-guides__cta) are RETIRED. Their visual
 * identity is now carried by the editor-selectable `is-style-cta` block
 * style variation (/styles/button-cta.json), which replicates the exact
 * BtnV4 appearance (ink/paper, 18×28 pill, 12px uppercase 0.16em; hover
 * accent + translateY(-2px) + accent shadow). The two front-page CTAs now
 * use `is-style-cta`. Proven 0px / 0 color drift. The `.yf-home-guides__cta`
 * override was already masked (lost specificity to BtnV4's 0-3-0 rule) so
 * its removal changes nothing. (`.yf-home-guides__cta-row` layout kept.)
 * ──────────────────────────────────────────────────────── */

/* ─── CardV4 family ───────────────────────────────────── */
.yf-card4 {
	position: relative;
	display: flex;
	flex-direction: column;
	cursor: pointer;
	transition: transform 0.5s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-card4:hover {
	transform: translateY(-6px);
}

/* Media wrapper — image + optional stamp + optional pill */
.yf-card4__media {
	position: relative;
	border-radius: 18px;
	overflow: hidden;
	background: var(--wp--preset--color--paper-deep);
	box-shadow: 0 2px 8px rgba(28, 24, 20, 0.06), 0 14px 32px rgba(28, 24, 20, 0.08);
	transition: box-shadow 0.5s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-card4:hover .yf-card4__media {
	box-shadow: 0 6px 18px rgba(28, 24, 20, 0.10), 0 28px 60px rgba(28, 24, 20, 0.18);
}

/* Image inside card media — empty placeholder renders as
   paper-deep aspect-ratio rectangle (no broken-image icon). */
.yf-card4__media .wp-block-image,
.yf-card4__img {
	margin: 0;
	width: 100%;
	aspect-ratio: 4 / 5;
	background-color: var(--wp--preset--color--paper-deep);
	overflow: hidden;
}
.yf-card4__media .wp-block-image img,
.yf-card4__img img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: transform 1.4s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-card4:hover .wp-block-image img,
.yf-card4:hover .yf-card4__img img {
	transform: scale(1.07);
}
/* Hide placeholder broken-image icon for empty <img> elements. */
.yf-card4__media .wp-block-image img:not([src]),
.yf-card4__media .wp-block-image img[src=""],
.yf-card4__img img:not([src]),
.yf-card4__img img[src=""] {
	display: none;
}

/* Postcard stamp — top-right, rotated, accent text */
.yf-card4__stamp {
	position: absolute;
	top: 16px;
	right: 16px;
	margin: 0;
	padding: 8px 12px 7px;
	background: var(--wp--preset--color--paper);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 700;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
	box-shadow: 0 2px 8px rgba(28, 24, 20, 0.18);
	transform: rotate(-3deg);
	transition: transform 0.35s var(--wp--custom--yf--easing--air, ease-out);
	z-index: 2;
}
.yf-card4:hover .yf-card4__stamp {
	transform: rotate(-1deg) translateY(-2px);
}

/* Below — text content under the media */
.yf-card4__below {
	padding-top: 22px;
}
.yf-card4__kicker {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}
.yf-card4__title {
	position: relative;
	display: inline-block;
	align-self: flex-start;
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 26px;
	font-weight: 400;
	line-height: 1.14;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--ink);
}
.yf-card4__title a {
	color: inherit;
	text-decoration: none;
}
.yf-card4__title::after {
	content: "";
	position: absolute;
	left: 0;
	right: 100%;
	bottom: -3px;
	height: 1.5px;
	background: var(--wp--preset--color--accent);
	transition: right 0.5s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-card4:hover .yf-card4__title::after {
	right: 0;
}
.yf-card4__meta {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 11px;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ink-mute);
}
.yf-card4__standfirst {
	margin: 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: 14px;
	line-height: 1.55;
	color: var(--wp--preset--color--ink-soft);
}

/* CardV4 feature variant — wider image, larger title */
.yf-card4--feature .yf-card4__media .wp-block-image,
.yf-card4--feature .yf-card4__img {
	aspect-ratio: 16 / 11;
}
.yf-card4--feature .yf-card4__title {
	font-size: 38px;
}

/* CardV4 text variant — no image, accent rule top */
.yf-card4--text {
	padding: 36px 30px 28px;
	background: var(--wp--preset--color--paper-soft);
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 18px;
	aspect-ratio: 4 / 5;
	justify-content: space-between;
	transition: transform 0.5s var(--wp--custom--yf--easing--air, ease-out),
		box-shadow 0.5s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-card4--text::before {
	content: "";
	position: absolute;
	top: 0;
	left: 30px;
	right: 30px;
	height: 3px;
	background: var(--wp--preset--color--accent);
	border-radius: 0 0 3px 3px;
}
.yf-card4--text:hover {
	transform: translateY(-6px);
	box-shadow: 0 28px 60px rgba(28, 24, 20, 0.14);
}
.yf-card4--text .yf-card4__title {
	font-size: 28px;
	font-style: italic;
	margin-top: 14px;
}

/* CardV4 pick variant — full-bleed image with overlay (galleries) */
.yf-card4--pick {
	position: relative;
	border-radius: 18px;
	overflow: hidden;
	background: var(--wp--preset--color--ink);
	aspect-ratio: 3 / 4;
}
.yf-card4--pick .wp-block-post-featured-image,
.yf-card4-pick-img {
	position: absolute;
	inset: 0;
	margin: 0;
	background-color: var(--wp--preset--color--ink);
}
.yf-card4--pick .wp-block-post-featured-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 1.4s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-card4--pick:hover .wp-block-post-featured-image img {
	transform: scale(1.06);
}
.yf-card4--pick::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, transparent 40%, rgba(28, 24, 20, 0.78) 100%);
	pointer-events: none;
}
.yf-card4-pick-content {
	position: absolute;
	left: 22px;
	right: 22px;
	bottom: 22px;
	z-index: 2;
	color: var(--wp--preset--color--on-image);
}
.yf-card4-pick-from,
.yf-card4--pick .wp-block-post-terms {
	font-family: var(--wp--preset--font-family--display);
	font-size: 14px;
	font-style: italic;
	color: var(--wp--preset--color--accent-soft);
	margin: 0 0 8px;
}
.yf-card4--pick .wp-block-post-terms a {
	color: inherit;
	text-decoration: none;
}
.yf-card4-pick-title,
.yf-card4--pick .wp-block-post-title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 24px;
	font-weight: 400;
	line-height: 1.12;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--on-image);
}
.yf-card4--pick .wp-block-post-title a {
	color: inherit;
	text-decoration: none;
}

/* ─── Homepage section base ───────────────────────────── */
.yf-home-section__header {
	width: 100%;
}
.yf-home-section__kicker {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}
.yf-home-section__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: 44px;
	font-weight: 400;
	line-height: 1.05;
	letter-spacing: -0.015em;
	color: var(--wp--preset--color--ink);
	text-wrap: balance;
}
.yf-home-section__title--italic {
	font-style: italic;
}
.yf-home-section__note {
	margin: 0;
	max-width: 360px;
	font-family: var(--wp--preset--font-family--body);
	font-size: 18px;
	line-height: 1.55;
	font-style: italic;
	color: var(--wp--preset--color--ink-soft);
}
.yf-home-section__link {
	margin: 0 !important;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.04em;
}
.yf-home-section__link a {
	color: var(--wp--preset--color--ink);
	text-decoration: none;
	border-bottom: 1px solid var(--wp--preset--color--ink);
	padding-bottom: 2px;
	transition: color 0.2s var(--wp--custom--yf--easing--air, ease-out),
		border-color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-home-section__link a:hover {
	color: var(--wp--preset--color--accent);
	border-color: var(--wp--preset--color--accent);
}

/* ─── Editor's Picks ──────────────────────────────────── */
.yf-home-picks .yf-home-section__title {
	font-size: 60px;
	font-style: italic;
	line-height: 1.04;
	letter-spacing: -0.02em;
}
.yf-home-picks__grid {
	display: grid;
	grid-template-columns: 1.4fr 1fr 1fr;
	gap: 32px;
}

/* ─── Destinations ────────────────────────────────────── */
/* B3 de-lock: duplicated repeat(4)!important removed so the Post Template
   columnCount (4) drives - identical look, editor control effective. */
.yf-home-destinations__grid.is-layout-grid {
	gap: 24px;
}

/* ─── Galleries & films ───────────────────────────────── */
/* Galleries grid — asymmetric `1.4fr 1fr 1fr` per HomepageV4
   (the first PickCard is the editorial feature, neighbours are
   uniform 1fr). The wp:post-template's default uniform 3-up grid
   is overridden via class scope.                                 */
.yf-home-galleries__grid.is-layout-grid,
.yf-home-galleries .wp-block-post-template.is-layout-grid {
	grid-template-columns: 1.4fr 1fr 1fr !important;
	gap: 24px;
}
.yf-home-galleries__empty {
	margin: 0;
	padding: 48px 0;
	font-family: var(--wp--preset--font-family--body);
	font-size: 17px;
	font-style: italic;
	color: var(--wp--preset--color--ink-mute);
	text-align: center;
}

/* ─── Stories rail ────────────────────────────────────── */
/* B3 de-lock: duplicated repeat(3)!important removed; columnCount (3) drives. */
.yf-home-stories__grid.is-layout-grid {
	gap: 32px;
}

/* ─── Guides band (ink) ───────────────────────────────── */
.yf-home-guides {
	position: relative;
	color: var(--wp--preset--color--paper);
	overflow: hidden;
}
/* Atmospheric outline-circle decoration — was a wp:html div in
   Batch 11.x; now drawn purely via CSS so the editor sees only
   valid blocks. */
.yf-home-guides::before {
	content: "";
	position: absolute;
	top: -80px;
	left: -80px;
	width: 320px;
	height: 320px;
	border: 1.5px solid var(--wp--preset--color--accent-quiet);
	border-radius: 50%;
	opacity: 0.18;
	pointer-events: none;
	z-index: 0;
}
.yf-home-guides__inner {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: 1.2fr 1fr;
	gap: 96px;
	align-items: center;
	max-width: 1280px;
	margin: 0 auto;
}
.yf-home-guides__inner > * {
	max-width: none !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
}
.yf-home-guides__copy {
	max-width: 640px;
}
.yf-home-guides__kicker {
	margin: 0 0 16px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent-quiet);
}
.yf-home-guides__title {
	margin: 0 0 24px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 84px;
	font-style: italic;
	font-weight: 400;
	line-height: 0.98;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--paper);
	text-wrap: balance;
}
.yf-home-guides__body {
	margin: 0 0 36px;
	max-width: 520px;
	font-family: var(--wp--preset--font-family--body);
	font-size: 22px;
	line-height: 1.5;
	color: rgba(244, 238, 227, 0.78);
}
.yf-home-guides__cta-row {
	margin: 0 0 24px;
	align-items: center;
}
.yf-home-guides__meta {
	margin: 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	color: rgba(244, 238, 227, 0.5);
}
.yf-home-guides__image-wrap {
	position: relative;
}
.yf-home-guides__image,
.yf-home-guides__image-wrap .wp-block-image {
	margin: 0;
	aspect-ratio: 3 / 4;
	background-color: var(--wp--preset--color--paper-deep);
	border-radius: 18px;
	overflow: hidden;
	box-shadow: 0 30px 60px rgba(0, 0, 0, 0.4);
}
.yf-home-guides__image img,
.yf-home-guides__image-wrap .wp-block-image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}
.yf-home-guides__image-wrap .wp-block-image img:not([src]),
.yf-home-guides__image-wrap .wp-block-image img[src=""] {
	display: none;
}
.yf-home-guides__pill {
	position: absolute;
	top: 24px;
	left: 24px;
	margin: 0;
	padding: 10px 18px;
	background: var(--wp--preset--color--paper);
	color: var(--wp--preset--color--ink);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 600;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	border-radius: var(--wp--custom--yf--radius--pill, 999px);
	z-index: 2;
}

/* ─── Newsletter band ─────────────────────────────────── */
.yf-home-newsletter__panel {
	position: relative;
	max-width: 1280px;
	margin: 0 auto;
	overflow: hidden;
}
/* Two atmospheric outline-circles — large top-right, small mid-right.
   Were wp:html divs in Batch 11.x; now drawn via the panel's own
   `::before` (large) and `::after` (small) pseudo-elements. */
.yf-home-newsletter__panel::before,
.yf-home-newsletter__panel::after {
	content: "";
	position: absolute;
	border: 1px solid var(--wp--preset--color--accent);
	border-radius: 50%;
	pointer-events: none;
	z-index: 0;
}
.yf-home-newsletter__panel::before {
	top: -120px;
	right: -120px;
	width: 320px;
	height: 320px;
	border-width: 1.5px;
	opacity: 0.5;
}
.yf-home-newsletter__panel::after {
	top: 80px;
	right: 200px;
	width: 80px;
	height: 80px;
	opacity: 0.3;
}
.yf-home-newsletter__inner {
	position: relative;
	z-index: 1;
	display: grid;
	grid-template-columns: 1.3fr 1fr;
	gap: 80px;
	align-items: center;
}
.yf-home-newsletter__inner > * {
	max-width: none !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
}
.yf-home-newsletter__copy {
	max-width: 480px;
}
.yf-home-newsletter__kicker {
	margin: 0 0 16px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	color: var(--wp--preset--color--accent);
}
.yf-home-newsletter__title {
	margin: 0 0 24px;
	font-family: var(--wp--preset--font-family--display);
	font-size: 60px;
	font-style: italic;
	font-weight: 400;
	line-height: 1.02;
	letter-spacing: -0.02em;
	color: var(--wp--preset--color--ink);
	text-wrap: balance;
}
.yf-home-newsletter__body {
	margin: 0;
	max-width: 440px;
	font-family: var(--wp--preset--font-family--body);
	font-size: 19px;
	line-height: 1.55;
	color: var(--wp--preset--color--ink-soft);
}
.yf-home-newsletter__cta .wp-block-buttons {
	margin: 0;
}
.yf-home-newsletter__meta {
	margin: 16px 0 0;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 12px;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--ink-mute);
}

/* ============================================================
   BATCH 11.3 — block-validity-first composition rules.

   Every decorative element that previously lived in a `wp:html`
   block (BigMediaCTA icons, scroll-cue animated bar, atmosphere
   rings, byline divider, card readMin pill clock icons) is now
   drawn via CSS pseudo-elements (`::before` / `::after`) so the
   editor sees only valid core blocks. SVG glyphs are supplied
   via `mask-image: url("data:image/svg+xml;…")` so the colour
   stays themed.

   Composition rules (hero 2-column below-grid, guides 1.2/1
   grid, newsletter 1.3/1 grid, picks `1.4fr 1fr 1fr` grid) sit
   alongside. Constrained-layout's `margin-left/right: auto`
   default (which would centre inline-block card titles inside
   their columns) is overridden where it would harm composition.
   ============================================================ */

/* Editor's-Picks editorial label — display 16px italic accent,
   matches the design's `.yf-rail3__label` typography. Replaces
   the previous shared `__kicker--italic` (12 px UI uppercase).  */
.yf-home-picks__label {
	margin: 0 !important;
	font-family: var(--wp--preset--font-family--display);
	font-size: 16px;
	font-style: italic;
	font-weight: 400;
	letter-spacing: -0.01em;
	color: var(--wp--preset--color--accent);
}

/* CardV4 read-time pill — bottom-right of the media box.
   Was a wp:html block; now a wp:paragraph with the clock glyph
   supplied via `::before` mask-image.                           */
.yf-card4__pill {
	position: absolute;
	right: 16px;
	bottom: 16px;
	margin: 0 !important;
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 12px;
	background: rgba(28, 24, 20, 0.72);
	-webkit-backdrop-filter: blur(14px);
	        backdrop-filter: blur(14px);
	border-radius: var(--wp--custom--yf--radius--pill, 999px);
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 600;
	letter-spacing: 0.06em;
	color: var(--wp--preset--color--paper);
	z-index: 2;
}
.yf-card4__pill::before {
	content: "";
	display: inline-block;
	width: 9px;
	height: 9px;
	background-color: currentColor;
	flex-shrink: 0;
	-webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='black' stroke-width='1.4'><circle cx='6' cy='6' r='4.5'/><path d='M6 3.5V6l1.5 1.5'/></svg>");
	        mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='black' stroke-width='1.4'><circle cx='6' cy='6' r='4.5'/><path d='M6 3.5V6l1.5 1.5'/></svg>");
	-webkit-mask-position: center;
	        mask-position: center;
	-webkit-mask-repeat: no-repeat;
	        mask-repeat: no-repeat;
	-webkit-mask-size: contain;
	        mask-size: contain;
}

/* Text-card subgroups — two block-native wp:group children of
   `.yf-card4--text`. Flex-column space-between on `.yf-card4`
   already distributes them; the bottom group gets the hairline
   separator via `border-top` so no wp:separator is needed.     */
.yf-card4--text__top {
	display: flex;
	flex-direction: column;
	gap: 16px;
}
.yf-card4--text__bottom {
	border-top: 1px solid var(--wp--preset--color--rule);
	padding-top: 14px;
}

/* (`.yf-hero5b__below-grid` / `__below-left` / `__below-right`
   rules previously here were the Batch 11.3 two-column composition
   for the OLD Hero B sibling structure; the hero has been rebuilt
   to HeroBandV4 in Batch 11.7 and those classes no longer exist
   in the markup. Layout for the new hero lives at the top of this
   file under `.yf-hero5b__bottom`, `.yf-hero5b__plane`, and
   `.yf-hero5b__rightslot`.) */

/* Byline divider — a 1×36 hairline before the byline. In Batch
   11.7 the byline sits inside the frosted plane's row alongside
   the BtnV4 CTA; the divider sits to the left of the byline so
   it visually separates the CTA from the author block.         */
.yf-hero5b__byline {
	position: relative;
	padding-left: 25px;
}
.yf-hero5b__byline::before {
	content: "";
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(-50%);
	width: 1px;
	height: 36px;
	background: var(--wp--preset--color--rule);
}

/* Constrained-layout override for card-internal and section-
   header-internal wrappers. WP's default constrained layout
   centres inline-block children via `margin-left/right: auto
   !important`. Inside a narrow card column this can centre
   short titles or kickers — the design wants them left-aligned
   against the column edge. !important is required to beat WP's
   `!important` margin auto.                                     */
.yf-card4__media.is-layout-constrained > *,
.yf-card4__below.is-layout-constrained > *,
.yf-card4--text > *,
.yf-card4--text__top > *,
.yf-card4--text__bottom > *,
.yf-media-cta4__body.is-layout-constrained > *,
.yf-media-cta4__icon.is-layout-constrained > *,
.yf-home-section__header > .wp-block-group.is-layout-constrained > *,
.yf-home-guides__copy.is-layout-constrained > *,
.yf-home-guides__image-wrap.is-layout-constrained > *,
.yf-home-newsletter__copy.is-layout-constrained > *,
.yf-home-newsletter__cta.is-layout-constrained > * {
	margin-left: 0 !important;
	margin-right: 0 !important;
	max-width: none;
}

/* Re-assert the title/inline-block left-alignment in case any
   ancestor still applies margin-auto. `.yf-card4__title` is
   `display: inline-block` so margin-auto would centre it.      */
.yf-card4__title,
.yf-card4__kicker,
.yf-card4__meta,
.yf-card4__standfirst,
.yf-home-section__title,
.yf-home-section__kicker,
.yf-home-section__note,
.yf-home-guides__kicker,
.yf-home-guides__title,
.yf-home-guides__body,
.yf-home-guides__meta,
.yf-home-guides__pill,
.yf-home-newsletter__kicker,
.yf-home-newsletter__title,
.yf-home-newsletter__body,
.yf-home-newsletter__meta,
.yf-hero5b__dek,
.yf-hero5b__kicker-text,
.yf-hero5b__byline-name,
.yf-hero5b__byline-meta,
.yf-hero5b__byline-portrait {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

/* ─── Responsive ─────────────────────────────────────── */
@media (max-width: 1199px) {
	.yf-home-guides__title {
		font-size: 64px;
	}
	.yf-home-newsletter__title,
	.yf-home-picks .yf-home-section__title {
		font-size: 48px;
	}
}
@media (max-width: 900px) {
	/* Header */
	.yf-header {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px);
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px);
	}
	/* Subscribe-hide formerly lived in this block at ≤900. Moved to
	   a dedicated `@media (max-width: 600px)` block above (mobile
	   only). Tablet (601–1199) now SHOWS Subscribe with compact
	   sizing — see the `@media (min-width: 601px) and (max-width:
	   1199px)` block above. */

	/* Hero — keep cinematic but soften paddings */
	.yf-hero5b__image--cinematic {
		min-height: 540px;
	}
	.yf-hero5b__below {
		padding-top: 40px !important;
		padding-bottom: 80px !important;
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
	}
	/* (Old `.yf-hero5b__below-grid` / `__below-right` / `__byline-row`
	   responsive rules removed in Batch 11.7 — those classes no
	   longer exist. The new hero's mobile collapse is handled by
	   the `.yf-hero5b__bottom { grid-template-columns: 1fr }` rule
	   in the Batch 11.7 hero CSS block at the top of this file.) */

	/* Homepage sections — softer paddings, stacked grids */
	.yf-home-section {
		padding-left: var(--wp--custom--yf--gutter-mobile, 24px) !important;
		padding-right: var(--wp--custom--yf--gutter-mobile, 24px) !important;
	}
	.yf-home-section__title {
		font-size: 34px;
	}
	.yf-home-picks .yf-home-section__title,
	.yf-home-newsletter__title {
		font-size: 36px;
	}

	.yf-home-picks__grid {
		grid-template-columns: 1fr;
		gap: 40px;
	}
	.yf-home-destinations__grid.is-layout-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}
	.yf-home-galleries__grid.is-layout-grid,
	.yf-home-galleries .wp-block-post-template.is-layout-grid,
	.yf-home-stories__grid.is-layout-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
	}

	/* Guides + Newsletter inner grids collapse to single column. */
	.yf-home-guides__inner {
		grid-template-columns: 1fr;
		gap: 48px;
	}
	.yf-home-newsletter__inner {
		grid-template-columns: 1fr;
		gap: 40px;
	}

	.yf-home-guides__title {
		font-size: 48px;
	}
	.yf-home-guides__body {
		font-size: 18px;
	}
	.yf-home-guides__image-wrap {
		max-width: 100%;
	}
	.yf-home-newsletter__panel {
		padding-top: 64px !important;
		padding-right: 32px !important;
		padding-bottom: 64px !important;
		padding-left: 32px !important;
	}
	.yf-home-newsletter__body {
		font-size: 17px;
	}
}
@media (max-width: 600px) {
	.yf-home-section__title {
		font-size: 28px;
	}
	.yf-home-picks .yf-home-section__title,
	.yf-home-newsletter__title {
		font-size: 30px;
	}
	.yf-home-destinations__grid.is-layout-grid,
	.yf-home-galleries__grid.is-layout-grid,
	.yf-home-galleries .wp-block-post-template.is-layout-grid,
	.yf-home-stories__grid.is-layout-grid {
		grid-template-columns: 1fr !important;
	}
	.yf-home-guides__title {
		font-size: 38px;
	}
	.yf-card4--feature .yf-card4__title {
		font-size: 28px;
	}
	.yf-card4__title {
		font-size: 22px;
	}
	.yf-media-cta4__label {
		font-size: 15px;
	}
}

/* ----------------------------------------------------------------
 * MW3.15 — BUG-TOC-001 hybrid: desktop sticky rail + mobile/narrow-tablet inline collapsible.
 * No drawer, no overlay, no second nav. Existing yoyafun_get_post_toc() emits <details><summary>
 * disclosure as a child of .yf-single__body article when shortcode is invoked inline.
 *
 * HMTB Item 4 — boundary moved 900/901 -> 1199/1200. The rail column
 * only becomes a real side sidebar at >=1200 (verified live: rail TOC at
 * w~268 / y~1415 beside the article at 1200/1280). In the 901-1199 tablet
 * band the rail column STACKS, so the rail TOC (a force-open <details>
 * with hidden summary = flat list) was being dumped at the very BOTTOM of
 * the page (y~8500). Tablet is defined as <=1199 (same range that gets the
 * nav hamburger). So tablet now shows the INLINE COLLAPSIBLE <details>
 * (closed, with visible summary, like mobile); only true desktop >=1200
 * keeps the sticky rail. The TOC markup is untouched (CSS-only).
 * ---------------------------------------------------------------- */
@media (min-width: 1200px) {
	/* Hide INLINE body TOC on desktop only (sticky rail TOC handles it) */
	.yf-single__body > .yf-toc { display: none; }
}
@media (max-width: 1199px) {
	/* Hide RAIL TOC across the whole tablet+mobile range; the inline
	   collapsible <details> dropdown handles it (never a flat list dumped
	   below the article). */
	.yf-rail4__module--toc { display: none; }
}

/* =========================================================
 * MW3.21 — Reading-progress bar (singular post views only).
 * Rendered by inc/reading-progress.php on wp_body_open.
 * ========================================================= */
.yf-reading-progress { position: fixed; top: 0; inset-inline-start: 0; inset-inline-end: 0; height: 3px; background: transparent; z-index: 100001; pointer-events: none; }
.yf-reading-progress__fill { height: 100%; width: 0%; background: var(--wp--preset--color--accent); transform-origin: left center; transition: width 0.05s ease-out; }
[data-yf-lang][dir="rtl"] .yf-reading-progress__fill, html[dir="rtl"] .yf-reading-progress__fill { transform-origin: right center; }
@media (prefers-reduced-motion: reduce) { .yf-reading-progress__fill { transition: none; } }

/* =========================================================
 * MW3.22 — Archive 4×3 grid redesign (M1-K5 OQ-07).
 * Used by templates/archive.html grid layout. Old .yf-archive__item
 * rules retained for templates/search.html compatibility.
 *
 * A3 de-lock: the base `grid-template-columns: repeat(4, 1fr)` was REMOVED
 * so the Post Template block's own `columnCount` (currently 4) drives the
 * desktop column count — i.e. an editor change to columnCount now takes
 * effect instead of being overridden by this CSS. The 4-col look is
 * unchanged (WP's columnCount:4 emits repeat(4, minmax(0,1fr)) = the same
 * grid). display:grid + gap are kept; the responsive 3/2/1 steps below stay
 * as a NON-!important fallback (WP's columnCount grids don't auto-collapse).
 * ========================================================= */
.yf-archive__grid { display: grid; gap: 40px 32px; }
@media (max-width: 1199px) { .yf-archive__grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 900px)  { .yf-archive__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px)  { .yf-archive__grid { grid-template-columns: 1fr; } }
.yf-archive__card { display: flex; flex-direction: column; gap: 12px; }
.yf-archive__card-image img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s ease; }
.yf-archive__card:hover .yf-archive__card-image img { transform: scale(1.02); }
.yf-archive__card-kicker { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.14em; color: var(--wp--preset--color--accent); }
.yf-archive__card-title { font-size: 1.25rem; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.yf-archive__card-title a:hover { color: var(--wp--preset--color--accent); }
.yf-archive__card-date { font-size: 0.75rem; color: var(--wp--preset--color--ink-mute); }

/* =========================================================
 * MW3.28 — Card System 3 (front-page lead cards; replaces yf-hero5b).
 * Rendered by patterns/card-system-3.php.
 * ========================================================= */
.yf-card3 { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; padding: 96px 64px; }
@media (max-width: 900px) { .yf-card3 { grid-template-columns: 1fr; padding: 64px 24px; } }
.yf-card3__card { display: flex; flex-direction: column; gap: 16px; }
.yf-card3__card-image img { width: 100%; aspect-ratio: 16/9; object-fit: cover; transition: transform 0.4s ease; }
.yf-card3__card:hover .yf-card3__card-image img { transform: scale(1.03); }
.yf-card3__card-kicker { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.14em; color: var(--wp--preset--color--accent); }
.yf-card3__card-title { font-size: clamp(1.5rem, 3vw, 2.25rem); text-wrap: balance; line-height: 1.2; }
.yf-card3__card-excerpt { font-size: 1rem; color: var(--wp--preset--color--ink-soft); }

/* UHR-1 Step 5: Single post layout */
/* Fill the article content box (override the constrained contentSize cap) so the
   main reading column + rail use the available width with no wasted right gutter. */
.yf-single-grid {
	/* Phase 7C-R3-FS — unified single-layout token system (single knobs; revert
	   with --yf--single--main-inset:0 and --yf--single--rail-shrink:1).
	   ITEM B: main reading-column content -10% (symmetric, center axis fixed) via
	   padding-inline on .yf-single-main. ITEM C: rail track -5% with the outer/
	   docked edge anchored — justify-content:space-between pins main's inline-start
	   edge and the rail's inline-end edge, and the freed 5% flows into the gap
	   (NOT into the main track, which is computed from --rail-base, so ITEM B's
	   baseline stays decoupled from ITEM C). Range-based; logical axis → RTL safe. */
	--yf--single--rail-base: clamp(260px, 22vw, 320px);            /* pre-change rail track */
	--yf--single--rail-shrink: 0.95;                                /* ITEM C: rail = 95% */
	--yf--single--rail-width: calc(var(--yf--single--rail-base) * var(--yf--single--rail-shrink));
	--yf--single--gap: clamp(32px, 4vw, 64px);
	--yf--single--main-inset: 5%;                                  /* ITEM B: 5% each side → content 90% */
	max-width: none;
	width: 100%;
	display: grid;
	grid-template-columns:
		minmax(0, calc(100% - var(--yf--single--rail-base) - var(--yf--single--gap)))
		var(--yf--single--rail-width);
	justify-content: space-between;
	column-gap: var(--yf--single--gap);
	align-items: start;
}
/* ITEM B: symmetric inline inset → main content = 90% of its (unchanged) track,
   center axis fixed. Padding sits inside the border box → no track or overflow change. */
.yf-single-main { min-width: 0; padding-inline: var(--yf--single--main-inset); }
.yf-single-rail { min-width: 0; }
.yf-single-rail > * { min-width: 0; }
/* Tablet + mobile: single column, rail stacks BELOW content (never hidden). */
@media (max-width: 1199px) {
	.yf-single-grid { grid-template-columns: 1fr; gap: 48px; }
}
@media (max-width: 767px) {
	.yf-single-grid { gap: 32px; }
}
.yf-cta { display: inline-flex; align-items: center; gap: 8px; }
.yf-cta + .yf-cta { margin-inline-start: 16px; }
/* end UHR-1 Step 5 */

/* ============================================================
 * Phase 7C-R3-B — Unified Term Hero (Option C). Additive only.
 * Styles the yoyafun/term-hero output (.yf-hero-image) on archive /
 * taxonomy / gallery-archive surfaces, and UNIFIES the previously
 * unstyled ink fallback so it is consistently dark (never blank /
 * collapsed). RTL/LTR safe (logical properties). Responsive clamp.
 * ============================================================ */

/* The archive/taxonomy hero band (image when present, ink otherwise). */
.yf-hero-image {
	display: block;
	width: 100%;
	min-height: clamp(320px, 44vh, 520px);
	margin: 0;
	overflow: hidden;
	/* base colour so an image-less / still-loading hero never reads as blank */
	background-color: var(--wp--preset--color--ink, #1C1814);
}
.yf-hero-image img {
	display: block;
	width: 100%;
	height: 100%;
	min-height: inherit;
	object-fit: cover;
	object-position: center;
}

/* [D] Unified dark ink fallback — was unstyled (rendered light/empty). */
.yf-hero-image--ink {
	background-color: var(--wp--preset--color--ink, #1C1814);
	background-image: linear-gradient(180deg, rgba(28, 24, 20, 0) 0%, rgba(28, 24, 20, 0.35) 100%);
}

/* Taxonomy hero places kicker/title OVER the media: stack + legibility scrim. */
.yf-hero--tax {
	position: relative;
	display: grid;
	/* F3 follow-up Item A: isolation removed — it trapped the header's open
	   mobile nav overlay inside the hero's stacking context. Grid children
	   still stack by their own z-index (image 0 < scrim 1 < overlay 2 <
	   header 6); isolation is not required for sibling z-stacking. */
}
.yf-hero--tax > .yf-hero-image { grid-area: 1 / 1; z-index: 0; }
/* Hero v2 Class 6 — taxonomy native cover (gallery_region / gallery_type). The
   Hero Outlet now owns the term hero image (image-only cover); the .yf-hero__overlay
   (kicker + query-title + term-description) stays at z2 OVER it, header z6, scrims
   z1. Cover takes the same single grid cell + height clamp the term-hero figure
   used → empty entity = appearance preserved; per-term editable entity renders on
   top via the Outlet. ink bg = never blank. Image fill from HERO-V2-COVER-SELFCONTAINED. */
.yf-hero--tax > .yf-hero__outlet--cover {
	grid-area: 1 / 1;
	z-index: 0;
	margin: 0;
	min-width: 0;
}
.yf-hero--tax .yf-hero__cover.wp-block-cover {
	min-height: clamp(320px, 44vh, 520px);
	width: 100%;
	background-color: var(--wp--preset--color--ink);
}
@media ( max-width: 600px ) {
	.yf-hero--tax .yf-hero__cover.wp-block-cover {
		min-height: clamp(260px, 46vh, 420px);
	}
}
.yf-hero--tax::after {
	content: "";
	grid-area: 1 / 1;
	z-index: 1;
	background: linear-gradient(180deg, rgba(0, 0, 0, 0) 32%, rgba(0, 0, 0, 0.55) 100%);
	pointer-events: none;
}
.yf-hero--tax > .yf-hero__overlay {
	grid-area: 1 / 1;
	z-index: 2;
	align-self: end;
	padding-block-end: clamp(28px, 5vw, 56px);
	padding-inline: clamp(20px, 5vw, 64px);
	color: #fff;
}
.yf-hero--tax .yf-hero__kicker,
.yf-hero--tax .yf-hero__title,
.yf-hero--tax .yf-hero__dek { color: inherit; }

/* Mobile hero height. */
@media (max-width: 600px) {
	.yf-hero-image { min-height: clamp(260px, 46vh, 420px); }
}
/* end Phase 7C-R3-B unified term hero */

/* ============================================================
 * Phase 7C-R3-F · F3 — GLOBAL hero/header visual integration.
 * Supersedes the 7C-R3-E "solid paper bar" header (that opaque
 * background WAS the reported beige strip). The header now sits OVER
 * the hero image; the image (or a dark ink fallback when none) extends
 * behind it; a top+bottom legibility scrim keeps header + title
 * readable; relocated post-titles render inside the hero. Header
 * controls flip to on-image colors and remain clickable purely via
 * stacking (z-order), with the scrim/title non-interactive so no
 * overlay intercepts clicks. Mirrors the proven .yf-hero5b__image
 * header-over-image pattern. Fluid/range-based (clamp + logical props);
 * the menu system / nav block / Mechanism A are untouched.
 *
 * Families covered:
 *   --page / --home / --hub : core post-featured-image (.yf-hero__media) + overlay title
 *   --tax / --archive       : yoyafun/term-hero; header relocated INTO the hero (F3 template move)
 *   --search / --404        : ink fallback band (no image)
 * ============================================================ */

/* 1) Image families: positioning context + no collapse + dark ink fallback.
 *    Flex column lets the overlay title pin to the band's bottom edge. */
.yf-hero--page,
.yf-hero--home,
.yf-hero--hub,
.yf-hero--search,
.yf-hero--404 {
	position: relative;
	display: flex;
	flex-direction: column;
	background-color: var(--wp--preset--color--ink, #1C1814);
	/* F3 follow-up Item A: NO `isolation:isolate` / `overflow:hidden` on the
	   section. Both trapped the header's open mobile nav overlay: isolation
	   made the hero a stacking context with z-index:auto, so the overlay's
	   z-index:100000 was confined to the hero and later DOM siblings (body,
	   footer) painted over it; overflow:hidden additionally clipped it. The
	   image is clipped on the MEDIA layer instead (see below). The hero is a
	   positioning context (position:relative, no z-index → not a stacking
	   context), so position:fixed overlays escape to the viewport. */
}

/* BATCH C: section min-height retained for hub only (no template, not
   variant-driven). home/page own min-height via .is-style-hero-standard;
   search/404 sections own it via .is-style-hero-banner (clamp, no mobile
   reduction). All 0px drift. */
.yf-hero--hub {
	min-height: clamp(320px, 44vh, 520px);
}

/* 2) Featured image (or ink fallback band) fills behind everything. */
.yf-hero--page > .yf-hero__media,
.yf-hero--home > .yf-hero__media,
.yf-hero--hub > .yf-hero__media,
.yf-hero--search > .yf-hero__media,
.yf-hero--404 > .yf-hero__media {
	position: absolute;
	inset: 0;
	z-index: 0;
	margin: 0;
	min-height: 0;
	overflow: hidden; /* F3 follow-up Item A: clip the image HERE, not on the section */
}
.yf-hero--page > .yf-hero__media img,
.yf-hero--home > .yf-hero__media img,
.yf-hero--hub > .yf-hero__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	display: block;
}

/* HERO SEARCH/INDEX/404 cover-mode — the Outlet cover REPLACES the
   .yf-hero__media band in-place (same absolute inset:0 / z-index:0), so the
   is-style-hero-banner section keeps driving the height (clamp(320,44vh,520),
   no mobile reduction) → rendered hero is PIXEL-IDENTICAL to the band at EVERY
   width incl mobile (no 414px clamp drift). Header + ::after scrim overlay it
   exactly as they did the band. Cover image fill = HERO-V2-COVER-SELFCONTAINED.
   Scoped to these 3 surfaces only; no other surface touched. */
.yf-hero--search > .yf-hero__outlet--cover,
.yf-hero--404 > .yf-hero__outlet--cover,
.yf-hero--index > .yf-hero__outlet--cover {
	position: absolute;
	inset: 0;
	z-index: 0;
	margin: 0;
	min-height: 0;
	overflow: hidden;
}
.yf-hero--search .yf-hero__cover.wp-block-cover,
.yf-hero--404 .yf-hero__cover.wp-block-cover,
.yf-hero--index .yf-hero__cover.wp-block-cover {
	min-height: 0;
	height: 100%;
	width: 100%;
}

/* 3) Legibility scrim — dark at the top (under the header) and bottom
 *    (under the title), transparent in the middle. Non-interactive. */
.yf-hero--page::after,
.yf-hero--home::after,
.yf-hero--hub::after,
.yf-hero--search::after,
.yf-hero--404::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background:
		linear-gradient(180deg, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0) 30%),
		linear-gradient(0deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0) 45%);
	pointer-events: none;
}

/* 4) Header transparent + above the scrim + clickable (ALL hero families).
 *    DESCENDANT selector: the .yf-header div lives inside the template-part
 *    wrapper <header class="wp-block-template-part">, so a child combinator
 *    (`>`) would miss it. */
.yf-hero--page .yf-header,
.yf-hero--home .yf-header,
.yf-hero--hub .yf-header,
.yf-hero--tax .yf-header,
.yf-hero--archive .yf-header,
.yf-hero--search .yf-header,
.yf-hero--404 .yf-header {
	position: relative;
	z-index: 6;
	pointer-events: auto;
	background: transparent;
	border-bottom: 0;
}

/* 5) Relocated overlay title: pinned to the band bottom, over the scrim. */
.yf-hero--page .yf-hero__overlay,
.yf-hero--home .yf-hero__overlay,
.yf-hero--hub .yf-hero__overlay {
	position: relative;
	z-index: 4;
	margin-block-start: auto;
	padding-block-end: clamp(24px, 4vw, 48px);
	padding-inline: clamp(20px, 5vw, 64px);
}
.yf-hero--page .yf-hero__title,
.yf-hero--home .yf-hero__title,
.yf-hero--hub .yf-hub__title,
.yf-hero--hub .yf-hero__title {
	margin: 0;
	font-family: var(--wp--preset--font-family--display);
	font-size: clamp(2rem, 4.5vw + 1rem, 4.75rem);
	line-height: 1.02;
	letter-spacing: -0.02em;
	text-wrap: balance;
	color: var(--wp--preset--color--on-image, #FFFFFF);
	pointer-events: none; /* non-interactive display title never intercepts header clicks */
}

/* 6) Taxonomy + archive (term-hero families): single-cell grid so the
 *    relocated header overlays the term-hero image. The header is the
 *    template-part wrapper <header> (the direct grid child); the .yf-header
 *    div inside it gets transparency/colors from rules 4 + 7. A top scrim
 *    (::before — tax's ::after is the bottom title scrim) keeps the header
 *    legible. --tax already has display:grid + .yf-hero-image placement +
 *    bottom scrim from the term-hero rules above; --archive adds them here. */
.yf-hero--archive {
	position: relative;
	display: grid;
	/* F3 follow-up Item A: isolation removed (same overlay-trap reason as --tax). */
}
.yf-hero--tax > header,
.yf-hero--archive > header {
	grid-area: 1 / 1;
	align-self: start;
	z-index: 6;
	position: relative;
}
.yf-hero--archive > .yf-hero-image {
	grid-area: 1 / 1;
	z-index: 0;
}
/* Hero v2 Class 5 — archive native cover. The Hero Outlet now owns the
   archive hero image (image-only cover; the archive title/kicker/description
   stay in .yf-archive__header below). The cover wrapper takes the same single
   grid cell the term-hero figure used, so the header still overlays it and the
   ::before top scrim + transparent header rules below are unchanged. Cover
   layout (image absolute + object-fit) comes from HERO-V2-COVER-SELFCONTAINED.
   Height clamp + mobile clamp mirror the old .yf-hero-image band exactly →
   empty entity = appearance preserved. ink bg = never blank if no image. */
.yf-hero--archive > .yf-hero__outlet--cover {
	grid-area: 1 / 1;
	z-index: 0;
	margin: 0;
	min-width: 0;
}
.yf-hero--archive .yf-hero__cover.wp-block-cover {
	min-height: clamp(320px, 44vh, 520px);
	width: 100%;
	background-color: var(--wp--preset--color--ink);
}
@media ( max-width: 600px ) {
	.yf-hero--archive .yf-hero__cover.wp-block-cover {
		min-height: clamp(260px, 46vh, 420px);
	}
}
.yf-hero--tax::before,
.yf-hero--archive::before {
	content: "";
	grid-area: 1 / 1;
	z-index: 1;
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.45) 0%, rgba(0, 0, 0, 0) 30%);
	pointer-events: none;
}

/* 7) Header controls → on-image colors across ALL hero-over-image families
 *    (page/home/hub/tax/archive). Mirrors the proven .yf-hero5b__image rules;
 *    grouped with :is() to avoid duplicating each selector. The desktop
 *    dropdown card + the open mobile overlay flip BACK to ink so they stay
 *    legible on their light surfaces (specificity-win, no !important). */
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__logo-yoya {
	color: var(--wp--preset--color--on-image);
}
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__logo-fun {
	color: var(--wp--preset--color--accent-soft);
}
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__nav .wp-block-navigation-item__content,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__search a,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__lang a,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__nav .wp-block-navigation__submenu-icon {
	color: var(--wp--preset--color--on-image);
}
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__nav .wp-block-navigation-item__content:hover,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__nav .wp-block-navigation-item__content:focus-visible,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__search a:hover {
	color: var(--wp--preset--color--accent-soft);
}
/* Subscribe outline button over the image: paper outline/text. */
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__subscribe .wp-block-button__link {
	color: var(--wp--preset--color--on-image);
	border-color: var(--wp--preset--color--on-image);
}
/* Open mobile overlay (near-white surface) → ink items/glyphs. */
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon {
	color: var(--wp--preset--color--ink);
}
/* Desktop dropdown submenu (paper card) → ink items. */
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
	color: var(--wp--preset--color--ink);
}

/* ============================================================
 * HMTB Item 1 — Single-post glass control surface, generalised.
 * The single-post header (nested in `.yf-hero5b__image`) is the
 * visual SOURCE OF TRUTH: Subscribe / Search / Language switcher
 * all render as the same glass pill (bg rgba(255,255,255,.12),
 * blur(10px), border rgba(255,255,255,.25), on-image text) via the
 * rules at ~3569–3633. The `:is()` block above only set on-image
 * COLOURS for the other hero families (and mistargeted the language
 * `<select>` through `__lang a`), so those controls were flat — and
 * Subscribe even kept the base ink outline (its 0,4,0 rule beat the
 * 0,3,0 colour rule). These rules replicate single's COMPUTED style
 * control-by-control, property-for-property, so every non-single
 * surface MATCHES single. Values copied verbatim from 3569–3633.
 * Subscribe uses the 0,5,0 compound (matching single) to beat the
 * base outline rule. Flip-to-ink rules for the OPEN dropdown / OPEN
 * mobile overlay are untouched (they win on their own selectors).
 * ============================================================ */

/* Language switcher <select> — glass pill (mirror 3571–3591). */
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__lang select {
	background-color: rgba(255, 255, 255, 0.12);
	border-color: rgba(255, 255, 255, 0.25);
	color: var(--wp--preset--color--on-image);
	-webkit-backdrop-filter: blur(10px);
	        backdrop-filter: blur(10px);
}
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__lang select:hover,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__lang select:focus-visible {
	background-color: rgba(255, 255, 255, 0.22);
	border-color: rgba(255, 255, 255, 0.4);
	color: var(--wp--preset--color--on-image);
}
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__lang select option {
	color: var(--wp--preset--color--ink);
	background-color: var(--wp--preset--color--paper);
}

/* Search button — glass circle (mirror 3596–3607). */
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__search a {
	background: rgba(255, 255, 255, 0.12);
	border: 1px solid rgba(255, 255, 255, 0.25);
	-webkit-backdrop-filter: blur(10px);
	        backdrop-filter: blur(10px);
	color: var(--wp--preset--color--on-image);
}
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__search a:hover {
	background: rgba(255, 255, 255, 0.22);
	border-color: rgba(255, 255, 255, 0.4);
	color: var(--wp--preset--color--on-image);
}

/* Subscribe — glass pill (mirror 3620–3633; 0,5,0 beats base outline). */
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__subscribe.wp-block-button.is-style-outline > .wp-block-button__link,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__subscribe .wp-block-button__link {
	background: rgba(255, 255, 255, 0.12);
	color: var(--wp--preset--color--on-image);
	border-color: rgba(255, 255, 255, 0.25);
	-webkit-backdrop-filter: blur(10px);
	        backdrop-filter: blur(10px);
}
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__subscribe.wp-block-button.is-style-outline > .wp-block-button__link:hover,
:is(.yf-hero--page, .yf-hero--home, .yf-hero--hub, .yf-hero--tax, .yf-hero--archive, .yf-hero--search, .yf-hero--404, .yf-gallery-single__hero, .yf-hero--index) .yf-header__subscribe .wp-block-button__link:hover {
	background: rgba(255, 255, 255, 0.22);
	border-color: rgba(255, 255, 255, 0.4);
	color: var(--wp--preset--color--on-image);
}

/* 8) Mobile hero band height (fluid). home/page now carry their mobile
   min-height via .is-style-hero-standard (@media in the BATCH C block); hub
   retained here (no template / not variant-driven). 0px drift. */
@media (max-width: 600px) {
	.yf-hero--hub {
		min-height: clamp(260px, 46vh, 420px);
	}
}
/* end Phase 7C-R3-F F3 global hero/header integration */

/* ============================================================
 * U1-A Utility Layer — INERT FOUNDATION (closed registry v1)
 * - This layer is INERT in U1-A: applied to NO element anywhere.
 * - It must not change appearance of any surface.
 * - NOT to be used inside header/navigation without a separate approved batch:
 *   .yf-u-inline-* are FORBIDDEN inside .yf-header__nav / core navigation
 *   containers without a dedicated batch + proof.
 * - .yf-u-stack-* are FORBIDDEN on blocks managed by blockGap without proof.
 * - Reserved semantic names (NO css, governance only):
 *   yf-u-priority-primary / -secondary / -trust / -social  (semantic-only in U1-A)
 * - ANY future application requires a separate approved batch + proof matrix.
 * - Closed list: adding any new yf-u-* class requires a user-approved dispatch.
 * ============================================================ */
.yf-u-inline-start  { justify-content: flex-start; margin-inline-end: auto; }
.yf-u-inline-end    { justify-content: flex-end;   margin-inline-start: auto; }
.yf-u-inline-center { justify-content: center;     margin-inline: auto; }
.yf-u-stack-xs > * + * { margin-block-start: var(--wp--preset--spacing--xs); }
.yf-u-stack-sm > * + * { margin-block-start: var(--wp--preset--spacing--sm); }
.yf-u-stack-md > * + * { margin-block-start: var(--wp--preset--spacing--md); }
.yf-u-stack-lg > * + * { margin-block-start: var(--wp--preset--spacing--lg); }

/* ============================================================
 * BATCH B · U1-C — `yf-section` section-utility registry (CSS-knots layer)
 * ------------------------------------------------------------
 * Editor-first: the PRIMARY control for sections is Gutenberg native
 * (Group block bg from the palette, padding by named spacing presets,
 * blockGap, alignwide/full) + the five Group "section style" variations
 * (Band/Card/Feature/Split/Muted, registered in /styles). This registry
 * is the FOURTH rung — axes the variations don't carry — applied via
 * Advanced → Additional CSS class(es). All values are token-driven; all
 * properties are LOGICAL (RTL-safe by construction); mobile rules live
 * inside each utility. INERT until a class is added (zero visual change).
 *
 * Closed registry — adding a new yf-* axis requires an approved dispatch.
 * Documented code-only values: founding widths 560 / 680 / 1200 (locked
 * identity, per editor-control-map §8) — everything else is a token.
 *
 * Axes:
 *  density : .yf-section (default xl) · --compact (md) · --spacious (2xl)
 *  width   : --narrow (560) · default (content 680) · --wide (1200) · --full
 *  tone    : --light · --dark (on-image text + link contrast) · --tinted
 *  chrome  : --with-border (hairline rule) · --with-shadow (shadow-card)
 *  layout  : default stack · --split (50/50 → 1col) · --grid (auto-fit → 1col)
 *  regions : __intro (kicker+title+lede) · __cta (CTA row, start-aligned)
 * ============================================================ */
.yf-section { padding-block: var(--wp--preset--spacing--xl); }
.yf-section--compact  { padding-block: var(--wp--preset--spacing--md); }
.yf-section--spacious { padding-block: var(--wp--preset--spacing--2xl); }

.yf-section--narrow { max-inline-size: 560px;  margin-inline: auto; }
.yf-section--wide   { max-inline-size: 1200px; margin-inline: auto; }
.yf-section--full   { max-inline-size: none; }

.yf-section--light  { background-color: var(--wp--preset--color--paper-soft); }
.yf-section--tinted { background-color: var(--wp--preset--color--paper-deep); }
.yf-section--dark   { background-color: var(--wp--preset--color--ink); color: var(--wp--preset--color--on-image); }
.yf-section--dark a { color: var(--wp--preset--color--on-image); }
.yf-section--dark a:hover { color: var(--wp--preset--color--accent-soft); }

.yf-section--with-border { border: var(--wp--custom--yf--hairline) solid var(--wp--preset--color--rule); }
.yf-section--with-shadow { box-shadow: var(--wp--custom--yf--shadow--card); }

.yf-section--split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--wp--preset--spacing--lg); align-items: start; }
.yf-section--grid  { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--wp--preset--spacing--lg); }

.yf-section__intro { display: flex; flex-direction: column; gap: var(--wp--preset--spacing--xs); }
.yf-section__cta   { display: flex; flex-wrap: wrap; gap: var(--wp--preset--spacing--sm); justify-content: flex-start; align-items: center; }

@media (max-width: 781px) {
	.yf-section          { padding-block: var(--wp--preset--spacing--lg); padding-inline: var(--wp--custom--yf--gutter-mobile); }
	.yf-section--compact  { padding-block: var(--wp--preset--spacing--sm); }
	.yf-section--spacious { padding-block: var(--wp--preset--spacing--xl); }
	.yf-section--split,
	.yf-section--grid    { grid-template-columns: 1fr; }
}
/* end BATCH B U1-C section utilities */

/* ============================================================
 * BATCH C · Hero height variants (editor-selectable, token-driven)
 * ------------------------------------------------------------
 * Block style variations registered on core/group (/styles/hero-*.json)
 * surface these in the Styles panel. The EFFECTIVE rules live here at
 * class specificity (0-1-0) so they (a) carry the measured responsive
 * @media behavior a /styles partial can't, and (b) cleanly own min-height
 * once a surface's prior height source is removed (C4). Values are 100%
 * token-driven (custom.yf.hero.h.*), measured == C-0 (0px drift). INERT
 * until a surface adds the class. min-height only — no z-index/overlay/
 * position touched. Inline minHeight (if any) still wins (back-compat).
 * ============================================================ */
.is-style-hero-compact   { min-height: var(--wp--custom--yf--hero--h--compact); }
.is-style-hero-standard  { min-height: var(--wp--custom--yf--hero--h--standard); }
.is-style-hero-tall      { min-height: var(--wp--custom--yf--hero--h--tall); }
.is-style-hero-immersive { min-height: var(--wp--custom--yf--hero--h--immersive); }
/* banner = clamp at ALL widths (no mobile reduction) — matches search/404 sections (0px). */
.is-style-hero-banner    { min-height: var(--wp--custom--yf--hero--h--banner); }
@media (max-width: 600px) {
	.is-style-hero-compact   { min-height: var(--wp--custom--yf--hero--h--compact-m); }
	.is-style-hero-standard  { min-height: var(--wp--custom--yf--hero--h--standard-m); }
	.is-style-hero-tall      { min-height: var(--wp--custom--yf--hero--h--tall-m); }
	.is-style-hero-immersive { min-height: var(--wp--custom--yf--hero--h--immersive-m); }
}
/* end BATCH C hero height variants */

/* ============================================================
   TH-02-B — single-post byline legibility fix.
   The byline (avatar · author · date · reading-time · fact-checked)
   was authored for on-image placement (name = on-image #FFFFFF;
   meta row/date = paper-toned rgba(244,238,227,.7)), but it renders
   BELOW the hero on the paper background (#F4EEE3) — so the name is
   white-on-cream and the meta row is paper-on-paper (both illegible).
   Override the paper-placed byline text to the theme ink preset.
   Scope: .yf-single__byline only appears in templates/single.html.
   ============================================================ */
.yf-single__byline-name {
	color: var(--wp--preset--color--ink);
}
.yf-single__byline-meta-row,
.yf-single__byline-meta-row .wp-block-post-date,
.yf-single__byline-meta-row .yf-single__byline-date,
.yf-single__byline-meta-row .yf-meta-badge {
	color: var(--wp--preset--color--ink);
}

/* ============================================================
   ADSENSE BATCH E3 — reserved-size ad slots, inert by default.
   Every E3 ad container carries `yf-ad-e3 yf-ad--{size}`. It is
   display:none until it actually holds an <ins class="adsbygoogle">
   (i.e. a live, enabled, non-killed slot), so the shipped default
   state (kill ON / no IDs) shows ZERO ad boxes — visually identical
   to pre-E3. When live, the reserved min-height holds layout (CLS≈0).
   ============================================================ */
.yf-ad-e3 { display: none; }
.yf-ad-e3:has( .adsbygoogle ) {
	display: block;
	margin: 40px auto;
	padding: 8px 0;
	text-align: center;
	max-width: 100%;
}
.yf-ad-e3 .yf-ad__label {
	display: block;
	margin: 0 0 10px;
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	font-weight: 600;
	letter-spacing: 0.24em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-ad-e3 .adsbygoogle { display: block; width: 100%; }
.yf-ad-e3.yf-ad--leader   { min-height: 90px; }
.yf-ad-e3.yf-ad--rect     { min-height: 250px; }
.yf-ad-e3.yf-ad--halfpage { min-height: 600px; }
@media ( max-width: 781px ) {
	.yf-ad-e3.yf-ad--leader   { min-height: 100px; }
	.yf-ad-e3.yf-ad--halfpage { min-height: 250px; }
}
/* C-3 Option A — sidebar sponsored modules stay hidden until a live ad. */
.yf-rail4__module--sponsored:not( :has( .adsbygoogle ) ) { display: none; }
.yf-ad-slot--sidebar-mid:has( .adsbygoogle ) { min-height: 250px; }
.yf-ad-slot--sidebar-low:has( .adsbygoogle ) { min-height: 600px; }

/* ============================================================
   AD-SLOT OVERFLOW CONTAINMENT (responsive, contained). Ad CSS only.
   ROOT CAUSE (Cowork, REAL filled ads, system Edge, 5 posts EN+AR+FR,
   both directions): the FILLED AdSense IFRAME (src=googleads.g.double
   click.net) injected inside <ins.adsbygoogle.yf-ad__slot> renders at
   FULL VIEWPORT width and sticks out ~24px on every single post — LTR
   right, RTL left (leftOvf=-24) — constant +24 at 360–450, clean at 600;
   identical on all posts → systemic + bidi. The hero cover is INNOCENT.
   Prior `max-width:100%` on the <ins> did NOT constrain the iframe: the
   INJECTED iframe carries its own viewport-sized inline width, so the
   slot must force the iframe (and ins children) to the CONTAINER width.
   `width:100%` overrides the iframe's viewport width; `max-width:100%`
   is direction-agnostic so it fixes LTR right-overflow AND RTL left-
   overflow with NO physical margins. inc/adsense.php untouched
   (forbidden); no hero/cover/header rules here — style.css only.
   ============================================================ */
.yf-ad-e3,
.yf-ad-slot,
.yf-ad__slot,
ins.adsbygoogle {
	max-width: 100% !important;
	box-sizing: border-box !important;
	overflow: clip;
}
ins.adsbygoogle,
ins.adsbygoogle > *,
.yf-ad-e3 iframe,
.yf-ad-slot iframe,
.yf-ad__slot iframe {
	max-width: 100% !important;
	width: 100% !important;
}
/* Overflow-safe ad containers (horizontal only — never clip ad height). */
.yf-ad,
.yf-single__inline-ad,
.yf-ad-grid-cell {
	max-width: 100%;
	box-sizing: border-box;
	overflow-x: clip;
}

/* ============================================================
   Unified Surface Hero — Hero Outlet + Design-System motion.
   Additive only. The Outlet (yoyafun/hero-outlet) renders the
   per-language hero EXTRAS inside the existing hero shell, after
   the dynamic core fields; it inherits the overlay's colour/type.
   Motion presets are reduced-motion safe. NO header/nav rules here.
   ============================================================ */
.yf-hero__outlet { margin-block-start: clamp(12px, 2vw, 20px); }
.yf-hero__outlet > :first-child { margin-block-start: 0; }
.yf-hero__outlet .wp-block-buttons { margin-block-start: 0; }

/* prefers-reduced-motion: neutralise the transform/transition from the
   additive /styles `card-lift` block-style variation. */
@media ( prefers-reduced-motion: reduce ) {
	.is-style-card-lift { transition: none !important; }
	.is-style-card-lift:hover { transform: none !important; }
}

/* ============================================================
   Unified Surface Hero — image hero on search / 404 / index.
   The static ink media on search/404 was swapped for the dynamic
   yoyafun/hero-image (class yf-hero__media) → default hero image
   (never ink). These rules give that figure's <img> object-fit
   cover (the prior cover rule only covered page/home/hub), and give
   index.html the same header-over-image banner treatment as
   search/404. Additive; no header/nav markup touched.
   ============================================================ */
.yf-hero--search > .yf-hero__media img,
.yf-hero--404 > .yf-hero__media img,
.yf-hero--index > .yf-hero__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* index banner shell (mirrors the search/404 family). */
.yf-hero--index {
	position: relative;
	display: flex;
	flex-direction: column;
	isolation: isolate;
}
.yf-hero--index > .yf-hero__media {
	position: absolute;
	inset: 0;
	z-index: 0;
	overflow: hidden;
}
.yf-hero--index::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: linear-gradient(180deg, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0) 42%, rgba(0, 0, 0, 0.22) 100%);
	pointer-events: none;
}
.yf-hero--index .yf-header {
	position: relative;
	z-index: 6;
	background: transparent;
	border-bottom: 0;
}
.yf-hero--index .yf-header__logo-yoya { color: var(--wp--preset--color--on-image); }
.yf-hero--index .yf-header__logo-fun { color: var(--wp--preset--color--accent-soft); }
.yf-hero--index .yf-header__nav .wp-block-navigation-item__content,
.yf-hero--index .yf-header__search a,
.yf-hero--index .yf-header__lang a,
.yf-hero--index .yf-header__nav .wp-block-navigation__submenu-icon { color: var(--wp--preset--color--on-image); }
.yf-hero--index .yf-header__subscribe .wp-block-button__link {
	color: var(--wp--preset--color--on-image);
	border-color: var(--wp--preset--color--on-image);
}
.yf-hero--index .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content,
.yf-hero--index .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon { color: var(--wp--preset--color--ink); }
.yf-hero--index .yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content { color: var(--wp--preset--color--ink); }

/* ============================================================
   Unified Surface Hero v2 — NATIVE COVER hero (pilot: galleries).
   The Outlet renders a core/cover (authored entity or server
   fallback). The section grid-stacks the nested header OVER the
   cover (header-over-hero preserved) while the cover drives the
   height — so the native min-height drag/numeric control grows the
   hero live. Scoped to .yf-hero--galleries so the 85 hub pages
   (which share .yf-hero--hub) keep their existing band rendering.
   ============================================================ */

/* ── HERO-V2-COVER-SELFCONTAINED ─────────────────────────────
   The hero core/cover is rendered via the Hero Outlet's do_blocks().
   WP's separate-core-block-assets loading enqueues the core
   `wp-block-cover` stylesheet INCONSISTENTLY for outlet-rendered
   covers (PROVEN: greece single missing it → wp-block-cover was
   box-sizing:content-box / position:static and the image-background
   stayed position:static → laid out at its natural 853px height
   instead of object-fit:cover at the 520px clamp, growing the grid
   cell to 862px; athens + iceland singles, identical markup, loaded
   it and rendered correctly at 520px). Own the cover's critical
   layout here so EVERY hero cover (galleries / single-gallery / hub /
   page / single) is correct regardless of core block-CSS timing.
   Mirrors core wp-block-cover; does NOT set min-height (each surface
   keeps its own clamp) so it cannot change any hero height. */
.yf-hero__cover.wp-block-cover {
	position: relative;
	box-sizing: border-box;
	/* HERO-COVER-FILL-GAP — the cover sits inside .yf-hero__outlet--cover,
	   which is the grid-stretched cell of the hero section. When authored
	   hero content grows the section taller than the cover's own clamp, the
	   outlet stretches to the section height but the cover kept only its
	   content height (clamp) — leaving a transparent strip below the cover
	   that exposed the section's ink background (measured: 703 section vs
	   683 cover = 20px dark strip on home). height:100% makes the cover fill
	   its stretched outlet so cover_bottom == section_bottom (gap 0). With
	   NO extra content the outlet equals the clamp, so 100% resolves to the
	   same clamp height → no-content appearance stays pixel-identical. The
	   image (absolute inset:0) already fills the cover, so it follows. */
	height: 100%;
}
.yf-hero__cover > img.wp-block-cover__image-background,
.yf-hero__cover > video.wp-block-cover__video-background {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
	border: none;
	object-fit: cover;
	object-position: center;
}

.yf-hero--galleries {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-rows: auto;
	align-items: stretch;
	/* the cover provides the visual height; clear the flex band model */
	min-height: 0;
}
.yf-hero--galleries > header,
.yf-hero--galleries > .yf-header {
	grid-row: 1;
	grid-column: 1;
	z-index: 6;
	align-self: start;
}
.yf-hero--galleries > .yf-hero__outlet--cover {
	grid-row: 1;
	grid-column: 1;
	z-index: 0;
	margin: 0;
	min-width: 0;
}
/* Cover fills the cell; seed (no inline min-height) uses the responsive
   clamp; the editor's min-height drag/numeric sets an inline px that
   overrides this and grows the grid row live. */
.yf-hero--galleries .yf-hero__cover.wp-block-cover {
	min-height: clamp(320px, 44vh, 520px);
	width: 100%;
}
@media ( max-width: 600px ) {
	.yf-hero--galleries .yf-hero__cover.wp-block-cover {
		min-height: clamp(260px, 46vh, 420px);
	}
}
/* Title in the cover keeps the hub hero type scale. */
.yf-hero--galleries .yf-hero__cover .yf-hub__title {
	color: var(--wp--preset--color--on-image);
}

/* ============================================================
   Unified Surface Hero v2 — NATIVE COVER (single-gallery).
   Same grid-stack model as galleries, scoped to the bespoke
   .yf-gallery-single__hero shell. Header-over-hero preserved;
   the cover drives height (native drag/numeric). The existing
   serial/kicker/title classNames keep their styling + the
   dynamic G6/G7 render filters still fire inside the cover.
   ============================================================ */
.yf-gallery-single__hero {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-rows: auto;
	align-items: stretch;
}
.yf-gallery-single__hero > header,
.yf-gallery-single__hero > .yf-header {
	grid-row: 1;
	grid-column: 1;
	z-index: 6;
	align-self: start;
}
.yf-gallery-single__hero > .yf-hero__outlet--cover {
	grid-row: 1;
	grid-column: 1;
	z-index: 0;
	margin: 0;
	min-width: 0;
}
.yf-gallery-single__hero .yf-hero__cover.wp-block-cover {
	min-height: clamp(420px, 62vh, 720px);
	width: 100%;
}
.yf-gallery-single__hero .yf-hero__cover .wp-block-cover__inner-container {
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
	padding: 36px 64px 56px;
	display: flex;
	flex-direction: column;
	gap: 20px;
}
/* header-on-image colours (this shell is not in the shared :is() list) */
.yf-gallery-single__hero .yf-header__logo-yoya { color: var(--wp--preset--color--on-image); }
.yf-gallery-single__hero .yf-header__logo-fun { color: var(--wp--preset--color--accent-soft); }
.yf-gallery-single__hero .yf-header__nav .wp-block-navigation-item__content,
.yf-gallery-single__hero .yf-header__search a,
.yf-gallery-single__hero .yf-header__lang a,
.yf-gallery-single__hero .yf-header__nav .wp-block-navigation__submenu-icon { color: var(--wp--preset--color--on-image); }
.yf-gallery-single__hero .yf-header__subscribe .wp-block-button__link {
	color: var(--wp--preset--color--on-image);
	border-color: var(--wp--preset--color--on-image);
}
.yf-gallery-single__hero .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content,
.yf-gallery-single__hero .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon { color: var(--wp--preset--color--ink); }
.yf-gallery-single__hero .yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content { color: var(--wp--preset--color--ink); }
/* CRITICAL: transparent header so the cover image shows THROUGH it (header-over-hero).
   Without this the header's default opaque paper background renders as a solid bar
   over the image's top strip (Cowork CLASS-1 fail). Mirrors .yf-hero--hub .yf-header. */
.yf-gallery-single__hero > header,
.yf-gallery-single__hero > header.wp-block-template-part,
.yf-gallery-single__hero .yf-header {
	background: transparent;
	border-bottom: 0;
}
/* Top scrim for header legibility over bright image areas (z between cover and header). */
.yf-gallery-single__hero::before {
	content: "";
	grid-row: 1;
	grid-column: 1;
	align-self: start;
	z-index: 1;
	width: 100%;
	height: 170px;
	background: linear-gradient(180deg, rgba(20, 16, 12, 0.5) 0%, rgba(20, 16, 12, 0) 100%);
	pointer-events: none;
}
@media ( max-width: 600px ) {
	.yf-gallery-single__hero .yf-hero__cover.wp-block-cover { min-height: clamp(320px, 52vh, 480px); }
	.yf-gallery-single__hero .yf-hero__cover .wp-block-cover__inner-container { padding: 28px 20px 36px; }
}

/* ============================================================
   Unified Surface Hero v2 — NATIVE COVER (hubs). Scoped to
   .yf-hero--hub:not(.yf-hero--galleries) so the verified galleries
   pilot (which also carries .yf-hero--hub) is NOT disturbed.
   Grid-stacks the nested header OVER the cover; cover drives height
   (native drag/numeric). Header is transparent (explicit + the
   existing .yf-hero--hub .yf-header rule) so the image shows through.
   ============================================================ */
.yf-hero--hub:not(.yf-hero--galleries) {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-rows: auto;
	align-items: stretch;
}
.yf-hero--hub:not(.yf-hero--galleries) > header,
.yf-hero--hub:not(.yf-hero--galleries) > .yf-header {
	grid-row: 1;
	grid-column: 1;
	z-index: 6;
	align-self: start;
	background: transparent;
	border-bottom: 0;
}
.yf-hero--hub:not(.yf-hero--galleries) > .yf-hero__outlet--cover {
	grid-row: 1;
	grid-column: 1;
	z-index: 0;
	margin: 0;
	min-width: 0;
}
.yf-hero--hub:not(.yf-hero--galleries) .yf-hero__cover.wp-block-cover {
	min-height: clamp(320px, 44vh, 520px);
	width: 100%;
}
.yf-hero--hub:not(.yf-hero--galleries) .yf-hero__cover .wp-block-cover__inner-container {
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
	padding-block-end: clamp(24px, 4vw, 48px);
}
.yf-hero--hub:not(.yf-hero--galleries) .yf-hero__cover .yf-hub__title,
.yf-hero--hub:not(.yf-hero--galleries) .yf-hero__cover .yf-hub__intro {
	color: var(--wp--preset--color--on-image);
}
@media ( max-width: 600px ) {
	.yf-hero--hub:not(.yf-hero--galleries) .yf-hero__cover.wp-block-cover { min-height: clamp(260px, 46vh, 420px); }
}

/* ============================================================
   Unified Surface Hero v2 — NATIVE COVER (plain pages).
   .yf-hero--page is exclusive to page.html (no shared-class clash).
   Grid-stack header over cover; transparent header; cover height =
   the standard hero variant (matches the page's original height).
   ============================================================ */
.yf-hero--page {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-rows: auto;
	align-items: stretch;
}
.yf-hero--page > header,
.yf-hero--page > .yf-header {
	grid-row: 1;
	grid-column: 1;
	z-index: 6;
	align-self: start;
	background: transparent;
	border-bottom: 0;
}
.yf-hero--page > .yf-hero__outlet--cover {
	grid-row: 1;
	grid-column: 1;
	z-index: 0;
	margin: 0;
	min-width: 0;
}
.yf-hero--page .yf-hero__cover.wp-block-cover {
	min-height: var(--wp--custom--yf--hero--h--standard, clamp(320px, 44vh, 520px));
	width: 100%;
}
.yf-hero--page .yf-hero__cover .wp-block-cover__inner-container {
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
	padding-block-end: clamp(24px, 4vw, 48px);
}
.yf-hero--page .yf-hero__cover .yf-hero__title,
.yf-hero--page .yf-hero__cover .yf-hub__intro {
	color: var(--wp--preset--color--on-image);
}
@media ( max-width: 600px ) {
	.yf-hero--page .yf-hero__cover.wp-block-cover { min-height: var(--wp--custom--yf--hero--h--standard-m, clamp(260px, 46vh, 420px)); }
}

/* ============================================================
   Unified Surface Hero v2 — NATIVE COVER (home / front-page).
   .yf-hero--home is exclusive to front-page.html. Mirrors --page:
   grid-stack the nested header OVER the cover; transparent header;
   cover height = the standard hero variant (the home kept
   is-style-hero-standard, so the same height var as before). IMAGE-ONLY
   (the home hero had an empty overlay / no title) → empty entity =
   appearance preserved; per-language editable entity (post,front_page)
   renders on top via the Outlet. Overrides the shared page/home/hub flex
   rule. Image fill from HERO-V2-COVER-SELFCONTAINED. ink bg = never blank. */
.yf-hero--home {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-rows: auto;
	align-items: stretch;
}
.yf-hero--home > header,
.yf-hero--home > .yf-header {
	grid-row: 1;
	grid-column: 1;
	z-index: 6;
	align-self: start;
	background: transparent;
	border-bottom: 0;
}
.yf-hero--home > .yf-hero__outlet--cover {
	grid-row: 1;
	grid-column: 1;
	z-index: 0;
	margin: 0;
	min-width: 0;
}
.yf-hero--home .yf-hero__cover.wp-block-cover {
	min-height: var(--wp--custom--yf--hero--h--standard, clamp(320px, 44vh, 520px));
	width: 100%;
	background-color: var(--wp--preset--color--ink);
}
.yf-hero--home .yf-hero__cover .wp-block-cover__inner-container {
	width: 100%;
	max-width: var(--wp--style--global--wide-size, 1200px);
	margin-inline: auto;
	padding-block-end: clamp(24px, 4vw, 48px);
}
.yf-hero--home .yf-hero__cover .yf-hero__title,
.yf-hero--home .yf-hero__cover .yf-hub__intro {
	color: var(--wp--preset--color--on-image);
}
@media ( max-width: 600px ) {
	.yf-hero--home .yf-hero__cover.wp-block-cover { min-height: var(--wp--custom--yf--hero--h--standard-m, clamp(260px, 46vh, 420px)); }
}

/* ============================================================
   Unified Surface Hero v2 — NATIVE COVER (single posts, HYBRID).
   The cover provides ONLY the image (image-only); the dynamic
   breadcrumb (post-terms) + post-title stay in the template,
   overlaid (image-content z3) so they FOLLOW the live post. The
   image area is grid-stacked (override the fixed flex height) so
   the cover drives height → native min-height drag/numeric work.
   The tuned single ::after scrim (top+bottom) is kept for
   legibility (cover carries no overlay). Bespoke shell → explicit
   transparent header.
   ============================================================ */
.yf-hero5b--single > .yf-hero5b__image {
	height: auto;
	display: grid;
	grid-template-columns: 1fr;
	grid-template-rows: auto;
}
.yf-hero5b--single > .yf-hero5b__image > .yf-hero__outlet--cover {
	grid-row: 1;
	grid-column: 1;
	z-index: 0;
	margin: 0;
	min-width: 0;
}
.yf-hero5b--single > .yf-hero5b__image > .yf-hero5b__image-content {
	grid-row: 1;
	grid-column: 1;
	z-index: 3;
}
.yf-hero5b--single .yf-hero__outlet--cover .wp-block-cover {
	min-height: var(--yf-hero-inner-h, 520px);
	width: 100%;
}
.yf-hero5b--single .yf-hero__outlet--cover .wp-block-cover__image-background {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
}
.yf-hero5b--single .yf-header { background: transparent; border-bottom: 0; }
.yf-hero5b--single .yf-header__logo-yoya { color: var(--wp--preset--color--on-image); }
.yf-hero5b--single .yf-header__logo-fun { color: var(--wp--preset--color--accent-soft); }
.yf-hero5b--single .yf-header__nav .wp-block-navigation-item__content,
.yf-hero5b--single .yf-header__search a,
.yf-hero5b--single .yf-header__lang a,
.yf-hero5b--single .yf-header__nav .wp-block-navigation__submenu-icon { color: var(--wp--preset--color--on-image); }
.yf-hero5b--single .yf-header__subscribe .wp-block-button__link {
	color: var(--wp--preset--color--on-image);
	border-color: var(--wp--preset--color--on-image);
}
.yf-hero5b--single .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content,
.yf-hero5b--single .yf-header__nav .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-icon { color: var(--wp--preset--color--ink); }
.yf-hero5b--single .yf-header__nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content { color: var(--wp--preset--color--ink); }
@media ( max-width: 1199px ) {
	.yf-hero5b--single .yf-hero__outlet--cover .wp-block-cover { min-height: var(--yf-hero-inner-h-t, 420px); }
}
@media ( max-width: 600px ) {
	.yf-hero5b--single .yf-hero__outlet--cover .wp-block-cover { min-height: var(--yf-hero-inner-h-m, 320px); }
}

/* ============================================================
 * B4 - rail mini related/cross lists (replaces the static
 * "wired in a later batch" rail placeholders with real links).
 * Typography mirrors the rail TOC list.
 * ============================================================ */
.yf-rail4__mini { display: flex; flex-direction: column; gap: 12px; }
.yf-rail4__mini-item { display: flex; flex-direction: column; gap: 2px; text-decoration: none; }
.yf-rail4__mini-kicker {
	font-family: var(--wp--preset--font-family--ui);
	font-size: 10px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ink-mute);
}
.yf-rail4__mini-title {
	font-family: var(--wp--preset--font-family--body);
	font-size: 14px;
	line-height: 1.4;
	color: var(--wp--preset--color--ink-soft);
	transition: color 0.2s var(--wp--custom--yf--easing--air, ease-out);
}
.yf-rail4__mini-item:hover .yf-rail4__mini-title { color: var(--wp--preset--color--accent); }
/* band card links wrap the whole card - keep text colors inherited */
.yf-card5-2__link, .yf-cross__link { text-decoration: none; color: inherit; display: block; }

/* ============================================================
   T1 (Dispatch A / Gate 1) — featured-image card containers must
   fill their grid cell and clip, so a portrait/vertical image can
   never dictate card width (regression: the figure shrank to the
   image's intrinsic width, ~414px, instead of the cell). The
   <img> then covers as a block.
   Scope: archive cards + card3 (front-page lead cards). card4 is
   already complete; cross / card5-2 use a background-image (no
   <img>, no overflow risk). Appended at end of file — outside the
   Mechanism A / .yf-header__* rules, header untouched.
   ============================================================ */
/* MW3.29 - CORRECT card-image containment (replaces failed T1 width/overflow attempt).
   Link/image taken OUT of flow so the figure is sized ONLY by cell width + aspect-ratio;
   any image (portrait/landscape/square/pano) renders as a clean square, no overflow/overlap. */
.yf-archive__card-image { position: relative; width: 100%; aspect-ratio: 1 / 1; overflow: hidden; }
.yf-archive__card-image > a,
.yf-archive__card-image > img { position: absolute; inset: 0; display: block; }
.yf-archive__card-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
