/*
 * Foodyx home — Exploded Assembly.
 *
 * One continuous spine runs the page. Through the system section that spine
 * becomes POSHUB: the backbone the eight modules attach to, and the same
 * backbone the external integrations attach to. The relationship is drawn, not
 * asserted in a sentence.
 *
 * Every value here is a theme.json token. Mobile-first: the 360px case is the
 * unconditional default, widened with min-width only.
 */

.fx-page {
	--fx-rail: var(--wp--preset--spacing--60);
	--fx-wide: 76rem;
	--fx-hairline: var(--wp--custom--border--hairline);
	--fx-connector: var(--wp--custom--border--connector);

	position: relative;
	padding-left: var(--fx-rail);
}

/*
 * The page rail. Quiet and structural, and it begins BELOW the hero: the hero
 * is not part of the assembly system and carries none of its language.
 */
.fx-rail {
	position: relative;
}

.fx-rail::before {
	content: "";
	position: absolute;
	inset-block: 0;
	left: calc(-1 * var(--fx-rail));
	width: var(--fx-hairline);
	background-color: var(--wp--preset--color--connector);
}

/* ---- Hero --------------------------------------------------------------- */

/*
 * The supplied hero visual, used as-is, with the proposition set over its light
 * left side. Nothing is composited here.
 *
 * On phones the overlay is abandoned — the copy would sit on a 320px-wide photo
 * and lose both legibility and the image. Copy first, image beneath.
 */
.fx-hero {
	position: relative;
	margin-block-start: var(--wp--preset--spacing--70);
	margin-inline-start: calc(-1 * var(--fx-rail));
}

.fx-hero__bg {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--wp--custom--radius--md);
	order: 2;
}

.fx-eyebrow {
	margin: 0 0 var(--wp--preset--spacing--30);
	color: var(--wp--preset--color--ink-muted);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.4;
}

.fx-hero h1 {
	margin: 0;
	max-width: 20ch;
	font-size: var(--wp--preset--font-size--display-sm);
	text-wrap: balance;
}

.fx-lede {
	margin-block-start: var(--wp--preset--spacing--50);
	max-width: 46ch;
	line-height: 1.55;
}

.fx-actions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--wp--preset--spacing--40);
	margin-block-start: var(--wp--preset--spacing--60);
}

/* Phone: stack, copy first. */
.fx-hero {
	display: flex;
	flex-direction: column;
}

.fx-hero__text {
	order: 1;
	margin-block-end: var(--wp--preset--spacing--70);
	padding-inline-start: var(--fx-rail);
}

/* Core buttons carry theme.json's button element styles. */
.wp-block-button__link {
	display: inline-flex;
	align-items: center;
	min-height: 44px;
}

/* The theme.json token, not the .fx-page alias: these buttons also appear in
   the closing band, which sits outside .fx-page. */
.wp-block-button.is-style-outline > .wp-block-button__link {
	border-width: var(--wp--custom--border--hairline);
	border-color: var(--wp--preset--color--connector);
	color: var(--wp--preset--color--ink);
}

.wp-block-button.is-style-outline > .wp-block-button__link:hover,
.wp-block-button.is-style-outline > .wp-block-button__link:focus-visible {
	border-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--accent-strong);
	background-color: transparent;
}

/* ---- The system: POSHUB as backbone ------------------------------------ */

/*
 * Through this section the spine thickens and goes to accent. That line IS
 * POSHUB: the modules attach to it, and so do the external integrations. The
 * petrol is spent here because connection is exactly what it is for.
 */
/*
 * Through this section the spine thickens and goes to accent. That line IS
 * POSHUB: the modules attach to it, and so do the external integrations. It
 * starts here, below the hero, and stops where the integrations end.
 */
/*
 * THE CHAPTER BREAK. This was a margin, and it silently collapsed out through
 * .fx-rail: 96px of intended separation arrived on the page as 24px, and the
 * products read as an appendix to the hero. It is padding now, which cannot
 * collapse, so the gap is the value written here.
 */
.fx-system {
	--fx-chapter: var(--wp--preset--spacing--90);

	position: relative;
	margin-block-start: 0;
	padding-block-start: var(--fx-chapter);
}

