/*
Theme Name: FFA Horizon
Theme URI: https://ffa.org
Author: FFA / Lawrence Downes
Author URI: https://ffa.org
Description: Second first-party block (FSE) theme variation for the National FFA Organization — a darker, more color-forward Exploratory mode (DM Serif headings, Montserrat body) with a light Tactical mode for library/utilitarian surfaces. Brand truth lives in theme.json (approved palette only); reusable patterns/block styles come from the ffa-patterns + ffa-block-ui plugins. Sibling of ffa-brand; the plugins supply all CPT rendering via the decoupled template providers.
Version: 0.5.0
Requires at least: 6.6
Tested up to: 7.0
Requires PHP: 8.1
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: ffa-horizon
Tags: full-site-editing, block-styles, blog
*/

/* -------------------------------------------------------------------------
 * Sticky site header.
 * The header template part renders as <header class="wp-block-template-part">,
 * a direct child of .wp-site-blocks — so the wrapper (not the inner group) is
 * the element whose containing block is tall enough for position:sticky to work.
 * ---------------------------------------------------------------------- */
.wp-site-blocks > header.wp-block-template-part {
	position: sticky;
	top: 0;
	z-index: 100;
}

/* Offset for the WordPress admin bar when logged in. */
.admin-bar .wp-site-blocks > header.wp-block-template-part {
	top: 32px;
}

@media screen and (max-width: 782px) {
	.admin-bar .wp-site-blocks > header.wp-block-template-part {
		top: 46px;
	}
}

/* A soft shadow appears only once the header is pinned. */
.ffa-scrolled .wp-site-blocks > header.wp-block-template-part {
	box-shadow: 0 6px 18px -10px rgba(10, 14, 40, 0.6);
}

/* Scroll canvas. The sticky header's top bar is dark (corduroy) but the body
 * background is light, so a mobile rubber-band overscroll at the top reveals a
 * white sliver above the header. Paint the root canvas corduroy so the
 * overscroll gutters (top and bottom) stay on-brand. The corduroy preset var
 * is defined on <body>, which the root element can't inherit up to, so the
 * value is set literally here. */
html {
	background-color: #16274a;
}

/* -------------------------------------------------------------------------
 * Header emblem + shrink-on-scroll.
 * ---------------------------------------------------------------------- */
.ffa-emblem {
	margin: 0;
}
.ffa-emblem img {
	display: block;
	width: clamp(56px, 6vw, 84px);
	height: auto;
	transition: width 0.25s ease;
}
.ffa-main-bar {
	padding-top: var(--wp--preset--spacing--40);
	padding-bottom: var(--wp--preset--spacing--40);
	transition: padding-top 0.25s ease, padding-bottom 0.25s ease;
}

.ffa-scrolled .ffa-emblem img {
	width: 46px;
}
.ffa-scrolled .ffa-main-bar {
	padding-top: 0.45rem;
	padding-bottom: 0.45rem;
}

@media (prefers-reduced-motion: reduce) {
	.ffa-emblem img,
	.ffa-main-bar {
		transition: none;
	}
}

/* -------------------------------------------------------------------------
 * Header chrome — colors come from theme.json custom props so the Tactical
 * body class can flip the dark Exploratory header to a light one without
 * editing the header template part.
 * ---------------------------------------------------------------------- */
.ffa-main-bar {
	background-color: var(--wp--custom--header--bg);
	color: var(--wp--custom--header--text);
	border-bottom: 3px solid var(--wp--custom--header--rule);
}
/* Tactical keeps a thin hairline rule, not the bold yellow Exploratory accent. */
body.ffa-tactical .ffa-main-bar {
	border-bottom-width: 1px;
}
.ffa-main-bar .wp-block-navigation,
.ffa-main-bar .wp-block-navigation a:where(:not(:hover)) {
	color: var(--wp--custom--header--text);
}

/* Close the gap between the sticky header and the first section / title bar so
 * the hero (home) and the title bar (archives) sit flush under the header. */
.wp-site-blocks > header.wp-block-template-part + * {
	margin-block-start: 0;
}

