/*
 * Fluent Commerce 2026 design system — blog index and article.
 *
 * From the export's "Site - Blog", "Site - Blog Post", "Block - Email CTA" and
 * "Block - Crosslink". The design expresses all of this as inline styles on the
 * markup, because a Claude Design page has nowhere else to put it. Here it is
 * lifted into named classes — same values, but the article template can then
 * style WordPress's block output, which inline styles could never reach.
 *
 * Written fresh rather than carried over from the previous assets/blog.css. That
 * file was written before any design existed, so every number in it was a guess;
 * none of it survives.
 *
 * @package Fluent_Commerce
 */

/* ═════════════════════════════════════════════════════════════════════════════
 * SHARED — the card
 *
 * One component, two uses: the index grid and the article's "More great
 * reading". The whole card is a single <a>, which is why the hover state can be
 * declared once on the anchor and inherited by the topic and read-time (both
 * color:inherit) while the title and blurb hold their own colour. No stretched
 * link, no nested anchors, nothing for a screen reader to announce twice.
 * ══════════════════════════════════════════════════════════════════════════ */
body.fc-ds .fc-card {
	display: flex;
	flex-direction: column;
	gap: var(--sp-24);
	padding-top: var(--sp-24);
	/* The 1px top rule is the card's only frame. No box, no shadow, no radius. */
	border-top: var(--stroke-1) solid var(--fc-ink-a20);
	color: var(--fc-ink-a60);
	transition: color var(--dur-base) var(--ease-out), border-top-color var(--dur-base) var(--ease-out);
}

/*
 * The hover moves the rule and the meta from 20%/60% to full ink. That is the
 * entire interaction — no lift, no scale, no image zoom.
 */
body.fc-ds .fc-card:hover {
	color: var(--fc-ink-12);
	border-top-color: var(--fc-ink-12);
}

body.fc-ds .fc-card__top {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: var(--sp-24);
}

body.fc-ds .fc-card__topic {
	color: inherit;
}

body.fc-ds .fc-card__arrow {
	flex: none;
	color: inherit;
}

/*
 * 16/10 with the image as a background rather than an <img>, matching the design
 * — it keeps the ratio exact and gives a tinted plate when a post has no
 * featured image, instead of a hole in the grid.
 */
body.fc-ds .fc-card__figure {
	display: block;
	aspect-ratio: 16 / 10;
	background-color: var(--fc-ink-a06);
	background-size: cover;
	background-position: center;
}

body.fc-ds .fc-card__title {
	font-family: var(--font-display);
	font-weight: var(--fw-regular);
	font-size: var(--type-title-32);
	line-height: var(--lh-tight);
	letter-spacing: var(--ls-display);
	color: var(--fc-ink-12);
	text-wrap: pretty;
}

/* Card copy, so the card step of the scale — not a 15 of its own. */
body.fc-ds .fc-card__blurb {
	font-size: var(--type-body-15);
	font-weight: var(--fw-medium);
	line-height: var(--lh-loose);
	color: var(--fc-ink-a80);
}

body.fc-ds .fc-card__read {
	color: inherit;
}

/*
 * The related-posts variant. The design drops the read time and sets the blurb
 * at the full body size on a tighter leading — a related card is an invitation,
 * not a listing, so it reads a shade more like body copy.
 */
body.fc-ds .fc-card--related .fc-card__blurb {
	font-size: var(--type-body-18);
	line-height: var(--lh-body);
}

/* ═════════════════════════════════════════════════════════════════════════════
 * BLOG INDEX
 * ══════════════════════════════════════════════════════════════════════════ */
body.fc-ds .fc-blog-head__eyebrow {
	color: var(--fc-ink-a60);
}

body.fc-ds .fc-blog-head__split {
	margin-top: var(--sp-32);
	gap: var(--sp-54);
}

/*
 * The gap above belongs to the eyebrow, not to the section. The blog index does not
 * print one (see fluent_commerce_ds_listing_head), so on that page the split is the
 * section's first child and the heading should sit flush with the section top.
 *
 * :first-child rather than a modifier class, so this follows the markup on its own —
 * any listing that gains or loses its eyebrow is handled without a second edit here.
 */