/*
 * The petrol backbone starts WITH the chapter, not above it. Running it up
 * through the break would tie the hero and the products together with a line
 * and undo the separation the padding just bought. The grey page spine still
 * crosses the gap — that is the quiet continuity, and it is meant to.
 */
.fx-system::before {
	content: "";
	position: absolute;
	inset-block: calc(var(--fx-chapter) + 0.6em) 0;
	left: calc(-1 * var(--fx-rail));
	width: var(--fx-connector);
	background-color: var(--wp--preset--color--accent);
}

/* Anything attached to the backbone draws its own join. */
.fx-assembly,
.fx-hub,
.fx-integrations {
	position: relative;
}

/*
 * The eight products join POSHUB on a single connector, not eight of them. One
 * tick says "this whole selection sits on the backbone"; eight ticks would
 * reach only the left column and would re-scatter a grid built to read as one
 * thing. Same idiom as the integrations join below.
 */
.fx-assembly {
	margin-block-start: 0;
}

.fx-assembly::before {
	content: "";
	position: absolute;
	top: 0.6em;
	left: calc(-1 * var(--fx-rail));
	width: var(--fx-rail);
	height: var(--fx-hairline);
	background-color: var(--wp--preset--color--accent);
}

.fx-hub,
.fx-integrations {
	margin-block-start: var(--wp--preset--spacing--90);
}

/* On phones h1 and h2 would otherwise both be display-sm: no step at all. */
.fx-section-title,
.fx-hub h2 {
	margin: 0 0 var(--wp--preset--spacing--60);
	font-size: var(--wp--preset--font-size--xl);
}

/* ---- Highlighted products ---------------------------------------------- */

/*
 * FROZEN — approved 18 September 2026. See patterns/home-products.php for what
 * the freeze covers. The chapter break that belongs to this section lives up in
 * .fx-system and is frozen with it.
 */

/*
 * A HIGHLIGHTED SELECTION of eight, laid out as a portfolio rather than a
 * table. The earlier version ruled every cell on all four sides and read as
 * documentation; the lines are now hairline-soft, horizontal only, and there is
 * no vertical divider at all. What separates the products is whitespace.
 *
 * Mobile-first: one column is the unconditional default. Two columns at 48rem,
 * four at 80rem — and at four the cell restacks, icon above the name, because a
 * 272px column has no room for an icon beside the text.
 */
.fx-assembly .fx-section-title {
	margin-block-end: var(--wp--preset--spacing--40);
}

/*
 * The intro sits close to the grid on purpose. The chapter break above the
 * heading is what separates this section from the hero; repeating that distance
 * inside the section only pushes the heading away from the products it
 * introduces. One value at every width — the 48rem step-up to spacing-80 was
 * removed, which is the 16px this gap lost.
 */
.fx-section-intro {
	margin: 0 0 var(--wp--preset--spacing--70);
	max-width: 58ch;
	color: var(--wp--preset--color--ink-muted);
	line-height: 1.55;
}

.fx-products {
	display: grid;
	border-block-end: var(--fx-hairline) solid var(--wp--custom--surface--rule-soft);
}

/*
 * Phone and tablet: the icon sits beside the text and spans it, which keeps the
 * row compact. The areas exist so four columns can restack the same markup.
 */
.fx-product {
	display: grid;
	grid-template-columns: var(--wp--custom--size--icon-field) minmax(0, 1fr);
	grid-template-areas:
		"icon num"
		"icon name"
		"icon what";
	column-gap: var(--wp--preset--spacing--50);
	align-content: start;
	padding-block: var(--wp--preset--spacing--50);
	border-block-start: var(--fx-hairline) solid var(--wp--custom--surface--rule-soft);
}

/*
 * The icon carries the scan, so it gets a field of its own: a petrol tint
 * rather than a border, which would read as one more box on a page already
 * full of rules. Accent on the tint measures 5.6:1.
 */
.fx-product__icon {
	grid-area: icon;
	align-self: start;
	display: grid;
	place-items: center;
	width: var(--wp--custom--size--icon-field);
	height: var(--wp--custom--size--icon-field);
	border-radius: var(--wp--custom--radius--sm);
	background-color: var(--wp--custom--surface--accent-soft);
	color: var(--wp--preset--color--accent);
}