/* Same at the bottom: the footer is the last child of .wp-site-blocks and picks
 * up the root block-gap as a top margin, showing the page background as a white
 * sliver between the last dark band and the dark footer. The core :last-child
 * reset only clears margin-block-end, so zero the start here. */
.wp-site-blocks > footer.wp-block-template-part {
	margin-block-start: 0;
}

/* Seamless colour bands — adjacent full-bleed sections (hero + section groups)
 * butt directly together with no gap, so the page background never shows between
 * them. Each band brings its own internal padding for breathing room. Covers
 * both layouts: sections placed directly under <main> (front-page.html) and
 * sections rendered inside .wp-block-post-content (page.html / the door pages,
 * where the page's blocks are wrapped by post-content). Scoped to group/cover
 * children only — NOT a bare `> *` — so <p> spacing inside a blog post body is
 * left intact (see single.html / imported news posts). */
/* The <main> branch takes :where() on the CHILD deliberately, dropping it from
 * 0,2,1 to 0,1,1. At 0,2,1 it silently won arguments it was never meant to
 * enter: a plugin's own 0,2,0 rule setting a margin on a direct child of <main>
 * lost to it, and the only way out was !important — for a rule that does not
 * even name the element it was overriding, so grepping for the class found
 * nothing and the cascade looked broken. 0,1,1 still beats core's
 * `:root :where(.is-layout-constrained) > *` at 0,1,0, so the bands stay
 * seamless, while a single-class-pair rule can now say otherwise without
 * shouting. The .wp-block-post-content branch is left at 0,2,0 because it is
 * already only one step above core and has no headroom to give up. */
main.wp-block-group > :where(.wp-block-group, .wp-block-cover),
.wp-block-post-content > .wp-block-group,
.wp-block-post-content > .wp-block-cover {
	margin-block: 0;
}

/* -------------------------------------------------------------------------
 * Column "cards".
 * When a column ends in a call-to-action, pin the buttons to the bottom so the
 * CTAs line up across an equal-height row even when the cards carry different
 * amounts of copy. Two things make this robust everywhere the theme is used:
 *   1. Only pin while the columns sit side by side (>=782px). Once they stack
 *      on phones each card is its own height, so there is nothing to align and
 *      we leave the buttons' natural top margin (the intended copy->CTA gap).
 *   2. The `!important` on the auto margin is required: a buttons block usually
 *      carries an inline `margin-top` from its own spacing control, and an
 *      inline style beats an ordinary stylesheet rule — so without `!important`
 *      the inline margin silently defeats the pin and the buttons never drop to
 *      the bottom. That is exactly the regression this rule keeps hitting.
 * Also let multi-card rows that opted out of mobile stacking
 * (is-not-stacked-on-mobile) stack anyway on phones, where three-abreast cards
 * get too cramped to read comfortably.
 * ---------------------------------------------------------------------- */
@media (min-width: 782px) {
	.wp-block-columns > .wp-block-column:has(> .wp-block-buttons:last-child) {
		display: flex;
		flex-direction: column;
	}
	.wp-block-columns > .wp-block-column:has(> .wp-block-buttons:last-child) > .wp-block-buttons:last-child {
		margin-block-start: auto !important;
	}
}

@media (max-width: 781px) {
	.wp-block-columns.is-not-stacked-on-mobile {
		flex-wrap: wrap;
	}
	.wp-block-columns.is-not-stacked-on-mobile > .wp-block-column {
		flex-basis: 100%;
	}
}

/* -------------------------------------------------------------------------
 * Footer grit — subtle fractal-noise overlay on the dark footer.
 * ---------------------------------------------------------------------- */
.ffa-footer {
	position: relative;
	overflow: hidden;
}
.ffa-footer::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	background-color: #ffffff;
	opacity: 0.22;
	-webkit-mask: url(/wp-content/themes/ffa-horizon/assets/motifs/grit.svg) repeat 0 0 / 640px 450px;
	mask: url(/wp-content/themes/ffa-horizon/assets/motifs/grit.svg) repeat 0 0 / 640px 450px;
}
.ffa-footer > * {
	position: relative;
}