body.fc-ds .fc-blog-head__split:first-child {
	margin-top: 0;
}

body.fc-ds .fc-blog-head__intro {
	max-width: 46ch;
	font-size: var(--type-body-18);
	font-weight: var(--fw-medium);
	line-height: var(--lh-loose);
	color: var(--fc-ink-a80);
}

/*
 * 54 across, 72 down. The asymmetry is deliberate: the row gap has to clear the
 * next card's top rule so the grid reads as rows of cards rather than a mesh.
 */
body.fc-ds .fc-blog-grid {
	/*
	 * The head and the grid share one section, so the space between them is a
	 * margin here rather than a second section's padding — the alternative is two
	 * sections whose paddings have to cancel each other out to produce one gap.
	 */
	margin-top: var(--sp-72);
	column-gap: var(--sp-54);
	row-gap: var(--sp-72);
}

/* ── Load more ──
 * The button is a real link to page 2 and works with JavaScript switched off.
 * blog.js upgrades it in place: it fetches the next page, appends the cards and
 * moves the link on. The IntersectionObserver in the design triggers the same
 * function, so the button is both the affordance and the fallback.
 */
body.fc-ds .fc-blog-more {
	margin-top: var(--sp-72);
	padding-top: var(--sp-32);
	border-top: var(--stroke-1) solid var(--fc-ink-a20);
	display: flex;
	justify-content: center;
}

body.fc-ds .fc-blog-more__btn {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	height: 48px;
	padding: 0 var(--sp-24);
	border: var(--stroke-1) solid var(--fc-ink-12);
	border-radius: 0;
	background: transparent;
	font-family: var(--font-core);
	font-size: 14px;
	font-weight: var(--fw-medium);
	color: var(--fc-ink-12);
	cursor: pointer;
	transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}

body.fc-ds .fc-blog-more__btn:hover {
	background: var(--fc-ink-12);
	color: var(--fc-bone);
}

body.fc-ds .fc-blog-more__btn[aria-busy="true"] {
	opacity: 0.5;
	pointer-events: none;
}

/* Nothing to load: the row keeps its rule, the control goes. */
body.fc-ds .fc-blog-more.is-done .fc-blog-more__btn {
	display: none;
}

body.fc-ds .fc-blog-empty {
	max-width: 46ch;
	font-size: var(--type-lead-26);
	color: var(--fc-ink-a60);
}

/* ═════════════════════════════════════════════════════════════════════════════
 * THE NEWS LIST
 *
 * /news/ is the one archive on this site that is not a grid of cards, and the reason is
 * the content rather than the design: not one of the 84 imported press releases has an
 * image, so the card grid there would be 84 empty .fc-card__figure plates. See the news
 * entry in inc/content-types.php and the head of inc/ds-news.php.
 *
 * The construction is the resources index's, because that page already solved "a listing
 * with nothing to show but words": a shared top border on the <ul> plus a bottom border
 * on every <li>, which gives n items n+1 hairlines — closed top and bottom — and survives
 * rows being added or dropped without any rule needing to know which one is last. The
 * hover moves a WHITE PLATE under the row rather than underlining it: on bone, white
 * reads as lifted where a grey would read as disabled.
 *
 * It is a copy of those rules and not a shared class, because .fc-resources__* lives in
 * pages.css and this file and that one never load together — see the note above the two
 * wp_enqueue_style calls in inc/ds.php. Nine rules duplicated is the cost of that fork;
 * the alternative is promoting the row into layout.css, which would put a component on
 * every page on the site to serve two.
 *
 * WHAT IS DIFFERENT FROM /resources/: the row is a two-column grid rather than a
 * space-between flex, with the date in a fixed column on the left. An announcement's date
 * is not trailing metadata — it is half of what the row says, live's own index leads with
 * it, and a fixed column is what makes 84 of them line up as a column instead of ragging
 * against 84 headline lengths.
 * ══════════════════════════════════════════════════════════════════════════ */