/*
 * The set is drawn on a 24px grid at stroke 1.8. At 52px that stroke renders
 * near 4px and the icons go blobby, so it is thinned here to hold the same
 * optical weight at twice the size. The SVGs themselves are untouched.
 */
.fx-product__icon svg {
	display: block;
	width: var(--wp--custom--size--icon);
	height: var(--wp--custom--size--icon);
	stroke-width: 1.15;
}

.fx-product__num {
	grid-area: num;
	margin: 0;
	color: var(--wp--preset--color--ink-muted);
	font-size: var(--wp--preset--font-size--xs);
	font-variant-numeric: tabular-nums slashed-zero;
	line-height: 1.2;
}

.fx-product__name {
	grid-area: name;
	margin: var(--wp--preset--spacing--20) 0 0;
	font-size: var(--wp--preset--font-size--lg);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.2;
}

.fx-product__what {
	grid-area: what;
	margin: var(--wp--preset--spacing--30) 0 0;
	max-width: 34ch;
	color: var(--wp--preset--color--ink-muted);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
}

/* ---- POSHUB node ------------------------------------------------------- */

/*
 * No rail tick and no POSHUB chip here any more: the supplied ecosystem diagram
 * carries the relationship, and repeating it in the page's own backbone idiom
 * would state the same thing twice in two different visual languages.
 *
 * The diagram sits on the page, not in a card: no border, no shadow, and the
 * section carries no visible heading because the image already has one.
 */
.fx-hub__diagram {
	margin: var(--wp--preset--spacing--80) 0 0;
	line-height: 0;
}

/*
 * On phones the diagram escapes both the rail indent and the page gutter. It is
 * a wide schematic: every pixel of width is legibility, and the brief is
 * explicit that a full-width scaled image beats cropping the relationships.
 */
.fx-hub__diagram {
	margin-inline-start: calc(-1 * (var(--fx-rail) + var(--wp--custom--gutter--sm)));
	margin-inline-end: calc(-1 * var(--wp--custom--gutter--sm));
}

.fx-hub__diagram img {
	display: block;
	width: 100%;
	height: auto;
}

@media (min-width: 48rem) {
	.fx-hub__diagram {
		margin-inline: 0;
	}

	.fx-hub__diagram img {
		border-radius: var(--wp--custom--radius--md);
	}
}

.fx-hub p {
	margin: var(--wp--preset--spacing--50) 0 0;
	max-width: var(--wp--custom--measure);
}

/* ---- Integrations ------------------------------------------------------ */

.fx-integrations::before {
	content: "";
	position: absolute;
	top: 0.6em;
	left: calc(-1 * var(--fx-rail));
	width: var(--fx-rail);
	height: var(--fx-hairline);
	background-color: var(--wp--preset--color--accent);
}

.fx-integrations > p {
	max-width: var(--wp--custom--measure);
}

.fx-groups {
	display: grid;
	gap: var(--wp--preset--spacing--60);
	margin: var(--wp--preset--spacing--70) 0 0;
	padding: 0;
	list-style: none;
}

/*
 * Each group attaches to the same backbone the modules use: external systems
 * meeting the platform at the same layer. Names are text, never logos.
 */
.fx-group {
	position: relative;
	padding-left: var(--wp--preset--spacing--50);
	border-left: var(--fx-hairline) solid var(--wp--preset--color--connector);
}

/* The category is the point of this section, so it carries more weight than
   the partner names beneath it. */
.fx-group__name {
	margin: 0;
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--base);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.3;
}

.fx-group__items {
	display: grid;
	gap: var(--wp--preset--spacing--50);
	margin: var(--wp--preset--spacing--50) 0 0;
	padding: 0;
	list-style: none;
}

/*
 * The partner is a name with a supporting mark, not a logo tile. The logo is
 * decorative here because the name beside it already carries the meaning, so it
 * takes an empty alt rather than repeating the text to a screen reader.
 */
.fx-partner {
	display: flex;
	align-items: center;
	gap: var(--wp--preset--spacing--40);
}

.fx-partner__logo {
	flex: 0 0 auto;
	width: var(--wp--custom--size--badge);
	height: var(--wp--custom--size--badge);
	border-radius: 50%;
}