/* -------------------------------------------------------------------------
 * Reusable grit — texture a large field of bright colour so it isn't flat
 * (add className "ffa-grit" to any color band/block). Same fractal noise as the
 * header/footer; contents are lifted above the overlay.
 * ---------------------------------------------------------------------- */
.ffa-grit {
	position: relative;
	overflow: hidden;
}
.ffa-grit > * {
	position: relative;
	z-index: 1;
}
.ffa-grit::before {
	content: "";
	position: absolute;
	inset: 0;
	pointer-events: none;
	/* The FFA grit texture as a TINTABLE mask: the specks take the grit colour
	 * (--ffa-grit-color, default white) at the grit opacity (--ffa-grit-opacity,
	 * default 0.5). Sharp, background only. Both vars are set per band by the
	 * "FFA Grit" block control; the defaults give white specks for dark bands. */
	background-color: var(--ffa-grit-color, #ffffff);
	opacity: var(--ffa-grit-opacity, 0.5);
	-webkit-mask: url(/wp-content/themes/ffa-horizon/assets/motifs/grit.svg) repeat 0 0 / 640px 450px;
	mask: url(/wp-content/themes/ffa-horizon/assets/motifs/grit.svg) repeat 0 0 / 640px 450px;
}

/* Grit is the BAND's own background texture only — suppress it on any grit block
 * nested inside another (e.g. colour cards inside a band), so it shows on the
 * band background but never on the blocks/content placed inside it. */
.ffa-grit .ffa-grit::before {
	display: none;
}

/* -------------------------------------------------------------------------
 * Eyebrow — a small uppercase brand label above a heading (the "Eyebrow" block,
 * a core/paragraph variation; see assets/js/ffa-eyebrow.js). Typography lives
 * here so it holds even if the inline styles are cleared; colour is the author's
 * (the block defaults to Rising Sun).
 * ---------------------------------------------------------------------- */
.ffa-eyebrow {
	font-size: var(--wp--preset--font-size--small);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.22em;
	line-height: 1.3;
	margin-bottom: 0.4rem;
}

/* -------------------------------------------------------------------------
 * Line-art motifs. Used to CROWN headings and as faint same-hue texture —
 * never as lone floating decorations.
 * ---------------------------------------------------------------------- */

/* Sunburst CROWN — a clean rising-sun ray-fan SVG (blue, baked) that sits tight
 * ABOVE a section title. Small + cropped so it reads as a crown, not a banner. */
.wp-block-separator.ffa-sunburst {
	border: 0;
	opacity: 1;
	height: auto;
	width: min(190px, 52%);
	aspect-ratio: 240 / 132;
	min-height: 0;
	margin: 0 auto 0.5rem;
	background: center bottom / contain no-repeat url(/wp-content/themes/ffa-horizon/assets/motifs/sunburst.svg);
}

/* Same-hue dot texture — a faint dot field bleeding off a corner of a colour band
 * (use with .ffa-grit for position + overflow:hidden). Cropped small so it reads
 * as texture, not artwork. */
.ffa-texture-dots::after {
	content: "";
	position: absolute;
	z-index: 0;
	right: -1%;
	bottom: -3%;
	width: 34%;
	aspect-ratio: 1;
	pointer-events: none;
	opacity: 0.4;
	background-color: var(--wp--preset--color--rust);
	-webkit-mask: right bottom / contain no-repeat;
	mask: right bottom / contain no-repeat;
	-webkit-mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-dots.svg);
	mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-dots.svg);
}

/* Diagonal-line accent — small, crisp, bleeds off the BOTTOM-LEFT corner of a band
 * (use with .ffa-grit). Tinted to a neighbouring hue so it reads as a brand accent. */
.ffa-texture-diagonal::after {
	content: "";
	position: absolute;
	z-index: 0;
	left: -1%;
	bottom: -3%;
	width: 32%;
	aspect-ratio: 1;
	pointer-events: none;
	opacity: 0.36;
	background-color: var(--wp--preset--color--sky);
	-webkit-mask: left bottom / contain no-repeat;
	mask: left bottom / contain no-repeat;
	-webkit-mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-diagonal-lines.svg);
	mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-diagonal-lines.svg);
}