/*
 * The 72px restates .fc-blog-grid's own top margin, which this element also carries — it
 * carries it so assets/ds/blog.js can find it, not for spacing, and a list whose gap
 * depends on a class it holds for the script's benefit is a gap that vanishes the day
 * someone tidies the markup.
 */
body.fc-ds .fc-newslist {
	margin: var(--sp-72) 0 0;
	padding: 0;
	list-style: none;
	border-top: var(--stroke-1) solid var(--border-on-light);
}

body.fc-ds .fc-newslist__row {
	border-bottom: var(--stroke-1) solid var(--border-on-light);
}

/*
 * align-items: baseline, so the 12px date sits on the first line of a headline that wraps
 * to two rather than centring itself against the whole block.
 *
 * The 16px of side padding is what the white hover plate needs to read as a plate — it
 * gives the type somewhere to sit inside the highlight instead of touching its edge.
 */
body.fc-ds .fc-newslist__link {
	display: grid;
	grid-template-columns: 170px 1fr;
	align-items: baseline;
	gap: var(--sp-32);
	padding: var(--sp-24) var(--sp-16);
	color: var(--text-on-light);
	text-decoration: none;
	transition: background var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}

body.fc-ds .fc-newslist__link:hover,
body.fc-ds .fc-newslist__link:focus-visible {
	background: var(--surface-lightest);
	color: var(--fc-violet);
}

/*
 * The date holds its own colour, so the hover turns the headline violet and leaves the
 * timestamp where it was. It is not the thing being clicked.
 */
body.fc-ds .fc-newslist__date {
	color: var(--fc-ink-a60);
}

body.fc-ds .fc-newslist__label {
	display: inline-flex;
	align-items: flex-start;
	gap: var(--sp-8);
	font-size: var(--type-body-18);
	font-weight: var(--fw-medium);
	line-height: var(--lh-body);
	text-wrap: pretty;
}

/*
 * The arrow follows the label's colour, so it turns violet with the row on hover. The 4px
 * nudge sits it on the cap height of an 18px line rather than on the line box top, where
 * align-items: flex-start would otherwise leave it floating.
 */
body.fc-ds .fc-newslist__arrow {
	flex: none;
	display: block;
	margin-top: 4px;
}

/*
 * 680 is where the headline column has been squeezed to about half the row and press
 * release titles — which run long, "International retailer Safilo Group picks Fluent
 * Commerce to boost delivery speed and convenience for customers" — start wrapping to
 * four lines beside a date that occupies one. Below it the date goes above the headline,
 * which also means the 32px column gap has to become a small row gap.
 */
@container page (max-width: 680px) {
	body.fc-ds .fc-newslist__link {
		grid-template-columns: 1fr;
		gap: var(--sp-8);
	}
}

/* ═════════════════════════════════════════════════════════════════════════════
 * THE MEDIA LIST
 *
 * /media-articles/ is the news list above with a third column for the publication, so
 * .fc-medialist is a MODIFIER on .fc-newslist and every rule in this block is either the
 * third column or a consequence of it. The construction, the hairlines, the white hover
 * plate and the arrow are all inherited untouched.
 *
 * A third column rather than live's logo. Live leads each of its 282 rows with the outlet's
 * press-kit logo — 148 image files across 125 publications, each at its own size and on its
 * own background — and the thing a reader is actually scanning for is whether this is The
 * Grocer or a blog they have never heard of. The name answers that in text, in a column that
 * lines up, at no request cost. See the head of inc/ds-media.php.
 *
 * WHY THESE RULES OUT-SPECIFY THE NEWS ONES: the 900px collapse below has to target
 * .fc-medialist .fc-newslist__link, because only the media rows have a third column to
 * fold. That is two classes, so it also beats the news list's own single-class 680px rule —
 * which means the 680px collapse has to be restated here rather than inherited. The
 * alternative was a --medialist custom property for the column template, which is more
 * machinery than three restated declarations.
 * ══════════════════════════════════════════════════════════════════════════ */