.fx-partner__name {
	color: var(--wp--preset--color--ink);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.4;
}

/* ---- Prose passages ---------------------------------------------------- */

.fx-node {
	position: relative;
	margin-block-start: var(--wp--preset--spacing--100);
}

.fx-node::before {
	content: "";
	position: absolute;
	top: 0.75em;
	left: calc(-1 * var(--fx-rail));
	width: var(--fx-rail);
	height: var(--fx-hairline);
	background-color: var(--wp--preset--color--connector);
}

.fx-prose p {
	margin: var(--wp--preset--spacing--50) 0 0;
	max-width: var(--wp--custom--measure);
}

/* ---- Close ------------------------------------------------------------- */

/*
 * The closing band. A full-bleed zone rather than a card: it sits edge to edge
 * directly above the dark footer, so the page ends on two stacked bands instead
 * of trailing off into the page ground. The tint is a 4% petrol wash — enough
 * to separate the zone, far short of a colour field. No gradient, no shadow,
 * no border.
 *
 * The section lives outside .fx-page for this; see patterns/home.php.
 */
.fx-close {
	margin-block-start: var(--wp--preset--spacing--110);
	padding-block: var(--wp--preset--spacing--100);
	background-color: var(--wp--custom--surface--accent-wash);
}

/*
 * The band ends where the footer begins. The footer carries its own top margin
 * of spacing-110, which was invisible while this section sat on the page ground
 * and became a pale stripe between two bands the moment it got a background.
 * Cancelling it here keeps the footer's own rules untouched — the frozen CSS is
 * not edited — while letting the page close on tint straight into dark.
 */
/*
 * Two class selectors on purpose. WordPress's constrained-layout CSS ships
 * `.wp-block-group-is-layout-constrained > :last-child { margin-block-end: 0 }`
 * at two-class specificity, and this section is the last child of <main>. A
 * single `.fx-close` loses to it and the margin silently computes to 0.
 */
.fx-close.alignfull {
	margin-block-end: calc(-1 * var(--wp--preset--spacing--110));
}

/*
 * The band is full-bleed; its CONTENT is not. The inner box carries the same
 * 76rem column and the same rail indent the rest of the page uses, so the
 * closing copy starts on the exact left edge every section heading above it
 * starts on. WordPress's constrained layout would centre these blocks instead,
 * which floats them against a page that is left-aligned throughout.
 *
 * The rail value is repeated here rather than inherited: --fx-rail belongs to
 * .fx-page, and this section deliberately sits outside it.
 */
.fx-close__inner {
	max-width: var(--fx-wide, 76rem);
	margin-inline: auto;
	padding-inline-start: var(--wp--preset--spacing--60);
}

/*
 * Hierarchy is the whole job here. The demo gets the display heading, the lede
 * measure and the only filled button; the mailing list gets a smaller step, a
 * narrower measure and no filled control at all. Both share one left edge, so
 * the second reads as an afterword to the first rather than as a rival offer.
 */
.fx-close__demo {
	max-width: 38rem;
}

.fx-close__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--xl);
	text-wrap: balance;
}

.fx-close__body {
	margin: var(--wp--preset--spacing--50) 0 0;
	max-width: 52ch;
	line-height: 1.55;
}

/* The tertiary action sits under the button row, not in it — a third button in
   that row would read as a third equal offer. */
.fx-close__wa {
	margin: var(--wp--preset--spacing--50) 0 0;
	max-width: none;
}

/* ---- Mailing list ------------------------------------------------------ */

/*
 * A divider and a lot of air, not a box. A card here would make the signup a
 * peer of the demo, which is exactly what it must not be.
 */
.fx-signup {
	max-width: 38rem;
	margin-block-start: var(--wp--preset--spacing--90);
	padding-block-start: var(--wp--preset--spacing--80);
	border-block-start: var(--wp--custom--border--hairline) solid var(--wp--preset--color--rule);
}

.fx-signup__title {
	margin: 0;
	font-size: var(--wp--preset--font-size--md);
	font-weight: 700;
	letter-spacing: -0.01em;
	line-height: 1.3;
}

.fx-signup__body {
	margin: var(--wp--preset--spacing--30) 0 0;
	max-width: 48ch;
	color: var(--wp--preset--color--ink-muted);
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
}