/* Wave accent — small, crisp, bleeds off the TOP-RIGHT corner of a band
 * (use with .ffa-grit). */
.ffa-texture-waves::after {
	content: "";
	position: absolute;
	z-index: 0;
	right: -1%;
	top: -2%;
	width: 42%;
	aspect-ratio: 16 / 9;
	pointer-events: none;
	opacity: 0.34;
	background-color: var(--wp--preset--color--cream);
	-webkit-mask: right top / contain no-repeat;
	mask: right top / contain no-repeat;
	-webkit-mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-waves.svg);
	mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-waves.svg);
}

/* -------------------------------------------------------------------------
 * Configurable accent (the "FFA Accent" block control — see assets/js/ffa-accent.js
 * + render_block_accent() in functions.php). The block carries has-ffa-accent +
 * modifier classes and the --ffa-accent-* custom props; this draws the masked
 * motif, tinted to the chosen brand colour, positioned per the controls. A
 * positive offset translates the accent past the edge to overlap the next band.
 * ---------------------------------------------------------------------- */
.has-ffa-accent {
	position: relative;
	z-index: 1;
}
.has-ffa-accent > * {
	position: relative;
	z-index: 1;
}
.has-ffa-accent::after {
	content: "";
	position: absolute;
	z-index: 0;
	pointer-events: none;
	background-color: var(--ffa-accent-color, #F1DCAA);
	/* The motif is a FIXED-scale pattern — the lines/dots are a constant size. The
	 * accent box is a MASK WINDOW onto it: growing the box reveals MORE of the
	 * pattern (it never stretches the lines/dots). mask-size is a constant; the
	 * mask anchors to the chosen corner so the reveal grows out from there.
	 *
	 * --ffa-accent-scale shrinks the WHOLE accent proportionally on small screens
	 * (set in the media queries below): it multiplies the locked dimension, the
	 * reveal length, AND the pattern size together, so the composition stays the
	 * same — just smaller — rather than cropping to a corner on mobile. */
	--ffa-accent-scale: 1;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-size: calc(var(--ffa-accent-pattern, 900px) * var(--ffa-accent-scale));
	mask-size: calc(var(--ffa-accent-pattern, 900px) * var(--ffa-accent-scale));
	-webkit-mask-position: var(--ffa-accent-mx, center) var(--ffa-accent-my, center);
	mask-position: var(--ffa-accent-mx, center) var(--ffa-accent-my, center);
	transform: translateY(var(--ffa-accent-ty, 0px));
}
.ffa-accent--waves::after    { -webkit-mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-waves.svg);          mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-waves.svg); }
.ffa-accent--dots::after     { -webkit-mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-dots.svg);           mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-dots.svg); }
.ffa-accent--diagonal::after { -webkit-mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-diagonal-lines.svg); mask-image: url(/wp-content/plugins/ffa-patterns/assets/motifs/motif-diagonal-lines.svg); }

/* Orientation sets which axis is locked and which is the variable reveal length:
 * a landscape (horizontal) window keeps a fixed 150px HEIGHT and grows in WIDTH;
 * a portrait (vertical) window keeps a fixed 150px WIDTH and grows in HEIGHT.
 * No rotation — only the window shape changes, so the pattern never disappears. */
.ffa-accent--horizontal::after { height: calc(150px * var(--ffa-accent-scale)); width: calc(var(--ffa-accent-len, 320px) * var(--ffa-accent-scale)); }
.ffa-accent--vertical::after   { width: calc(150px * var(--ffa-accent-scale));  height: calc(var(--ffa-accent-len, 320px) * var(--ffa-accent-scale)); }

/* Side + vertical edge anchor the window (and the mask) to one corner of the band;
 * a positive overlap offset pushes it out past that edge to spill onto the next. */