/*
 * ── THE ANALYST NOTE ──
 * A white plate on the bone archive: title and copy on the left, button on the right. It
 * sits under .fc-split rather than inside it — see fluent_commerce_ds_media_guide().
 *
 * THE HAIRLINE IS WHAT KEEPS IT FROM READING AS A ROW. White on bone is exactly what a row
 * of this list becomes on hover, so the plate alone would look like a row stuck mid-hover
 * two inches above 282 real ones. The inset stroke and the title are what say otherwise:
 * no row has either. Same construction as .fc-case-card in resources.css — inset rather
 * than a border, so the stroke costs the box no size and its edge lands exactly on the
 * hairline that opens the list below.
 *
 * Square, like the list. The button inside it is the only rounded thing on the page and
 * should stay that way.
 */
body.fc-ds .fc-medianote {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-24) var(--sp-54);
	margin-top: var(--sp-54);
	padding: var(--sp-32);
	background: var(--fc-white);
	box-shadow: inset 0 0 0 var(--stroke-1) var(--fc-ink-a20);
}

/*
 * .fc-btn ships align-self: flex-start, which beats the align-items above it — so against
 * a title and three lines of copy the button would sit level with the title rather than
 * with the block. Restated here because it is a property of this pairing.
 */
body.fc-ds .fc-medianote > .fc-btn {
	align-self: center;
}

body.fc-ds .fc-medianote__text {
	max-width: 62ch;
}

/*
 * A panel title: grotesk semibold at 20px on --lh-title, which is what that line height is
 * documented for in tokens.css. Not the display serif — .fc-card__title's 32px Fraunces
 * next to the 72px Fraunces <h1> three inches above would read as a second, competing
 * heading rather than as the label on a box.
 */
body.fc-ds .fc-medianote__title {
	margin: 0;
	font-family: var(--font-core);
	font-size: var(--type-body-18);
	font-weight: var(--fw-semibold);
	line-height: var(--lh-title);
	color: var(--fc-ink-12);
}

/*
 * A step down from .fc-blog-head__intro above it, in size and in colour. The intro says what
 * the page is and this is an aside next to it; at the same weight the two would read as one
 * two-paragraph lead and the page would open with more preamble than list.
 */
body.fc-ds .fc-medianote__copy {
	margin: var(--sp-8) 0 0;
	font-size: var(--type-body-16);
	line-height: var(--lh-loose);
	color: var(--fc-ink-a60);
}

/*
 * The plate loses a third of its padding where the gutter is already down to 40px, for the
 * reason .fc-section.fc-ruled does the same: at that width a 32px inset is a visible share
 * of the measure and the copy starts wrapping early.
 */
@container page (max-width: 820px) {
	body.fc-ds .fc-medianote {
		padding: var(--sp-24);
	}
}

/*
 * 200px is what the longest name in the data needs before it wraps to a third line —
 * "Retail Technology Innovation Hub", "Supply & Demand Chain Executive". Two lines is fine
 * and baseline alignment keeps the first one level with the headline; three starts to make
 * the row about the publication.
 */
body.fc-ds .fc-medialist .fc-newslist__link {
	grid-template-columns: 170px 1fr 200px;
}

/*
 * Muted like the date, and for the same reason: the hover turns the HEADLINE violet, which
 * is the thing being clicked. The publication is a fact about the row, not part of the
 * target.
 */
body.fc-ds .fc-medialist__outlet {
	color: var(--fc-ink-a60);
	text-wrap: pretty;
}

/*
 * The one row with no link renders as a <div>, so it must not behave like one that goes
 * somewhere. Qualified with div rather than relying on this block coming after the news
 * hover rule — the whole point of the class is that it cannot be hovered, and that should
 * not depend on source order. a.fc-resources__link:hover in pages.css is the precedent.
 */
body.fc-ds div.fc-medialist__link--dead:hover,
body.fc-ds div.fc-medialist__link--dead:focus-visible {
	background: none;
	color: var(--text-on-light);
	cursor: default;
}