/* Phone: the field and the button each take the full width, stacked. */
.fx-signup__form {
	display: grid;
	gap: var(--wp--preset--spacing--40);
	margin-block-start: var(--wp--preset--spacing--50);
}

/*
 * The honeypot. Taken out of the layout, out of sight and out of the tab order,
 * but NOT display:none — some bots skip fields a browser would not render, and
 * the point of the field is that a bot fills it in.
 */
.fx-signup__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	margin: 0;
	overflow: hidden;
}

.fx-signup__input {
	min-height: 44px;
	padding: 0 var(--wp--preset--spacing--50);
	border: var(--wp--custom--border--hairline) solid var(--wp--preset--color--rule);
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--field);
	color: var(--wp--preset--color--ink);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--sm);
}

.fx-signup__input::placeholder {
	color: var(--wp--preset--color--ink-muted);
	opacity: 1;
}

/*
 * The submit is outline, never filled. One filled button in this band, and it
 * belongs to the demo.
 */
.fx-signup__submit {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 0 var(--wp--preset--spacing--60);
	border: var(--wp--custom--border--hairline) solid var(--wp--preset--color--connector);
	border-radius: var(--wp--custom--radius--md);
	background-color: transparent;
	color: var(--wp--preset--color--ink);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--sm);
	font-weight: 700;
	line-height: 1;
}

.fx-signup__note {
	margin: var(--wp--preset--spacing--40) 0 0;
	color: var(--wp--preset--color--ink-muted);
	font-size: var(--wp--preset--font-size--xs);
	line-height: 1.4;
}

/* ---- Signup states ----------------------------------------------------- */

/*
 * The `hidden` attribute is only `display: none` at user-agent level, so any
 * author `display` beats it — and .fx-signup__form is `display: grid`. Without
 * this the form stays on screen underneath the success message, on both the
 * fetch path and the no-JavaScript one.
 */
.fx-signup [hidden] {
	display: none;
}

/*
 * In flight. The cursor and the dimmed control say "working" without the
 * layout moving: the label swaps to an equal-width word, so nothing below the
 * form jumps while the request is out.
 */
.fx-signup__form[aria-busy="true"] .fx-signup__submit {
	opacity: 0.6;
	cursor: progress;
}

.fx-signup__input[aria-invalid="true"] {
	border-color: var(--wp--preset--color--accent-strong);
}

.fx-signup__status {
	margin-block-start: var(--wp--preset--spacing--50);
}

.fx-signup__status:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

.fx-signup__status p {
	margin: 0;
	max-width: 48ch;
	font-size: var(--wp--preset--font-size--sm);
	line-height: 1.5;
}

/*
 * Success is the one place petrol is spent in this block. It is a confirmation,
 * not a decoration, and the accent is what tells a scanning eye the state
 * changed. accent-strong on the wash measures 8.2:1.
 */
.fx-signup__ok {
	color: var(--wp--preset--color--accent-strong);
}

.fx-signup__ok strong {
	display: block;
	font-size: var(--wp--preset--font-size--md);
	letter-spacing: -0.01em;
}

/* Ink, not red: the palette has no error colour and inventing one here would
   put a value on the page that theme.json does not own. */
.fx-signup__err {
	color: var(--wp--preset--color--ink);
	font-weight: 700;
}

/* ---- Widening: tablet -------------------------------------------------- */

@media (min-width: 48rem) {
	.fx-page {
		--fx-rail: var(--wp--preset--spacing--70);
	}

	.fx-lede {
		font-size: var(--wp--preset--font-size--md);
	}

	.fx-section-title,
	.fx-hub h2,
	.fx-close__title {
		font-size: var(--wp--preset--font-size--display-sm);
	}

	.fx-close {
		padding-block: var(--wp--preset--spacing--110);
	}

	.fx-close__inner {
		padding-inline-start: var(--wp--preset--spacing--70);
	}

	/* Field and submit share a row, the field taking the slack. */
	.fx-signup__form {
		grid-template-columns: minmax(0, 1fr) auto;
		align-items: center;
	}

	.fx-system {
		margin-block-start: var(--wp--preset--spacing--100);
	}

	.fx-system {
		--fx-chapter: var(--wp--preset--spacing--100);
	}

	/*
	 * Two columns, four rows. The centre divider is gone — two axes of rules
	 * were most of what made this read as a spec table.
	 *
	 * The columns are separated by padding inside the cells, never by a column
	 * gap. A gap would break each row's hairline into one dash per column, and
	 * a dashed rule reads as a rendering fault rather than a separator.
	 */
	.fx-products {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}

	.fx-product {
		padding-block: var(--wp--preset--spacing--70);
		padding-inline-end: var(--wp--preset--spacing--80);
	}

	/* Exactly three: auto-fit was creating a fourth, empty track. */
	.fx-groups {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		max-width: 46rem;
	}
}