.ffa-accent--left::after   { left: 0;   --ffa-accent-mx: left; }
.ffa-accent--right::after  { right: 0;  --ffa-accent-mx: right; }
.ffa-accent--top::after    { top: 0;    --ffa-accent-my: top;    --ffa-accent-ty: calc(-1 * var(--ffa-accent-offset, 0px) * var(--ffa-accent-scale)); }
.ffa-accent--bottom::after { bottom: 0; --ffa-accent-my: bottom; --ffa-accent-ty: calc(var(--ffa-accent-offset, 0px) * var(--ffa-accent-scale)); }

/* Scale the whole accent down on smaller screens so it reads in proportion to the
 * narrower bands instead of dominating them (the locked dimension, reveal length
 * and pattern size all shrink together). */
@media (max-width: 781px) {
	.has-ffa-accent::after { --ffa-accent-scale: 0.7; }
}
@media (max-width: 480px) {
	.has-ffa-accent::after { --ffa-accent-scale: 0.5; }
}

/* Tricolor band — three brand-colour columns butted edge-to-edge into one
 * seamless full-bleed band. blockGap:0 in the block draws the seam; equal height
 * comes from the columns' default stretch, so each colour fills its full column. */
.ffa-tricolor.wp-block-columns {
	gap: 0;
	border-radius: 16px;
	overflow: hidden;
}

/* -------------------------------------------------------------------------
 * Anton (the `display` family) is ALWAYS all-caps and ALWAYS weight 400 — it's a
 * heavy display face, so faux-bold (700) smears it and it's unreadable small.
 *
 * ⚠️ The previous comment here said "h2–h6 are Montserrat and untouched". That
 * was not true: theme.json's styles.elements.heading applies the display family
 * to EVERY heading and set textTransform:none, so h2–h6 rendered Anton in mixed
 * case — reported on the Our Impact briefs. The casing now travels with the font
 * in theme.json itself, which is where the font is chosen.
 *
 * The selector list below is the fallback for surfaces that set the display font
 * in their own CSS rather than through the preset. It is a hand-maintained list
 * and has been incomplete twice, so the attribute selector catches anything
 * applying the preset inline, and the standing rule is that whoever applies the
 * font applies the casing with it. Doubled :root out-specifies theme.json.
 * ---------------------------------------------------------------------- */
:root:root h1,
.has-display-font-family,
[style*="--wp--preset--font-family--display"],
.impact-single__title,
.ffarl-collection-title {
	text-transform: uppercase;
	font-weight: 400;
	font-synthesis-weight: none;
}

/* Rule 3 (size floor): Anton is unreadable below 20px, so any display-tagged block
 * at the small/medium size presets (14px/18px) falls back to Montserrat 700. The
 * large/x-large/display presets (≥24px) keep Anton; headings h2–h6 are already
 * Montserrat. See docs/brand-typography-anton.md. */
.has-display-font-family.has-small-font-size,
.has-display-font-family.has-medium-font-size {
	font-family: var(--wp--preset--font-family--sans) !important;
	font-weight: 700 !important;
	text-transform: none;
}

/* -------------------------------------------------------------------------
 * Exploratory (default) is a light canvas with a dark, gritty header + footer
 * and color-blocked sections. Tactical config — flips the chrome to the clean,
 * restrained treatment (white header, hairline rule, steel linework) on the
 * content types assigned the Tactical look under Appearance -> Style Modes
 * (body.ffa-tactical, set in inc/style-modes.php). WP has no native
 * per-template style variation, so this scope class is the mechanism.
 * ---------------------------------------------------------------------- */
body.ffa-tactical {
	background-color: var(--wp--preset--color--white);
	color: var(--wp--preset--color--ink);
	--wp--custom--header--bg: var(--wp--preset--color--white);
	--wp--custom--header--text: var(--wp--preset--color--corduroy);
	--wp--custom--header--rule: #E3E7EE;
	--wp--custom--titlebar--bg: #EEF1F5;
	--wp--custom--titlebar--text: var(--wp--preset--color--corduroy);
	--wp--custom--titlebar--rule: var(--wp--preset--color--ffa-blue);
	--wp--custom--linework: var(--wp--preset--color--steel);
}
/* On the Tactical shell, pin headings/eyebrows to the restrained corduroy/steel
 * ladder (vs. Exploratory's ffa-blue + accent colours) for the utilitarian look. */