/*
 * 900 is where 170 + 32 + 200 + 32 has taken 434px off the row and the headline column is
 * down to about half of it, which is where these titles — "Under Armour teams up with
 * Emakina & Fluent Commerce to deliver a unified commerce experience" — go to four lines.
 * The publication drops under the headline rather than under the date: it belongs to the
 * headline, and column 1 is the date's.
 */
@container page (max-width: 900px) {
	body.fc-ds .fc-medialist .fc-newslist__link {
		grid-template-columns: 170px 1fr;
		row-gap: var(--sp-8);
	}

	body.fc-ds .fc-medialist__outlet {
		grid-column: 2;
	}
}

/*
 * Single column, restating the news list's own 680 rule for the specificity reason in the
 * banner above. grid-column goes back to 1 as well: left at 2 it would conjure an implicit
 * second column back into a grid that has just been told to have one.
 */
@container page (max-width: 680px) {
	body.fc-ds .fc-medialist .fc-newslist__link {
		grid-template-columns: 1fr;
		gap: var(--sp-8);
	}

	body.fc-ds .fc-medialist__outlet {
		grid-column: 1;
	}

	/*
	 * The 31 rows live has no date for print an empty date element, which holds column one
	 * open so their headlines stay aligned with everyone else's. In one column there is
	 * nothing left to align, so the empty element is only an 8px gap — hidden HERE and not
	 * at full width, where display: none would take it out of the grid and slide the
	 * headline into the date's column. See fluent_commerce_ds_media_row().
	 */
	body.fc-ds .fc-medialist .fc-newslist__date:empty {
		display: none;
	}
}

/* ═════════════════════════════════════════════════════════════════════════════
 * ARTICLE
 * ══════════════════════════════════════════════════════════════════════════ */
body.fc-ds .fc-crumbs {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-wrap: wrap;
	color: var(--fc-ink-a60);
}

body.fc-ds .fc-crumbs a {
	color: inherit;
}

body.fc-ds .fc-crumbs a:hover {
	color: var(--fc-ink-12);
}

body.fc-ds .fc-post__title {
	/* 24ch is the design's measure — a headline this size needs the wrap forced. */
	max-width: 24ch;
	margin: var(--sp-54) 0 0;
}

body.fc-ds .fc-post__lead {
	max-width: 62ch;
	margin: var(--sp-32) 0 0;
	font-size: var(--type-body-18);
	font-weight: var(--fw-medium);
	line-height: var(--lh-loose);
	color: var(--fc-ink-a80);
}

body.fc-ds .fc-post__meta {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-24);
	flex-wrap: wrap;
	margin-top: 40px;
	padding-top: 20px;
	border-top: var(--stroke-1) solid var(--fc-ink-a20);
}

body.fc-ds .fc-post__byline {
	display: flex;
	align-items: center;
	gap: var(--sp-8);
	flex-wrap: wrap;
	font-size: 14px;
	line-height: var(--lh-body);
	color: var(--fc-ink-a60);
}

body.fc-ds .fc-post__author {
	font-weight: var(--fw-semibold);
	color: var(--fc-ink-12);
}

body.fc-ds .fc-post__share {
	display: flex;
	align-items: center;
	gap: var(--sp-16);
}

body.fc-ds .fc-post__share a {
	display: inline-flex;
	color: var(--fc-ink-a60);
}

body.fc-ds .fc-post__share a:hover {
	color: var(--fc-ink-12);
}

/*
 * Head, hero and body are siblings in one section, so the rhythm between them is
 * margins. The 72 below the hero and the 72 above the body COLLAPSE to a single 72
 * when both are present, which is the point: a post with no featured image gets
 * the same space under its meta row as one with a hero gets under the image, with
 * no conditional class on the body.
 */
body.fc-ds .fc-post__hero {
	margin: var(--sp-72) 0;
}

/*
 * An ebook's hero is a link to its PDF. The wrapper takes the hero's margin and
 * the image gives it up, which is not cosmetic: an inline anchor does not collapse
 * margins with its siblings, so leaving the 72 on the image would stop it
 * collapsing against the body's 72 above and double the gap on ebooks only. A
 * block-level anchor collapses exactly as the bare image did, so the rule above
 * keeps describing what happens.
 */