/* ---- Widening: laptop -------------------------------------------------- */

/*
 * The intermediate step. Without it a 1920px row stretches a number, a name and
 * one line of text across the full measure with dead gap between them.
 */
@media (min-width: 64rem) {
	/* The proposition sits over the visual's light left side, as supplied. */
	.fx-hero {
		display: block;
		margin-block-start: var(--wp--preset--spacing--100);
	}

	/*
	 * Legibility scrim. DESIGN.md's single gradient exception: the counter area
	 * behind the copy dips to a luminance where ink measures about 3.5:1, and a
	 * scrim is the sanctioned remedy rather than moving the copy off the art.
	 */
	.fx-hero::after {
		content: "";
		position: absolute;
		inset: 0;
		border-radius: var(--wp--custom--radius--md);
		background: linear-gradient(
			to right,
			rgb(247 247 245 / 0.94) 0%,
			rgb(247 247 245 / 0.86) 26%,
			rgb(247 247 245 / 0.35) 44%,
			rgb(247 247 245 / 0) 56%
		);
		pointer-events: none;
	}

	.fx-hero__text {
		position: absolute;
		z-index: 1;
		inset-block: 0;
		left: 0;
		display: flex;
		flex-direction: column;
		justify-content: center;
		width: 46%;
		margin-block-end: 0;
		padding-inline: var(--wp--preset--spacing--80);
	}

	.fx-hero h1 {
		font-size: var(--wp--preset--font-size--display);
		max-width: 15ch;
	}

	.fx-products,
	.fx-section-intro,
	.fx-integrations > p,
	.fx-hub p {
		max-width: 58rem;
	}

	.fx-groups {
		max-width: 58rem;
	}
}

/* ---- Widening: wide desktop -------------------------------------------- */

/*
 * Four columns, two rows. At 272px a column cannot hold an icon beside the
 * text, so the cell restacks: the icon leads, the name follows it, and the
 * eight read as a portfolio you scan across rather than a list you read down.
 */
@media (min-width: 80rem) {
	.fx-products {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		max-width: 68rem;
	}

	.fx-product {
		grid-template-columns: minmax(0, 1fr);
		grid-template-areas:
			"icon"
			"num"
			"name"
			"what";
		padding-block: var(--wp--preset--spacing--80);
		padding-inline-end: var(--wp--preset--spacing--70);
	}

	.fx-product__icon {
		margin-block-end: var(--wp--preset--spacing--50);
	}

	.fx-product__what {
		max-width: none;
	}
}

/* ---- Motion ------------------------------------------------------------ */

/*
 * One authored moment: each section's connector draws itself into the POSHUB
 * backbone as that section enters view, so the gesture happens where it is read
 * rather than completing off-screen. Two connectors now, not nine — the eight
 * per-module ticks went with the card layout they belonged to.
 */
@media (prefers-reduced-motion: no-preference) {
	@supports (animation-timeline: view()) {
		.fx-assembly::before,
		.fx-integrations::before {
			animation: fx-draw linear both;
			animation-timeline: view();
			animation-range: entry 10% entry 55%;
		}
	}

	/* Browsers without scroll-driven animation keep a single entrance. */
	@supports not (animation-timeline: view()) {
		.fx-assembly::before {
			animation: fx-draw var(--wp--custom--motion--base) var(--wp--custom--motion--ease) backwards;
		}
	}

	@keyframes fx-draw {
		from {
			transform: scaleX(0);
		}

		to {
			transform: scaleX(1);
		}
	}
}