body.ffa-tactical :where(h1, h2, h3, h4, .wp-block-post-title) {
	color: var(--wp--preset--color--corduroy);
}
body.ffa-tactical :where(h5) { color: var(--wp--preset--color--steel); }
body.ffa-tactical :where(h6) { color: var(--wp--preset--color--rust); }
body.ffa-tactical a:where(:not(.wp-element-button)) {
	color: var(--wp--preset--color--ffa-blue);
}

/* -------------------------------------------------------------------------
 * Page title bar — a full-bleed band under the header carrying the page/archive
 * title. Exploratory (dark): blue band + 4px yellow top rule, white text.
 * Tactical (light): light band + blue left bar, corduroy text.
 * ---------------------------------------------------------------------- */
.ffa-title-bar {
	background-color: var(--wp--custom--titlebar--bg);
	color: var(--wp--custom--titlebar--text);
	border-top: 4px solid var(--wp--custom--titlebar--rule);
	padding-top: var(--wp--preset--spacing--60);
	padding-bottom: var(--wp--preset--spacing--60);
}
.ffa-title-bar :where(h1, h2, p) {
	color: var(--wp--custom--titlebar--text);
}
body.ffa-tactical .ffa-title-bar {
	border-top: 0;
	position: relative;
}
body.ffa-tactical .ffa-title-bar::before {
	content: "";
	position: absolute;
	top: var(--wp--preset--spacing--40);
	bottom: var(--wp--preset--spacing--40);
	left: max(var(--wp--style--root--padding-left, 1rem), calc((100% - var(--wp--style--global--content-size)) / 2));
	width: 6px;
	background: var(--wp--custom--titlebar--rule);
}
body.ffa-tactical .ffa-title-bar :where(h1, p) {
	padding-left: 2rem;
}

/* Search-term highlight (ElasticPress wraps matches). */
.ep-highlight,
.wp-block-post-template mark,
.impact-single mark {
	background: var(--wp--preset--color--ffa-yellow);
	color: var(--wp--preset--color--corduroy);
	padding: 0 0.15em;
	border-radius: 2px;
}

/* =========================================================================
 * Content-engine brand layer — FFARL resource/curriculum + CFVL video singles.
 * These bodies are driven by the plugins' scheme-token system; override the
 * tokens with brand values so they render as clean light (Tactical) surfaces.
 * ====================================================================== */
.ffarl-player-wrap[class*="ffarl-scheme-"],
.cfvl-player-wrap[class*="cfvl-scheme-"] {
	--ffarl-bg: var(--wp--preset--color--white);
	--ffarl-text: var(--wp--preset--color--ink);
	--ffarl-muted: color-mix(in srgb, var(--wp--preset--color--ink) 55%, transparent);
	--ffarl-accent: var(--wp--preset--color--steel);
	--ffarl-accent-ink: var(--wp--preset--color--white);
	--ffarl-surface: var(--wp--preset--color--surface);
	--ffarl-border: var(--wp--preset--color--line);
	--ffarl-font-display: var(--wp--preset--font-family--display);
	--ffarl-font-body: var(--wp--preset--font-family--sans);
	--ffarl-radius: 9px;
	--cfvl-bg: var(--wp--preset--color--white);
	--cfvl-text: var(--wp--preset--color--ink);
	--cfvl-muted: color-mix(in srgb, var(--wp--preset--color--ink) 55%, transparent);
	--cfvl-accent: var(--wp--preset--color--steel);
	--cfvl-accent-ink: var(--wp--preset--color--white);
	--cfvl-surface: var(--wp--preset--color--surface);
	--cfvl-border: var(--wp--preset--color--line);
	--cfvl-font-display: var(--wp--preset--font-family--display);
	--cfvl-font-body: var(--wp--preset--font-family--sans);
	--cfvl-radius: 9px;
}
.ffarl-resource-header .ffarl-collection-title,
.ffarl-resource-header h1 {
	font-family: var(--wp--preset--font-family--display);
	color: var(--wp--preset--color--ffa-blue);
}
.ffarl-resource-pill {
	background: color-mix(in srgb, var(--wp--preset--color--steel) 12%, transparent);
	color: var(--wp--preset--color--steel);
	border-radius: 999px;
	font-weight: 700;
	text-transform: uppercase;
	font-size: 0.72rem;
	letter-spacing: 0.04em;
	text-decoration: none;
}