body.fc-ds .fc-post__hero-link {
	display: block;
	margin: var(--sp-72) 0;
	/* The cover is the affordance; a text-decoration on an image is just a line. */
	text-decoration: none;
	border-radius: var(--radius-16);
}

body.fc-ds .fc-post__hero-link .fc-post__hero {
	margin: 0;
	transition: opacity var(--dur-fast) var(--ease-out);
}

body.fc-ds .fc-post__hero-link:hover .fc-post__hero {
	opacity: 0.92;
}

body.fc-ds .fc-post__hero-link:focus-visible {
	outline: 2px solid var(--fc-ink-12);
	outline-offset: 4px;
}

/* The hover still dims, it just arrives instantly rather than easing. */
@media ( prefers-reduced-motion: reduce ) {

	body.fc-ds .fc-post__hero-link .fc-post__hero {
		transition: none;
	}
}

body.fc-ds .fc-post__body {
	margin-top: var(--sp-72);
}

/* ── Prose ──
 * The site's paragraph size on a looser 1.65 leading, at weight 400 on an 80%-ink.
 * This is the only place on the site where someone reads a thousand words in one
 * go, so the leading opens up — but the size is the same one every other page sets
 * body copy at, and it now comes from the token rather than a number.
 *
 * It was 17px, hard-coded, which was ONE ABOVE the body size when this was written
 * and became one BELOW it when the reading size moved to 18 (see the READING SIZE
 * note in layout.css). That inverted the intent: an article was being set smaller
 * than the paragraphs on a landing page. Reading from --type-body-16 is what stops
 * that happening again the next time the scale is retuned.
 */
body.fc-ds .fc-prose {
	font-size: var(--type-body-16);
	font-weight: var(--fw-regular);
	line-height: 1.65;
	color: var(--fc-ink-a80);
	--sp-flow: var(--sp-32);
}

/*
 * In-article subheads are Instrument Sans SemiBold, NOT the display serif that
 * tokens.css gives every h2/h3. This is the design's call and it is right — the
 * serif is for statements, and a subhead inside an argument is a signpost. It
 * also keeps the article's one serif moment (the title) singular.
 */
body.fc-ds .fc-prose h2 {
	font-family: var(--font-core);
	font-weight: var(--fw-semibold);
	font-size: var(--type-title-32);
	line-height: 1.25;
	letter-spacing: var(--ls-display);
	color: var(--fc-ink-12);
	margin-top: 40px;
	text-wrap: pretty;
}

body.fc-ds .fc-prose h3 {
	font-family: var(--font-core);
	font-weight: var(--fw-semibold);
	font-size: var(--type-h5-24);
	line-height: var(--lh-snug);
	letter-spacing: normal;
	color: var(--fc-ink-12);
	text-wrap: pretty;
}

body.fc-ds .fc-prose h4 {
	font-family: var(--font-core);
	font-weight: var(--fw-semibold);
	font-size: var(--type-body-18);
	line-height: var(--lh-snug);
	color: var(--fc-ink-12);
}

body.fc-ds .fc-prose strong,
body.fc-ds .fc-prose b {
	font-weight: var(--fw-semibold);
	color: var(--fc-ink-12);
}

/*
 * Prose links carry the underline that tokens.css withholds from everything
 * else. 40% ink so it reads as texture at 17px, full ink on hover.
 */
body.fc-ds .fc-prose a,
body.fc-ds .fc-body-link {
	color: var(--fc-ink-12);
	border-bottom: var(--stroke-1) solid var(--fc-ink-a40);
}

body.fc-ds .fc-prose a:hover,
body.fc-ds .fc-body-link:hover {
	color: var(--fc-violet);
	border-bottom-color: var(--fc-violet);
}

body.fc-ds .fc-prose ul,
body.fc-ds .fc-prose ol {
	margin: 0;
	padding-left: 1.4em;
}