/* Resource-library single pages: re-skin the FFARL partials to the brand
 * palette + type by overriding the --ffarl-* design tokens. */
.ffarl-lib-single .ffarl-player-wrap.ffarl-library-wrap {
	--ffarl-accent: var(--wp--preset--color--ffa-blue);
	--ffarl-accent-ink: var(--wp--preset--color--white);
	--ffarl-surface: var(--wp--preset--color--surface);
	--ffarl-border: var(--wp--preset--color--line);
	--ffarl-radius: 8px;
	--ffarl-text: var(--wp--preset--color--ink);
	--ffarl-bg: transparent;
	--ffarl-font-body: var(--wp--preset--font-family--sans);
	--ffarl-font-display: var(--wp--preset--font-family--display);
}
.ffarl-lib-single .ffarl-resource-header {
	margin: 0 0 1.5rem;
}
.ffarl-lib-single .ffarl-collection-title {
	line-height: 1.08;
	letter-spacing: 0;
}
.ffarl-lib-single .ffarl-series-season-title {
	font-size: 0.78rem;
	font-weight: 800;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--wp--preset--color--ffa-blue);
}

/* -------------------------------------------------------------------------
 * Exploratory content patterns — folded in from the prototype site's
 * Additional CSS so they travel with the theme across every FFA site.
 * ---------------------------------------------------------------------- */

/* Split hero: an enlarged, blurred, duotoned photo sits behind a sharp
   duotoned side portrait. */
.ffa-split-hero.wp-block-cover {
	overflow: hidden;
}
.ffa-split-hero .wp-block-cover__image-background {
	filter: url(#wp-duotone-ffa-blue) blur(28px) !important;
	transform: scale(1.22);
}

/* Numbered marker badge for two-part cards. */
.ffa-num-badge {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 2.5rem;
	height: 2.5rem;
	border-radius: 50%;
	background: var(--wp--preset--color--ffa-yellow);
	color: var(--wp--preset--color--ffa-blue);
	font-weight: 800;
	font-size: 1.25rem;
	line-height: 1;
	margin: 0 0 1.5rem 0;
}

/* Numbered cards stretch to equal height within their row. */
.wp-block-columns .wp-block-column > .wp-block-group:has(.ffa-num-badge) {
	height: 100%;
}

/* FAQ questions in bold (ffa-faq block <summary>). */
.ffaq-faq summary {
	font-weight: 700;
}

/* Eyebrow contrast: wheat fails WCAG AA on the teal (steel) bands — use
   white there instead. */
.has-steel-background-color .ffa-eyebrow.has-wheat-color {
	color: var(--wp--preset--color--white);
}

/* --- Featured-image thumbnails (post-featured-image with aspectRatio + isLink) ---
   These sit in flex rows next to the title/text. The real cause of the "all over
   the place" sizes was flexbox: with default flex-shrink each thumbnail compressed
   to a DIFFERENT width (a width:240px card rendered ~191px vs ~126px depending on
   the neighbouring text) — the aspect ratio was fine, the width wasn't. Hold the
   width with flex-shrink:0, and take the isLink <a> out of the flow (absolute) so
   the figure's aspect-ratio box governs and the image crops to fill it. The `a` /
   `a img` selectors only touch LINKED featured images (every thumbnail), never the
   single-post hero (no link), which keeps its natural size. */
.wp-block-post-featured-image {
	position: relative;
	overflow: hidden;
	flex-shrink: 0;
}
.wp-block-post-featured-image a {
	position: absolute;
	inset: 0;
	display: block;
}
.wp-block-post-featured-image a img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* --- Post-body images: constrain migrated (classic/Avada) raw <img> tags ---
   Imported news bodies carry bare <img> with no width cap and no core/image
   wrapper, so they rendered at full natural size. Keep them within the column. */
.wp-block-post-content img {
	max-width: 100%;
	height: auto;
}

/* Responsive main-feed thumbnail width — the fixed 240px card image is too wide on
   a phone (it crushed the title/excerpt beside it). clamp() scales it down on
   narrow screens and holds 240px on desktop. Scoped by the inline width:240px so
   it only hits the main-feed cards — not the 100px sidebar thumbs, not the
   linkless single-post hero. !important overrides the inline width. */
.wp-block-post-featured-image[style*="width:240px"] {
	width: clamp(96px, 26vw, 240px) !important;
}

/* -------------------------------------------------------------------------
 * Colour spec cards. Each .ffa-swatch is a colour chip plus rows of values
 * (.ffa-spec); clicking a row copies its data-copy value to the clipboard and
 * flashes a confirmation (see assets/js/ffa-copy-hex.js).
 * ---------------------------------------------------------------------- */
.ffa-color-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
	gap: 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}