body.fc-ds .fc-prose li + li {
	margin-top: 12px;
}

body.fc-ds .fc-prose li::marker {
	color: var(--fc-ink-a40);
}

/* ── Pull quote ──
 * Fraunces between two hairlines. No quote marks, no violet bar, no italics —
 * the rules and the change of face are the whole device.
 */
body.fc-ds .fc-prose blockquote,
body.fc-ds .fc-prose .wp-block-quote,
body.fc-ds .fc-prose .wp-block-pullquote {
	margin: var(--sp-24) 0;
	padding: 40px 0;
	border-top: var(--stroke-1) solid var(--fc-ink-a20);
	border-bottom: var(--stroke-1) solid var(--fc-ink-a20);
	border-left: 0;
	background: none;
	text-align: left;
}

body.fc-ds .fc-prose blockquote p,
body.fc-ds .fc-prose .wp-block-pullquote p {
	font-family: var(--font-quote);
	font-weight: var(--fw-regular);
	font-size: var(--type-quote-32);
	line-height: var(--lh-snug);
	letter-spacing: var(--ls-quote);
	color: var(--fc-ink-12);
	text-wrap: pretty;
}

body.fc-ds .fc-prose blockquote p + p {
	margin-top: var(--sp-24);
}

body.fc-ds .fc-prose blockquote cite,
body.fc-ds .fc-prose blockquote .wp-block-quote__citation,
body.fc-ds .fc-prose .wp-block-pullquote__citation {
	display: block;
	margin-top: var(--sp-24);
	font-family: var(--font-label);
	font-style: normal;
	font-size: var(--type-label-12);
	font-weight: var(--fw-medium);
	line-height: 1.2;
	letter-spacing: var(--ls-label);
	text-transform: uppercase;
	color: var(--fc-ink-a60);
}

/* ── Stat grid ──
 * Three figures in Fraunces over hairline-topped columns.
 *
 * There is no custom block for this: add the CSS class `fc-stats` to a core
 * Columns block and put the figure in the first paragraph of each column, the
 * label in the second. That keeps it inside native Gutenberg — the site's
 * standard — and an editor who has never seen this file gets it right by
 * following the pattern in the column next door.
 */
body.fc-ds .fc-prose .fc-stats,
body.fc-ds .fc-stats {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: var(--sp-32);
	margin: var(--sp-24) 0;
}

@container page (max-width: 820px) {
	body.fc-ds .fc-prose .fc-stats,
	body.fc-ds .fc-stats {
		grid-template-columns: 1fr;
	}
}

body.fc-ds .fc-stat,
body.fc-ds .fc-stats > .wp-block-column {
	display: flex;
	flex-direction: column;
	gap: var(--sp-8);
	padding-top: var(--sp-24);
	border-top: var(--stroke-1) solid var(--fc-ink-a20);
	/* Columns inside a Columns block set their own flex-basis; release it. */
	flex-basis: auto !important;
}

body.fc-ds .fc-stat__value,
body.fc-ds .fc-stats > .wp-block-column > p:first-child {
	font-family: var(--font-quote);
	font-weight: var(--fw-regular);
	font-size: var(--type-numeral-48);
	line-height: var(--lh-flush);
	letter-spacing: var(--ls-quote);
	font-variant-numeric: tabular-nums;
	color: var(--fc-ink-12);
}

body.fc-ds .fc-stat__label,
body.fc-ds .fc-stats > .wp-block-column > p:last-child {
	font-family: var(--font-label);
	font-size: var(--type-label-12);
	font-weight: var(--fw-medium);
	line-height: 1.2;
	letter-spacing: var(--ls-label);
	text-transform: uppercase;
	color: var(--fc-ink-a60);
}

/* A one-paragraph column is a figure with no label, not a label. */
body.fc-ds .fc-stats > .wp-block-column > p:first-child:last-child {
	font-family: var(--font-quote);
	font-size: var(--type-numeral-48);
	text-transform: none;
	letter-spacing: var(--ls-quote);
}

/* ── Block-editor output the article has to absorb ── */

body.fc-ds .fc-prose figure {
	margin: 0;
}

body.fc-ds .fc-prose img {
	display: block;
	width: 100%;
	height: auto;
}

body.fc-ds .fc-prose figcaption {
	margin-top: 12px;
	font-family: var(--font-label);
	font-size: var(--type-label-12);
	font-weight: var(--fw-medium);
	letter-spacing: var(--ls-label);
	text-transform: uppercase;
	color: var(--fc-ink-a60);
}

/*
 * A wide or full-width image inside a 68ch measure has to escape it. Negative
 * margins are the only way out of a max-width column without restructuring the
 * markup, and they are safe here because .fc-page clips the x overflow.
 */
body.fc-ds .fc-prose .alignwide,
body.fc-ds .fc-prose .alignfull {
	width: calc(100% + 2 * var(--sp-54));
	max-width: none;
	margin-left: calc(-1 * var(--sp-54));
	margin-right: calc(-1 * var(--sp-54));
}

@container page (max-width: 820px) {
	body.fc-ds .fc-prose .alignwide,
	body.fc-ds .fc-prose .alignfull {
		width: 100%;
		margin-left: 0;
		margin-right: 0;
	}
}

body.fc-ds .fc-prose hr,
body.fc-ds .fc-prose .wp-block-separator {
	height: 0;
	margin: var(--sp-54) 0;
	border: 0;
	border-top: var(--stroke-1) solid var(--fc-ink-a20);
}

/* Code is a machine string, so it takes the mono face by right, not for effect. */
body.fc-ds .fc-prose code,
body.fc-ds .fc-prose kbd,
body.fc-ds .fc-prose samp {
	font-family: var(--font-mono);
	font-size: 0.875em;
	letter-spacing: var(--ls-mono);
	font-variant-ligatures: none;
}

body.fc-ds .fc-prose pre {
	margin: 0;
	padding: var(--sp-24);
	overflow-x: auto;
	background: var(--fc-white);
	border: var(--stroke-1) solid var(--fc-ink-a20);
	font-family: var(--font-mono);
	font-size: var(--type-mono-14);
	line-height: var(--lh-loose);
	color: var(--fc-ink-12);
}

body.fc-ds .fc-prose table {
	width: 100%;
	border-collapse: collapse;
	/* A step down from the prose around it — the table step of the scale. */
	font-size: var(--type-body-15);
}

body.fc-ds .fc-prose th,
body.fc-ds .fc-prose td {
	padding: 12px 0;
	text-align: left;
	border-bottom: var(--stroke-1) solid var(--fc-ink-a20);
}

body.fc-ds .fc-prose th {
	font-family: var(--font-label);
	font-size: var(--type-label-12);
	font-weight: var(--fw-medium);
	letter-spacing: var(--ls-label);
	text-transform: uppercase;
	color: var(--fc-ink-a60);
}

/* Embeds keep their aspect ratio without the usual padding-hack wrapper. */
body.fc-ds .fc-prose iframe {
	display: block;
	width: 100%;
	aspect-ratio: 16 / 9;
	height: auto;
	border: 0;
}

/* ── Related ── */
body.fc-ds .fc-related__title {
	margin: 0;
}

body.fc-ds .fc-related__grid {
	margin-top: var(--sp-54);
	column-gap: var(--sp-54);
	row-gap: var(--sp-72);
}

/*
 * BLOCK — CROSSLINK moved to layout.css when the contact page arrived. It was here
 * because a blog post was the only thing that ended with one; the contact page ends
 * with one too, and that page loads pages.css instead of this file, so the block had
 * to become a primitive or be duplicated. layout.css's own test for what belongs in
 * it — "whether a third page could plausibly use it" — is now answered.
 */

/*
 * BLOCK — EMAIL CTA moved to layout.css when the Integrations page arrived. Same
 * story as the crosslink above it: a post and a listing end with one, and so does a
 * composed page that loads pages.css instead of this file. Its six copy variants and
 * its two tones — the block is now light OR ink — are documented there.
 */