.ffa-swatch {
	position: relative;
	display: flex;
	flex-direction: column;
	background: var(--wp--preset--color--surface);
	border: 1px solid var(--wp--preset--color--line);
	border-radius: 12px;
	overflow: hidden;
	transition: box-shadow 0.14s ease;
}
.ffa-swatch:hover {
	box-shadow: 0 10px 22px -14px rgba(10, 14, 40, 0.5);
}
.ffa-swatch__chip {
	height: 72px;
	background: var(--ffa-swatch-color);
	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
}
.ffa-swatch__body {
	padding: 12px 12px 14px;
}
.ffa-swatch__name {
	margin: 0 0 8px;
	font-weight: 800;
	font-size: 0.95rem;
	line-height: 1.2;
	color: var(--wp--preset--color--ink);
}
/* One copyable value row. */
.ffa-spec {
	position: relative;
	display: flex;
	align-items: baseline;
	gap: 8px;
	width: 100%;
	margin: 0;
	padding: 5px 28px 5px 8px;
	border: 0;
	border-radius: 6px;
	background: transparent;
	font: inherit;
	text-align: left;
	cursor: pointer;
	transition: background 0.12s ease;
}
.ffa-spec + .ffa-spec {
	margin-top: 1px;
}
.ffa-spec:hover,
.ffa-spec:focus-visible {
	background: var(--wp--preset--color--paper);
	outline: none;
}
.ffa-spec:focus-visible {
	box-shadow: inset 0 0 0 2px var(--wp--preset--color--ffa-blue);
}
.ffa-spec__k {
	flex: 0 0 3.8em;
	font-size: 0.62rem;
	font-weight: 800;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--wp--preset--color--steel);
}
.ffa-spec__v {
	flex: 1 1 auto;
	font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
	font-size: 0.8rem;
	color: var(--wp--preset--color--ink);
}
/* Copy cue on the right edge; turns into a check when copied. */
.ffa-spec::after {
	content: "\29C9";
	position: absolute;
	top: 50%;
	right: 8px;
	transform: translateY(-50%);
	font-size: 0.85rem;
	line-height: 1;
	color: var(--wp--preset--color--steel);
	opacity: 0;
	transition: opacity 0.12s ease;
}
.ffa-spec:hover::after,
.ffa-spec:focus-visible::after {
	opacity: 0.6;
}
.ffa-spec.is-copied {
	background: rgba(56, 146, 65, 0.14);
}
.ffa-spec.is-copied::after {
	content: "\2713";
	opacity: 1;
	color: var(--wp--preset--color--ffa-green);
}
/* Screen-reader-only live region for copy announcements. */
.ffa-swatch__status {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}
@media (prefers-reduced-motion: reduce) {
	.ffa-swatch,
	.ffa-spec,
	.ffa-spec::after {
		transition: none;
	}
}
