/*
 * Elementor bridge — the least CSS that lets an Elementor container sit inside
 * the Foodyx page grid, and lets the theme own everything else.
 *
 * WHY THIS FILE EXISTS. The theme's page rhythm comes from templates/*.html and
 * .fx-page in home.css: <main> carries a page gutter, and section content is
 * inset again by a connector rail whose hairline sticks out into that inset.
 * An Elementor container on templates/template-elementor.html is full-bleed and
 * inherits neither.
 *
 * WHAT IT DELIBERATELY DOES NOT DO: restate layout.
 *
 * An earlier version of this file declared `display: flex` on .fx-hero,
 * .fx-actions, .fx-partner and friends "to win against Elementor" — and because
 * `.fx-elementor-section .fx-hero` is two classes, it beat home.css's OWN media
 * queries. That broke the desktop hero (which is `display: block` from 64rem,
 * with the text absolutely positioned over the image), stacked both CTA rows,
 * and stacked every partner logo above its label.
 *
 * The load order makes all of it unnecessary. home.css is enqueued AFTER
 * Elementor's stylesheet and after Elementor's per-page CSS, so on equal
 * specificity the theme already wins:
 *
 *   custom-frontend.min.css -> post-<id>.css -> style.css -> home.css -> THIS
 *
 * So this file touches layout in exactly one place: the two custom properties
 * Elementor reads for defaults that home.css never declares, and therefore
 * cannot override.
 *
 * SCOPE. Loaded only on pages actually built with Elementor — see
 * foodyx_is_elementor_page(). A theme-rendered route never requests it.
 *
 * TRANSITIONAL. The homepage patterns remain the production fallback until the
 * Elementor build is approved.
 */

/* ---- The section wrapper ------------------------------------------------ */

/*
 * One class per Elementor section container. It owns the page gutter and the
 * rail inset; the boxed inner owns the content width, so a boxed container set
 * to 76rem lands content at 1184px exactly as .fx-rail does.
 *
 * TWO GUTTERS, NOT ONE. They are equal from 48rem up and differ below it, which
 * is exactly how you get this wrong:
 *
 *   --fx-gutter   the page gutter <main> carries      20px -> 32px at 48rem
 *   --fx-rail     the connector inset and hairline    24px -> 32px at 48rem
 *
 * Using one value for both costs 8px of content width on phones only, so
 * desktop and tablet still look perfect and a visual check passes it.
 */
.fx-elementor-section {
	--fx-gutter: var(--wp--custom--gutter--sm);
	--fx-rail: var(--wp--preset--spacing--60);
}

/*
 * Two classes, not one. Elementor's `.e-con { padding-inline-start:
 * var(--padding-left) }` is one class too, and custom-frontend.min.css does
 * NOT reliably print before this file: after an Elementor CSS cache flush it
 * printed after it, and the gutter computed to 0 at 360px on every page but
 * the homepage — copy flush against the screen edge. Specificity settles it
 * whatever the order.
 */
.elementor .fx-elementor-section {
	padding-inline: var(--fx-gutter);
}

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

/*
 * The rail inset goes on the BOXED inner element, not the full-bleed outer one.
 * Elementor puts a container's own padding on the outer .e-con, where a left
 * inset is invisible and the hairline would land at the viewport edge.
 */
.elementor .fx-elementor-section > .e-con-inner {
	position: relative;
	padding-inline-start: var(--fx-rail);
}

/* ---- The connector hairline --------------------------------------------- */

/*
 * .fx-node::before, opt-in. Not every section carries a rail, so this is a
 * modifier rather than part of the base class. Elementor has no control for a
 * pseudo-element, which is the whole reason this cannot live in the editor.
 */
.fx-elementor-section--rail > .e-con-inner::before {
	content: "";
	position: absolute;
	top: 0.75em;
	inset-inline-start: 0;
	width: var(--fx-rail);
	height: var(--wp--custom--border--hairline);
	background-color: var(--wp--preset--color--connector);
}

/* ---- Page rhythm: the edges the theme's layout owns --------------------- */

/*
 * WHAT WORDPRESS DOES FOR A PATTERN AND NOT FOR A DOCUMENT.
 *
 * Every theme page puts its first band inside a wp-block-group, and WordPress
 * ships `.wp-block-group-is-layout-* > :first-child { margin-block-start: 0 }`
 * at two classes. So `.fx-hero`'s 96px, `.fx-ab`'s and `.fx-ip`'s and
 * `.fx-pp`'s 48px and `.fx-contact`'s 64px are all cancelled on production and
 * the page opens on <main>'s own 24px, identically on all five pages.
 *
 * An Elementor document has no such ancestor, so each of those margins landed
 * on top of the 24px instead. That is the whole of the "too much whitespace
 * above the hero": 24 + 96 = 120 against 24, and the same fault sat on the
 * other four pages at their own values, unmeasured.
 *
 * Restating WordPress's own rule for the document's first band fixes all five
 * at once, and keeps on fixing them if a band's leading margin is ever
 * retuned — nothing here repeats a value.
 */
.elementor .fx-elementor-section:first-child > .e-con-inner > :first-child {
	margin-block-start: 0;
}

/*
 * The mirror image at the bottom, and only for the band that closes on tint.
 *
 * `.fx-close.alignfull` in home.css cancels the footer's own spacing-110 top
 * margin so the page ends tint-into-dark with no pale stripe between the two
 * bands. That rule needs `.alignfull`, which is a block-editor class an
 * Elementor section never carries, so the cancellation was simply absent and
 * the footer's 128px landed on top of the band's own bottom padding.
 *
 * Restated on the section instead. The negative margin collapses out through
 * .elementor and <main> exactly as it does out of <main> on production.
 *
 * NOT keyed on the last section. Contact also ends on a full-bleed tinted band
 * — .fx-wastrip — and production keeps the footer's 128px there; measured, not
 * assumed. Only .fx-close closes the page on tint.
 */
.elementor .fx-elementor-section.fx-close {
	margin-block-end: calc(-1 * var(--wp--preset--spacing--110));
}

/*
 * THE CHAPTER BREAK, as a section modifier.
 *
 * home.css hangs it on `.fx-system`, the wrapper around the products, POSHUB
 * and integrations sections, as padding rather than margin — see the comment
 * there about 96px of intended separation arriving as 24px once it collapsed
 * out through `.fx-rail`. The Elementor document has no `.fx-system`, so the
 * products section sat straight under the hero with nothing between them:
 * 0px against production's 120px, at every width from 768 up.
 *
 * Padding here too, for the same reason. The two parts are the two the theme
 * spends: <main>'s blockGap before the chapter, then the chapter itself.
 *
 * A modifier, not a rule keyed on `.fx-products`, so a later page can open a
 * chapter without owning the homepage's grid. Same family as --rail, --flush
 * and --bleed.
 */
.elementor .fx-elementor-section--chapter {
	--fx-chapter: var(--wp--preset--spacing--90);

	padding-block-start: calc(var(--wp--preset--spacing--60) + var(--fx-chapter));
}

@media (min-width: 48rem) {
	.elementor .fx-elementor-section--chapter {
		--fx-chapter: var(--wp--preset--spacing--100);
	}
}

/*
 * A prose node's own leading space, so the document does not have to carry it.
 *
 * `.fx-node` in home.css is `margin-block-start: spacing-100` plus the
 * connector hairline, and --rail already draws the hairline. Carrying the
 * margin here too retires the one hand-typed offset in the homepage document,
 * where it was a bare "96" with nothing to say which token it stood for.
 */
.elementor .fx-elementor-section--rail {
	margin-block-start: var(--wp--preset--spacing--100);
}

/* ---- Wrapper neutralisation -------------------------------------------- */

/*
 * THE ONE IDEA THAT MAKES NATIVE SECTIONS POSSIBLE.
 *
 * The theme lays its sections out with direct-child relationships:
 * .fx-product places four children with grid-template-areas, .fx-hero__bg and
 * .fx-hero__text carry flex order, .fx-partner is a flex row. Elementor wraps
 * every widget in .elementor-widget > .elementor-widget-container, so those
 * wrappers become the grid items and the placement lands on nothing.
 *
 * display:contents removes the wrapper BOX while keeping its children in the
 * tree, so .fx-product__icon and friends become direct children of the grid
 * again and every existing rule in home.css applies unchanged. home.css is NOT
 * edited, so the products grid frozen on 18 September 2026 keeps the exact
 * markup contract it was approved with.
 *
 * .elementor-widget, NOT .elementor-element. The latter also matches nested
 * CONTAINERS, and flattening one destroys it: .fx-hero__text is a container,
 * and from 64rem it is absolutely positioned with z-index 1 over the hero's
 * gradient scrim. Flattened, it lost the box that carried both — so the 94%
 * opaque scrim painted over the copy and the hero read as washed-out grey.
 * Keep this selector on widgets only.
 */
.fx-elementor-section .fx-product > .elementor-widget,
.fx-elementor-section .fx-product > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-hero > .elementor-widget,
.fx-elementor-section .fx-hero > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-hero__text > .elementor-widget,
.fx-elementor-section .fx-hero__text > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-partner > .elementor-widget,
.fx-elementor-section .fx-partner > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-group > .elementor-widget,
.fx-elementor-section .fx-group > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-close__demo > .elementor-widget,
.fx-elementor-section .fx-close__demo > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-close__inner > .elementor-widget,
.fx-elementor-section .fx-close__inner > .elementor-widget > .elementor-widget-container {
	display: contents;
}

/*
 * ...EXCEPT WHEN THE WRAPPER IS THE THING THE THEME STYLES.
 *
 * Flattening is right for a Text Editor, where the theme's class is typed into
 * the markup and sits on the inner <p>. It is exactly wrong for a Heading,
 * where Elementor puts the css class on the WRAPPER and renders a bare
 * <h1>..<h6> inside it: flatten that and the grid item becomes an element
 * carrying none of the theme's rules, so the theme's placement, measure and
 * type all miss it.
 *
 * Two visible faults came from this, both of them past a visual approval:
 *
 *   .fx-ab__title   the Over Foodyx <h1> lost `grid-column: 1` and was placed
 *                   in column two of .fx-ab__intro — the page title rendered
 *                   on the right, on top of the three trust points
 *   .fx-close__title  the closing heading lost its column on the homepage and
 *                   sat 288px right of where the pattern puts it, wrapping to
 *                   an extra line
 *
 * Narrowed to the Heading widget deliberately. "Any widget carrying a theme
 * class" reads as the more principled rule and measured worse: a Text Editor
 * whose wrapper also carries one — `.fx-lede` in the hero — puts its class on
 * BOTH boxes, and giving the wrapper a box back cost 10px there and 62px over
 * the homepage. A Heading is the one widget that always renders a bare
 * <h1>..<h6> with the class left on the wrapper, so it is the one widget whose
 * wrapper has to stay a box.
 */
.elementor .fx-elementor-section .elementor-widget-heading[class*="fx-"] {
	display: block;
}

/*
 * ...and it has to look like a heading while it is one, because the heading
 * inside it inherits its type — see the rule at the bottom of this file.
 *
 * A <div> gets none of theme.json's `elements.heading` typography, so the
 * wrapper arrived carrying Elementor's line-height 1.6 and the root's
 * letter-spacing. The two values are read from the same tokens theme.json's
 * heading element now uses, so there is one source for both and no number is
 * written twice.
 *
 * :where() keeps this at zero specificity, so a component that states its own
 * — `.fx-ip__title` is 1.05/-0.02em — still wins, exactly as it does on a real
 * <h1> in the pattern.
 */
:where(.elementor .fx-elementor-section .elementor-widget-heading[class*="fx-"]) {
	line-height: var(--wp--custom--heading--line-height);
	letter-spacing: var(--wp--custom--heading--letter-spacing);
}

/* ---- Elementor container defaults -------------------------------------- */

/*
 * The only layout this file touches, and only because home.css cannot.
 *
 * Elementor's .e-con resolves `flex-direction: var(--flex-direction)` and
 * `gap: var(--gap)` from custom properties it sets per element. Where home.css
 * declares neither — .fx-actions and .fx-partner are plain flex ROWS relying on
 * the initial value — there is nothing for the theme to win with, so
 * Elementor's column default stacks them.
 *
 * Resetting the two properties to what the theme assumes hands layout back.
 * Anything home.css DOES declare still wins on its own: .fx-hero stays block at
 * 64rem, .fx-hero__text stays a centred column, .fx-products keeps its grid.
 */
.fx-elementor-section .e-con,
.fx-elementor-section .e-con-inner {
	--gap: 0px;
}

/*
 * Elementor resolves `display: var(--display)` and
 * `flex-direction: var(--flex-direction)` from custom properties it sets per
 * element. Those declarations sit on `.elementor-element:where(...)`, the same
 * specificity as a theme class, so which one wins is decided by load order and
 * is fragile to reason about — the earlier attempt at this got the desktop hero
 * exactly backwards.
 *
 * Driving Elementor's OWN variables removes the fight. There is nothing left to
 * out-specify: Elementor reads these and lays the container out accordingly,
 * and the values below are simply what home.css declares for the same class at
 * the same breakpoint. The media queries mirror home.css's, so the two change
 * together.
 */
.fx-elementor-section .fx-hero {
	--display: flex;
	--flex-direction: column;
}

.fx-elementor-section .fx-hero__text,
.fx-elementor-section .fx-close__demo,
.fx-elementor-section .fx-close__inner,
.fx-elementor-section .fx-group {
	--display: block;
}

.fx-elementor-section .fx-products,
.fx-elementor-section .fx-product {
	--display: grid;
}

.fx-elementor-section .fx-actions {
	--display: flex;
	--flex-direction: row;
}

@media (min-width: 48rem) {
	.fx-elementor-section .fx-groups,
	.fx-elementor-section .fx-group__items {
		--display: grid;
	}

	.fx-elementor-section .fx-partner {
		--display: flex;
		--flex-direction: row;
	}
}

/*
 * The desktop hero: a block box with the image filling it and the copy
 * absolutely positioned over the gradient scrim. This is the rule the earlier
 * blanket `display: flex` overrode, which is what stacked the hero and pushed
 * the image 640px down the page.
 */
@media (min-width: 64rem) {
	.fx-elementor-section .fx-hero {
		--display: block;
	}

	.fx-elementor-section .fx-hero__text {
		--display: flex;
		--flex-direction: column;
	}
}

/* The section wrapper stacks the sections inside it. */
.fx-elementor-section,
.fx-elementor-section > .e-con-inner {
	--display: flex;
	--flex-direction: column;
}

/* ---- Widget normalisation ----------------------------------------------- */

/*
 * Elementor exposes no control for the inner <p> of a Text Editor widget. The
 * theme's own margins own the rhythm, so the paragraph is zeroed and only the
 * space BETWEEN paragraphs is restored.
 */
/*
 * WRAPPED IN :where(), SO THE THEME ALWAYS OUTRANKS IT.
 *
 * The comment above says the theme's own margins own the rhythm, and at one
 * class this rule said the opposite: it zeroed `.fx-cat__what` and
 * `.fx-cat__value` too, which is exactly where that rhythm lives, and this
 * file loads last so the theme's single-class rule could not answer. Every
 * integration card came out 24px short — 8px + 16px, those two margins — every
 * `__intro` paragraph 12px, and the shortfall accumulated down the page.
 *
 * :not([class*="fx-"]) was the wrong repair and is recorded here because it
 * looks right: it hands a classed paragraph back to the theme, but a paragraph
 * the theme gives no margin then keeps the UA's 1em. `.fx-partner__name` is a
 * <span> in the pattern and a <p> in a Text Editor, so every partner row grew
 * 13px on the homepage.
 *
 * :where() contributes no specificity, so this beats the UA default and loses
 * to every theme rule, classed or not. That is the whole intent in one line,
 * and it needs no list of exceptions as pages are added.
 */
:where(.fx-elementor-section .elementor-widget-text-editor p) {
	margin: 0;
}

:where(.fx-elementor-section .elementor-widget-text-editor p + p) {
	margin-block-start: var(--wp--preset--spacing--50);
}

/*
 * Sections kept as working code and rendered through an Elementor Shortcode
 * widget bring their own markup and their own stylesheet. Elementor's wrapper
 * must not add anything of its own around them, or the section inherits a
 * second set of margins on top of the ones its CSS already sets.
 */
.fx-elementor-section .elementor-widget-shortcode,
.fx-elementor-section .elementor-shortcode {
	display: contents;
}

/* ---- Buttons ------------------------------------------------------------ */

/*
 * theme.json styles the core button ELEMENT, which reaches .wp-block-button__link
 * and nothing else. An Elementor Button widget renders .elementor-button, so it
 * inherits none of it and would arrive as a default Elementor button next to
 * theme-styled ones.
 *
 * These restate theme.json's button element against Elementor's class. Every
 * value is the same token theme.json reads, so the two cannot drift: change the
 * token and both follow. The outline variant matches the .is-style-outline rule
 * in home.css.
 */
.fx-elementor-section .elementor-button {
	padding: var(--wp--preset--spacing--40) var(--wp--preset--spacing--60);
	border: var(--wp--custom--border--hairline) solid transparent;
	border-radius: var(--wp--custom--radius--md);
	background-color: var(--wp--preset--color--accent);
	color: var(--wp--preset--color--field);
	font-family: inherit;
	font-size: var(--wp--preset--font-size--base);
	font-weight: 700;
	line-height: 1.4;
}

.fx-elementor-section .elementor-button:hover,
.fx-elementor-section .elementor-button:focus-visible {
	background-color: var(--wp--preset--color--accent-strong);
	color: var(--wp--preset--color--field);
}

.fx-elementor-section .fx-btn-outline .elementor-button {
	border-color: var(--wp--preset--color--connector);
	background-color: transparent;
	color: var(--wp--preset--color--ink);
}

.fx-elementor-section .fx-btn-outline .elementor-button:hover,
.fx-elementor-section .fx-btn-outline .elementor-button:focus-visible {
	border-color: var(--wp--preset--color--accent);
	background-color: transparent;
	color: var(--wp--preset--color--accent-strong);
}

/*
 * Each button sits in its own widget wrapper, so the wrappers are the flex
 * items of .fx-actions. They must not stretch the way a flex column child does.
 */
.fx-elementor-section .fx-actions > .elementor-widget {
	flex: 0 0 auto;
	width: auto;
}

/* ---- Section quirks ----------------------------------------------------- */

/*
 * .fx-hero pulls itself left with a negative margin to escape the rail inset
 * that patterns/home.php gives it. Inside an Elementor section that inset is
 * already accounted for by .fx-elementor-section, so the negative margin would
 * pull the hero 32px further left than the sections under it and make it 32px
 * wider. Measured against the live homepage: 1184px at x=377, not 1216 at 345.
 */
.fx-elementor-section .fx-hero {
	margin-inline-start: 0;
}

/* ---- Gaps --------------------------------------------------------------- */

/*
 * Elementor's 20px container gap survives `--gap: 0px` on some containers
 * because its per-element CSS sets `gap` directly rather than through the
 * variable. Left alone it cost the products grid three 20px column gaps, which
 * is exactly the 272px -> 257px card width that showed up in the comparison.
 *
 * So the gaps are stated here explicitly, from the same tokens home.css uses.
 * This file loads after home.css, so these win; the values are identical, so
 * the two cannot drift apart visually. Containers the theme gives no gap get 0.
 */
.fx-elementor-section .fx-products,
.fx-elementor-section .fx-hero,
.fx-elementor-section .fx-hero__text,
.fx-elementor-section .fx-close__inner,
.fx-elementor-section .fx-close__demo,
.fx-elementor-section .fx-group {
	gap: 0;
}

.fx-elementor-section .fx-product {
	column-gap: var(--wp--preset--spacing--50);
	row-gap: 0;
}

.fx-elementor-section .fx-groups {
	gap: var(--wp--preset--spacing--60);
}

/*
 * Four integration groups. home.css sets exactly three tracks from 48rem, which
 * would leave a fourth group alone on a second row. Keyed on the fourth group
 * being present, so a three-group list -- and the theme-rendered pattern --
 * keeps home.css's layout untouched: two by two on tablets, where four tracks
 * would be too narrow for a partner name beside its badge, then one row of
 * four from 64rem, inside the same max-width home.css gives three.
 */
@media (min-width: 48rem) {
	.elementor .fx-elementor-section .e-con.fx-groups:has(> .fx-group:nth-child(4)) {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 64rem) {
	.elementor .fx-elementor-section .e-con.fx-groups:has(> .fx-group:nth-child(4)) {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

.fx-elementor-section .fx-group__items {
	gap: var(--wp--preset--spacing--50);
}

.fx-elementor-section .fx-partner {
	gap: var(--wp--preset--spacing--40);
}

.fx-elementor-section .fx-actions {
	gap: var(--wp--preset--spacing--40);
}

/*
 * .fx-close__inner supplies its own max-width (76rem) and padding-inline-start,
 * so the section rail inset would narrow the band content by 32px: 1184 instead
 * of production 1216. The close band is the one section that insets itself.
 */
.elementor .fx-elementor-section.fx-close > .e-con-inner {
	padding-inline-start: 0;
}

/* ---- Native Image widgets ---------------------------------------------- */

/*
 * home.css styles the hero and partner images through .fx-hero__bg and
 * .fx-partner__logo, classes that sit on the <img> itself. An Elementor Image
 * widget owns its own markup, and a widget CSS class lands on the wrapper, not
 * the <img> — and that wrapper is flattened by display:contents above, so it
 * carries no box to style.
 *
 * Targeting the image by position inside the section is what lets the hero and
 * the logos be ordinary Image widgets: an editor swaps the picture in the
 * Elementor UI and the theme still owns how it looks. The declarations are
 * copies of .fx-hero__bg and .fx-partner__logo, from the same tokens.
 */
.fx-elementor-section .fx-hero img {
	display: block;
	width: 100%;
	height: auto;
	border-radius: var(--wp--custom--radius--md);
	order: 2;
}

/*
 * .fx-partner__logo cannot be put on an Elementor Image widget <img>, so the
 * image is targeted by position. The size is a variable because the two
 * stylesheets disagree for the same class: home.css uses the badge token
 * (2.375rem) and integrations.css declares 1.75rem. Default is the token; the
 * integrations card overrides it with that stylesheet own value.
 */
.fx-elementor-section .fx-partner img {
	display: block;
	flex: 0 0 auto;
	width: var(--fx-partner-logo, var(--wp--custom--size--badge));
	height: var(--fx-partner-logo, var(--wp--custom--size--badge));
	border-radius: 50%;
}

.fx-elementor-section .fx-cat {
	--fx-partner-logo: 1.75rem;
}

/* A category reached from the footer (/integraties/#betalingen): a little air above it. */
.fx-elementor-section .fx-cat[id] {
	scroll-margin-block-start: var(--wp--preset--spacing--60);
}

/*
 * A partner row that links to its detail page — the container's HTML tag is
 * "a". It must look exactly like its unlinked neighbours at rest, so only the
 * anchor's own defaults are undone; the hover and focus follow the linked
 * cards in detail.css: the name takes the accent, focus gets the site's ring.
 * Rows without a detail page stay plain <div>s and are untouched.
 */
.elementor .fx-elementor-section a.e-con.fx-partner {
	color: inherit;
	text-decoration: none;
	border-radius: var(--wp--custom--radius--sm);
}

.elementor .fx-elementor-section a.e-con.fx-partner .fx-partner__name {
	transition: color var(--wp--custom--motion--fast) var(--wp--custom--motion--ease);
}

.elementor .fx-elementor-section a.e-con.fx-partner:hover .fx-partner__name,
.elementor .fx-elementor-section a.e-con.fx-partner:focus-visible .fx-partner__name {
	color: var(--wp--preset--color--accent-strong);
}

.elementor .fx-elementor-section a.e-con.fx-partner:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/*
 * A product row on /producten/ whose detail page exists links to it: its
 * container's HTML tag is "a" (tools/migrations/products-page-links.php). At
 * rest it is identical to a plain row; on hover and keyboard focus the name
 * takes the accent and an underline, and focus gets the site's ring. Rows
 * without a page stay plain, so the chevron alone never promises a link.
 */
.elementor .fx-elementor-section a.e-con.fx-fam__item {
	color: inherit;
	text-decoration: none;
	border-radius: var(--wp--custom--radius--sm);
}

.elementor .fx-elementor-section a.e-con.fx-fam__item .fx-fam__name {
	transition: color var(--wp--custom--motion--fast) var(--wp--custom--motion--ease);
}

.elementor .fx-elementor-section a.e-con.fx-fam__item:hover .fx-fam__name,
.elementor .fx-elementor-section a.e-con.fx-fam__item:focus-visible .fx-fam__name {
	color: var(--wp--preset--color--accent-strong);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.elementor .fx-elementor-section a.e-con.fx-fam__item:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/*
 * A homepage product card that links to its detail page, as the rows above
 * (same migration). The card keeps its rest state; the name takes the accent
 * and an underline on hover and focus, and focus gets the site's ring.
 */
.elementor .fx-elementor-section a.e-con.fx-product {
	color: inherit;
	text-decoration: none;
	border-radius: var(--wp--custom--radius--sm);
}

.elementor .fx-elementor-section a.e-con.fx-product .fx-product__name {
	transition: color var(--wp--custom--motion--fast) var(--wp--custom--motion--ease);
}

.elementor .fx-elementor-section a.e-con.fx-product:hover .fx-product__name,
.elementor .fx-elementor-section a.e-con.fx-product:focus-visible .fx-product__name {
	color: var(--wp--preset--color--accent-strong);
	text-decoration: underline;
	text-underline-offset: 0.2em;
}

.elementor .fx-elementor-section a.e-con.fx-product:focus-visible {
	outline: var(--wp--custom--focus--width) solid var(--wp--preset--color--accent);
	outline-offset: var(--wp--custom--focus--offset);
}

/* Elementor figure/anchor wrappers must not add a box around either image. */
.fx-elementor-section .fx-hero .elementor-widget-image figure,
.fx-elementor-section .fx-hero .elementor-widget-image a,
.fx-elementor-section .fx-partner .elementor-widget-image figure,
.fx-elementor-section .fx-partner .elementor-widget-image a {
	display: contents;
}

/*
 * A THEME FIGURE KEEPS THE THEME'S MARGINS.
 *
 * Elementor ships
 *
 *   .elementor .elementor-widget:not(.elementor-widget-text-editor):not(...) figure
 *       { margin: 0 }
 *
 * at four classes and an element, and `.fx-hub__diagram` is a <figure> that
 * arrives inside a Shortcode widget. home.css states its margins at one class
 * and lost all four of them:
 *
 *   margin-block-start   48px -> 0, so the POSHUB schematic sat straight under
 *                        its lede at every width
 *   margin-inline        below 48rem the diagram escapes the rail AND the page
 *                        gutter on purpose — "every pixel of width is
 *                        legibility", as home.css puts it. Zeroed, it came out
 *                        326px wide inside a 390px screen instead of 390.
 *
 * Restated here against the same tokens, and the 48rem reset with it. It is
 * the only <figure> on any of the five pages, which is why this names one
 * component rather than guessing a default for figures in general.
 */
.elementor .fx-elementor-section .elementor-widget figure.fx-hub__diagram {
	margin-block: var(--wp--preset--spacing--80) 0;
	margin-inline-start: calc(-1 * (var(--fx-rail) + var(--wp--custom--gutter--sm)));
	margin-inline-end: calc(-1 * var(--wp--custom--gutter--sm));
}

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

/* ======================================================================== */
/* Over Foodyx — /over-foodyx/                                              */
/* ======================================================================== */

/*
 * Same two mechanisms as the homepage, applied to about.css's classes. The
 * values are read off about.css, not invented: see the table in
 * docs/elementor-migration.md for how they were derived.
 *
 * The page's own pattern says it outright: "Eyebrow, h1, lede, actions and the
 * value list are DIRECT children of the grid, with no wrapper". Every one of
 * these pages is built that way, which is why the wrapper flattening below is
 * not optional.
 */

/* Elementor container defaults -> what about.css declares for the same class */
.fx-elementor-section .fx-ab__intro,
.fx-elementor-section .fx-values,
.fx-elementor-section .fx-checks,
.fx-elementor-section .fx-traits__grid {
	--display: grid;
}

.fx-elementor-section .fx-ab__actions,
.fx-elementor-section .fx-values__item,
.fx-elementor-section .fx-checks__item,
.fx-elementor-section .fx-assurances,
.fx-elementor-section .fx-assurances__item {
	--display: flex;
	--flex-direction: row;
}

.fx-elementor-section .fx-values__text,
.fx-elementor-section .fx-approach__head,
.fx-elementor-section .fx-story__head,
.fx-elementor-section .fx-trait,
.fx-elementor-section .fx-milestone,
.fx-elementor-section .fx-timeline {
	--display: block;
}

@media (min-width: 64rem) {
	.fx-elementor-section .fx-approach,
	.fx-elementor-section .fx-story {
		--display: grid;
	}
}

/* Widget wrappers flattened so the theme's grid/flex items are direct again */
.fx-elementor-section .fx-ab__intro > .elementor-widget,
.fx-elementor-section .fx-ab__intro > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-values__item > .elementor-widget,
.fx-elementor-section .fx-values__item > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-values__text > .elementor-widget,
.fx-elementor-section .fx-values__text > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-checks__item > .elementor-widget,
.fx-elementor-section .fx-checks__item > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-trait > .elementor-widget,
.fx-elementor-section .fx-trait > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-milestone > .elementor-widget,
.fx-elementor-section .fx-milestone > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-approach__head > .elementor-widget,
.fx-elementor-section .fx-approach__head > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-story__head > .elementor-widget,
.fx-elementor-section .fx-story__head > .elementor-widget > .elementor-widget-container,
.fx-elementor-section .fx-assurances__item > .elementor-widget,
.fx-elementor-section .fx-assurances__item > .elementor-widget > .elementor-widget-container {
	display: contents;
}

/*
 * --flush: a section with no connector rail.
 *
 * The homepage insets its section content by --fx-rail so the connector
 * hairline has a gutter to sit in. /over-foodyx/, /producten/, /integraties/
 * and /contact/ do not use that construction at all — they are plain
 * constrained 76rem bands. Without this modifier their content lands 32px
 * narrow and the page-section class ends up on the full-bleed wrapper.
 */
.elementor .fx-elementor-section--flush > .e-con-inner {
	padding-inline-start: 0;
}

/* ======================================================================== */
/* Layout authority — the reusable fix                                      */
/* ======================================================================== */

/*
 * TWO ROOT CAUSES, BOTH MEASURED, NEITHER WHAT THEY LOOKED LIKE.
 *
 * 1. NOT flex-direction inheritance. `.fx-assurances` computed
 *    `flex-direction: row` correctly all along. The real cause is
 *
 *        .e-con { width: var(--width) }        with  --width: 100%
 *
 *    set per element by Elementor. Every child container is forced to the full
 *    width of its parent, so three assurance items were each 1120px wide in a
 *    1120px flex row and wrapped onto three lines: 96px tall instead of 21px.
 *    A production <li> is block-level and simply fills its grid cell or sizes
 *    to its content.
 *
 * 2. NOT a missing rule. `--display: block` on `.fx-trait` was present and
 *    losing on SPECIFICITY:
 *
 *        .elementor-90 .elementor-element.elementor-element-558358c  (0,3,0)
 *        .fx-elementor-section .fx-trait                             (0,2,0)
 *
 *    Elementor writes its per-element CSS with three classes, so no two-class
 *    bridge rule can ever win regardless of load order. `.fx-trait` stayed
 *    flex, a flex parent does not collapse its child's margins, and the h3's
 *    16px top margin stopped collapsing — the ~32px per card.
 *
 * THE FIX. State the theme's layout at a specificity that beats Elementor's
 * per-element CSS, using `.e-con` as the extra class so it is (0,4,0) and the
 * outcome does not depend on stylesheet order at all. Nothing here is a
 * per-widget override: it is one authority rule plus one line per theme class,
 * and each value is what the theme's own stylesheet declares.
 */

/* ---- Width: containers size like the elements they replace -------------- */

/*
 * A theme <li> or <div> in a grid fills its cell; in a flex row it sizes to
 * content. `width: auto` gives both. The section's own boxed inner keeps 100%.
 */
.elementor .fx-elementor-section .e-con {
	width: auto;
}

.elementor .fx-elementor-section > .e-con-inner {
	width: 100%;
}

/*
 * ...and the two the theme sizes itself, which `width: auto` above was
 * silently overriding. Same rule as the display and gap blocks around it: the
 * value is what home.css declares for the same class at the same breakpoint,
 * restated where it can win.
 *
 * .fx-close__inner  a block with max-width 76rem and auto inline margins fills
 *                   its parent and centres the BOX; as a flex item with
 *                   width:auto it shrank to its content instead, so the
 *                   closing band came out 640px wide and centred where the
 *                   pattern is 1216px and left-aligned on the page rail —
 *                   every child of it sat 288px too far right.
 * .fx-hero__text    home.css gives it width: 46% from 64rem. It was taking
 *                   59%, which let the h1 fit on four lines where the pattern
 *                   wraps it onto five: 294px against 368.
 */
.elementor .fx-elementor-section .e-con.fx-close__inner {
	width: 100%;
}

@media (min-width: 64rem) {
	.elementor .fx-elementor-section .e-con.fx-hero__text {
		width: 46%;
	}
}

/* ---- Display: restated above Elementor's per-element CSS ---------------- */

.elementor .fx-elementor-section .e-con.fx-ab__intro,
.elementor .fx-elementor-section .e-con.fx-values,
.elementor .fx-elementor-section .e-con.fx-checks,
.elementor .fx-elementor-section .e-con.fx-traits__grid,
.elementor .fx-elementor-section .e-con.fx-products,
.elementor .fx-elementor-section .e-con.fx-product,
.elementor .fx-elementor-section .e-con.fx-groups,
.elementor .fx-elementor-section .e-con.fx-group__items {
	--display: grid;
	display: grid;
}

.elementor .fx-elementor-section .e-con.fx-ab__actions,
.elementor .fx-elementor-section .e-con.fx-values__item,
.elementor .fx-elementor-section .e-con.fx-checks__item,
.elementor .fx-elementor-section .e-con.fx-assurances,
.elementor .fx-elementor-section .e-con.fx-assurances__item,
.elementor .fx-elementor-section .e-con.fx-actions,
.elementor .fx-elementor-section .e-con.fx-partner {
	--display: flex;
	--flex-direction: row;
	display: flex;
	flex-direction: row;
}

.elementor .fx-elementor-section .e-con.fx-values__text,
.elementor .fx-elementor-section .e-con.fx-approach__head,
.elementor .fx-elementor-section .e-con.fx-story__head,
.elementor .fx-elementor-section .e-con.fx-trait,
.elementor .fx-elementor-section .e-con.fx-milestone,
.elementor .fx-elementor-section .e-con.fx-timeline,
.elementor .fx-elementor-section .e-con.fx-group,
.elementor .fx-elementor-section .e-con.fx-close__inner,
.elementor .fx-elementor-section .e-con.fx-close__demo,
.elementor .fx-elementor-section .e-con.fx-ab,
.elementor .fx-elementor-section .e-con.fx-approach,
.elementor .fx-elementor-section .e-con.fx-traits,
.elementor .fx-elementor-section .e-con.fx-story,
.elementor .fx-elementor-section .e-con.fx-abcta {
	--display: block;
	display: block;
}

@media (min-width: 64rem) {
	.elementor .fx-elementor-section .e-con.fx-approach,
	.elementor .fx-elementor-section .e-con.fx-story {
		--display: grid;
		display: grid;
	}

	.elementor .fx-elementor-section .e-con.fx-hero {
		--display: block;
		display: block;
	}

	.elementor .fx-elementor-section .e-con.fx-hero__text {
		--display: flex;
		--flex-direction: column;
		display: flex;
		flex-direction: column;
	}
}

.elementor .fx-elementor-section .e-con.fx-hero {
	--display: flex;
	--flex-direction: column;
	display: flex;
	flex-direction: column;
}

/*
 * The desktop hero and longer copy (content batch 2, 29 September 2026).
 * home.css lays the copy over the image absolutely, so the hero is exactly as
 * tall as the image and longer copy spills out of it: the commercial H1 ("…
 * Zonder Foodyx-commissie per bestelling.") ran into the header above and the
 * trust row below at 1024–1440. Scoped to the Elementor build; home.css, and
 * the pattern it styles, are unchanged. After the rule above on purpose: same
 * selector, so order decides.
 *
 * 64–80rem: the copy column beside the terminal is ~400px, too narrow for the
 * copy, and growing the image to fit it pushed the terminal under the text.
 * The hero keeps the tablet arrangement instead — copy above, the image below
 * at its own ratio, no scrim — as it already does under 64rem.
 */
@media (min-width: 64rem) and (max-width: 79.99rem) {
	.elementor .fx-elementor-section .e-con.fx-hero {
		--display: flex;
		display: flex;
		flex-direction: column;
	}

	.elementor .fx-elementor-section .fx-hero::after {
		content: none;
	}

	.elementor .fx-elementor-section .fx-hero .fx-hero__text {
		position: static;
		width: auto;
		margin-block-end: var(--wp--preset--spacing--70);
		padding-inline: var(--fx-rail) 0;
	}

	.elementor .fx-elementor-section .fx-hero h1 {
		max-width: 20ch;
	}
}

/*
 * From 80rem: image and copy share one grid cell, so the hero is as tall as
 * the taller of the two. With the copy below, that is the image's own height
 * (1280: 665px against 658px); longer copy would make the image cover a taller
 * cell, anchored right where the terminal is, instead of overflowing.
 */
@media (min-width: 80rem) {
	.elementor .fx-elementor-section .e-con.fx-hero {
		--display: grid;
		display: grid;
	}

	.elementor .fx-elementor-section .fx-hero img,
	.elementor .fx-elementor-section .fx-hero .fx-hero__text {
		grid-area: 1 / 1;
	}

	.elementor .fx-elementor-section .fx-hero img {
		height: 100%;
		object-fit: cover;
		object-position: right center;
	}

	.elementor .fx-elementor-section .fx-hero .fx-hero__text {
		position: relative;
		inset: auto;
		padding-block: var(--wp--preset--spacing--80);
	}

	/*
	 * The Text Editor rule below (flex: 1 1 0%) makes the eyebrow share the
	 * column's free height with the lede, so its box grew to ~157px and left a
	 * ~144px hole above the H1 at 1440. At its own height the eyebrow gets an
	 * explicit spacing--70 gap to the H1 (home.css's spacing--30 was too tight
	 * over the image); the lede still takes the free space, so the CTAs stay
	 * where they were (30 September 2026).
	 */
	.elementor .fx-elementor-section .fx-hero .fx-hero__text .fx-eyebrow {
		flex: none;
		margin-block-end: var(--wp--preset--spacing--70);
	}
}

/*
 * The commercial H1 is about a third longer than the one the hero was drawn
 * for. At the display size it took six lines at 1280–1440 (the hero grew to
 * 842px and cropped the image). The small display token keeps it inside the
 * image's own height from 80rem, and at a tablet-like scale in the stacked
 * 64–80rem hero. One class more than Elementor's per-element heading rule
 * (post-<id>.css), which also sets a size.
 */
@media (min-width: 64rem) {
	.elementor .fx-elementor-section .fx-hero h1.elementor-heading-title {
		font-size: var(--wp--preset--font-size--display-sm);
	}
}

/* ---- Gap: the same specificity problem, third instance ------------------ */

/*
 * Elementor also sets --gap per element (20px default), and `.e-con { gap:
 * var(--gap) }` then applies it on BOTH axes. Production has `row-gap: normal`
 * everywhere and only declares column gaps, so every grid picked up 20px of
 * row gap it should not have: .fx-checks came out 302px against 235px.
 *
 * Only the VARIABLE is reset, never the `gap` property. Elementor resolves its
 * own declaration to 0 at one class, and the theme stylesheet — which loads
 * after Elementor and declares things like `gap: normal 48px` — then wins
 * outright and keeps its column gaps.
 */
.elementor .fx-elementor-section .e-con {
	/*
	 * Elementor 4 does NOT read --gap for the gap. It resolves
	 *
	 *     gap: var(--row-gap) var(--column-gap)
	 *
	 * so --gap is a legacy variable nothing on this path reads, and setting it
	 * changed nothing. These are the two it actually reads.
	 *
	 * Both go to 0 so the theme stylesheet owns spacing entirely. about.css
	 * declares only COLUMN gaps (e.g. column-gap: 48px on .fx-checks) and
	 * leaves row-gap at normal; it loads after Elementor, so its column
	 * declarations still win and only Elementor's stray 20px row gap goes.
	 */
	--row-gap: 0px;
	--column-gap: 0px;
	--gap: 0px;
}

/* ---- Text Editor widgets as flex items --------------------------------- */

/*
 * TWO CAUSES OF THE MOBILE HEIGHT, BOTH IN THE TEXT EDITOR WIDGET.
 *
 * 1. Its content was not shrinking. display:contents makes the inner element
 *    the flex item, but it arrives without flex-item sizing, so it took its
 *    content width instead of the space left over: 310px where 299px was
 *    available. .fx-checks__item is flex-wrap:wrap, so icon + text no longer
 *    fitted on one line and every row wrapped onto two. 95px against 81px, on
 *    every check and every value, on every page that uses the construction.
 *
 * 2. Elementor gives the widget line-height 1.6. The theme lets these spans
 *    INHERIT theirs — no rule sets line-height on .fx-checks__text at all —
 *    and the surrounding text is 1.5. Every wrapped line was 1.6px taller.
 *
 * Both rules are generic. They name no component and no page: they describe
 * how a Text Editor widget must behave once its wrapper is flattened, so they
 * apply unchanged to Integraties, Producten and Contact.
 *
 * Only .elementor-widget-text-editor is targeted. Icons come from Shortcode
 * widgets and keep the theme flex:0 0 auto that stops them stretching; in a
 * block parent the flex declarations are simply ignored.
 */
/*
 * Both shapes: Elementor 4 emits .elementor-widget-container for some widgets
 * and puts the content directly in the widget for others, so the selector has
 * to cover each. Targeting only the container path silently did nothing here.
 */
.elementor .fx-elementor-section .elementor-widget-text-editor > *,
.elementor .fx-elementor-section .elementor-widget-text-editor > .elementor-widget-container > * {
	flex: 1 1 0%;
	min-width: 0;
}

.elementor .fx-elementor-section .elementor-widget-text-editor {
	line-height: inherit;
}

/*
 * The same shrink problem one level up.
 *
 * Where the theme puts a text COLUMN beside an icon — .fx-values__text is the
 * first, and every *__text in the theme is the same shape — the column is a
 * nested Elementor container, not a widget, so the rule above does not reach
 * it. Without flex-item sizing it took its content width, overflowed the row,
 * and .fx-values__item wrapped the icon onto its own line: visible on values 2
 * and 3 while the shortest one still fitted.
 *
 * Matched on the __text suffix rather than listed per component, so it holds
 * for the pages still to be migrated. Icons are Shortcode widgets and item
 * containers are untouched, so nothing that already matches is affected.
 *
 * ONE EXCEPTION, found on Contact. "Every *__text is the same shape" is not
 * quite true: .fx-trust__text is a two-line label beside a badge, not a
 * column, and contact.css lets it size to its content. Growing it made each
 * .fx-trust__item fill its flex line, which moved the hairline dividers
 * between the three trust points — 8px out at 1024, 526px at 768.
 */
.elementor .fx-elementor-section .e-con[class*="__text"]:not(.fx-trust__text) {
	flex: 1 1 0%;
	min-width: 0;
}

/* ======================================================================== */
/* Integraties, Producten, Contact                                          */
/* ======================================================================== */

/*
 * Class lists only. The mechanisms are the ones proven on Over Foodyx and are
 * not repeated per page: layout authority at (0,4,0), width:auto, the two gap
 * variables Elementor actually reads, Text Editor flex-item sizing, inherited
 * line-height, nested *__text sizing, and --flush.
 *
 * Every value below is read off integrations.css / products.css / contact.css
 * for the same class at the same breakpoint — nothing is invented.
 */

.elementor .fx-elementor-section .e-con.fx-ip__intro,
.elementor .fx-elementor-section .e-con.fx-cats__grid,
.elementor .fx-elementor-section .e-con.fx-cat,
.elementor .fx-elementor-section .e-con.fx-hubband,
.elementor .fx-elementor-section .e-con.fx-wiring,
.elementor .fx-elementor-section .e-con.fx-cases__grid,
.elementor .fx-elementor-section .e-con.fx-case,
.elementor .fx-elementor-section .e-con.fx-pp__intro,
.elementor .fx-elementor-section .e-con.fx-families,
.elementor .fx-elementor-section .e-con.fx-fam,
.elementor .fx-elementor-section .e-con.fx-spokes,
.elementor .fx-elementor-section .e-con.fx-contact__intro,
.elementor .fx-elementor-section .e-con.fx-trust,
.elementor .fx-elementor-section .e-con.fx-contact__grid,
.elementor .fx-elementor-section .e-con.fx-form__rows,
.elementor .fx-elementor-section .e-con.fx-direct__row,
.elementor .fx-elementor-section .e-con.fx-direct__address,
.elementor .fx-elementor-section .e-con.fx-hours,
.elementor .fx-elementor-section .e-con.fx-wastrip__inner {
	--display: grid;
	display: grid;
}

.elementor .fx-elementor-section .e-con.fx-ip__actions,
.elementor .fx-elementor-section .e-con.fx-pp__actions,
.elementor .fx-elementor-section .e-con.fx-ask__copy,
.elementor .fx-elementor-section .e-con.fx-fam__item,
.elementor .fx-elementor-section .e-con.fx-trust__item,
.elementor .fx-elementor-section .e-con.fx-form__note,
.elementor .fx-elementor-section .e-con.fx-wastrip__action {
	--display: flex;
	--flex-direction: row;
	display: flex;
	flex-direction: row;
}

.elementor .fx-elementor-section .e-con.fx-wiring__node,
.elementor .fx-elementor-section .e-con.fx-spokes__node {
	--display: flex;
	--flex-direction: column;
	display: flex;
	flex-direction: column;
}

.elementor .fx-elementor-section .e-con.fx-trust__text,
.elementor .fx-elementor-section .e-con.fx-case__label,
.elementor .fx-elementor-section .e-con.fx-ip,
.elementor .fx-elementor-section .e-con.fx-pp,
.elementor .fx-elementor-section .e-con.fx-cats,
.elementor .fx-elementor-section .e-con.fx-ask,
.elementor .fx-elementor-section .e-con.fx-ipcta,
.elementor .fx-elementor-section .e-con.fx-ppcta,
.elementor .fx-elementor-section .e-con.fx-cases,
.elementor .fx-elementor-section .e-con.fx-panel,
.elementor .fx-elementor-section .e-con.fx-direct,
.elementor .fx-elementor-section .e-con.fx-wastrip,
.elementor .fx-elementor-section .e-con.fx-fam__list,
.elementor .fx-elementor-section .e-con.fx-ask__text {
	--display: block;
	display: block;
}

/*
 * Read off the stylesheets rather than assumed: .fx-ask and .fx-ppcta go
 * side-by-side at 48rem, not 64rem, and .fx-cases splits into two columns
 * only on /producten/ — integrations.css leaves its own .fx-cases a block at
 * every width, so the rule is scoped to the page rather than to the class.
 * The prefix match covers both the draft slug and the slug it takes over.
 */
@media (min-width: 48rem) {
	.elementor .fx-elementor-section .e-con.fx-ask,
	.elementor .fx-elementor-section .e-con.fx-ppcta {
		--display: grid;
		display: grid;
	}
}

@media (min-width: 64rem) {
	body[class*="page-producten"] .elementor .fx-elementor-section .e-con.fx-cases {
		--display: grid;
		display: grid;
	}
}

/* Widget wrappers flattened so the theme's grid/flex items are direct again */
/*
 * .fx-families holds a visually hidden <h2> that the comp has no heading for.
 * In the pattern it is position:absolute and so takes no grid cell; wrapped in
 * an Elementor widget box it took one, and the first family card started in
 * column two.
 */
.elementor .fx-elementor-section .fx-families > .elementor-widget,
.elementor .fx-elementor-section .fx-families > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-cat > .elementor-widget,
.elementor .fx-elementor-section .fx-cat > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-case > .elementor-widget,
.elementor .fx-elementor-section .fx-case > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-fam > .elementor-widget,
.elementor .fx-elementor-section .fx-fam > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-fam__item > .elementor-widget,
.elementor .fx-elementor-section .fx-fam__item > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-trust__item > .elementor-widget,
.elementor .fx-elementor-section .fx-trust__item > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-trust__text > .elementor-widget,
.elementor .fx-elementor-section .fx-trust__text > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-direct__row > .elementor-widget,
.elementor .fx-elementor-section .fx-direct__row > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-ask__copy > .elementor-widget,
.elementor .fx-elementor-section .fx-ask__copy > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-wiring__node > .elementor-widget,
.elementor .fx-elementor-section .fx-wiring__node > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-spokes__node > .elementor-widget,
.elementor .fx-elementor-section .fx-spokes__node > .elementor-widget > .elementor-widget-container {
	display: contents;
}

/* ---- Contact: the classes contact.css needs that the lists above miss ---- */

/*
 * contact.css places .fx-contact__title, .fx-contact__sub and .fx-trust by
 * explicit grid-column/grid-row at 64rem, so all three must be DIRECT children
 * of .fx-contact__intro. The heading and the paragraph are Elementor widgets,
 * so their two wrapper boxes have to disappear or the placement addresses a
 * wrapper instead of the element that carries the class.
 */
.elementor .fx-elementor-section .e-con.fx-contact,
.elementor .fx-elementor-section .e-con.fx-map,
.elementor .fx-elementor-section .e-con.fx-wastrip__text {
	--display: block;
	display: block;
}

.elementor .fx-elementor-section .fx-contact__intro > .elementor-widget,
.elementor .fx-elementor-section .fx-contact__intro > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-panel > .elementor-widget,
.elementor .fx-elementor-section .fx-panel > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-wastrip__inner > .elementor-widget,
.elementor .fx-elementor-section .fx-wastrip__inner > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-wastrip__text > .elementor-widget,
.elementor .fx-elementor-section .fx-wastrip__text > .elementor-widget > .elementor-widget-container,
.elementor .fx-elementor-section .fx-wastrip__action > .elementor-widget,
.elementor .fx-elementor-section .fx-wastrip__action > .elementor-widget > .elementor-widget-container {
	display: contents;
}

/* ---- Full-bleed bands --------------------------------------------------- */

/*
 * The map is "full bleed, edge to edge" — contact.css says so and the band is
 * the page's strongest horizontal break. A section normally carries the page
 * gutter and the connector rail inset; this modifier cancels both.
 *
 * Two classes on purpose. The gutter is widened again inside a 48rem media
 * query, and a single-class modifier would lose to it there.
 */
.fx-elementor-section.fx-elementor-section--bleed {
	--fx-gutter: 0px;
	--fx-rail: 0px;
}

.elementor .fx-elementor-section .fx-map > .elementor-widget,
.elementor .fx-elementor-section .fx-map > .elementor-widget > .elementor-widget-container {
	display: contents;
}

/* ---- A partner with no approved logo ------------------------------------ */

/* No partner on #91 uses this since Exact and Twinfield got their badges; kept for the next one. */

/*
 * integrations.css reserves the logo column for Exact and Twinfield and shows
 * nothing in it — "emptiness on purpose", as the comment there puts it. The
 * pattern does that with a bare <span class="fx-partner__logo--none">, which an
 * Elementor Text Editor will not keep: it strips an element with no content.
 *
 * So the placeholder is not authored as content here. It does not need to be —
 * "this partner has no logo" is exactly what :not(:has(img)) says, and holding
 * the column open is presentation on either side of the migration. The size is
 * the same variable the real logos use, so the two can never drift.
 */
.fx-elementor-section .fx-partner:not(:has(img))::before {
	content: "";
	/*
	 * Static, not Elementor's absolute: every .e-con draws its background
	 * overlay on ::before with position:absolute, which took this placeholder
	 * out of the row, so Exact and Twinfield sat flush left at 21px instead of
	 * aligned under the logos at 28px, as integrations.css intends.
	 */
	position: static;
	display: block;
	flex: 0 0 auto;
	width: var(--fx-partner-logo, var(--wp--custom--size--badge));
	height: var(--fx-partner-logo, var(--wp--custom--size--badge));
	border-radius: 50%;
	background: none;
}

/* ---- Heading widgets ---------------------------------------------------- */

/*
 * A Heading widget puts its css class on the WRAPPER and renders an <h1>..<h6>
 * inside it, so the theme's own rule for .fx-ip__title lands on a box and the
 * heading itself keeps whatever size theme.json gives that tag. The widgets
 * used to paper over this with their own typography settings, which is how the
 * Integraties h1 came out at the desktop size on a 768px screen: Elementor's
 * tablet breakpoint is not the theme's 48rem, so the mobile override never
 * applied and the "display" size did.
 *
 * Stated once here instead. The heading inherits the box the theme has already
 * sized, at three classes, which beats theme.json's :where() element styles and
 * needs no per-widget setting at all. Editors keep the Heading widget's Title
 * field; nothing about the type scale is duplicated into Elementor.
 *
 * Listed properties, not the `font` shorthand. The shorthand also resets
 * font-weight, and the wrapper is a plain <div> at 400 — which silently took
 * every heading on both pages down from 700 and let the /producten/ h1 fit on
 * one line at 768px where the pattern wraps it onto two.
 */
/*
 * MATCHED ON THE WIDGET, NOT ON "__title". The selector used to be
 * [class*="__title"], which is a name and not a shape: about.css calls its
 * section headings `.fx-ab__h2`, so every h2 on Over Foodyx missed this rule
 * and kept theme.json's 46px where the theme sets 34px. Both of them wrapped
 * onto a second line — `.fx-approach__head` 67px tall against 163, the story
 * head 81px — which is also most of what was left of that page's height delta.
 *
 * "A widget wrapper carrying a theme class" is the actual condition, and it
 * covers __title, __h2 and whatever the next page names its headings.
 */
/*
 * The inner heading takes the WRAPPER's type, and the rule above makes sure
 * the wrapper has a heading's type to give. Both halves are needed:
 *
 *   inherit alone      integrations.css tightens `.fx-ip__title` to
 *                      line-height 1.05 and letter-spacing -0.02em, and that
 *                      lands on the wrapper. Dropping the inherit dropped
 *                      both — the Integraties h1 went to 1.15 and 147px.
 *   the wrapper alone  home.css gives `.fx-close__title` a size and nothing
 *                      else, so without the defaults above the wrapper was a
 *                      bare <div> wearing Elementor's line-height 1.6 and the
 *                      closing heading came out 147px against the pattern's
 *                      106, with letter-spacing normal.
 *
 * Together: the component's own type wins where it states one, theme.json's
 * heading wins where it does not — which is exactly what happens to a real
 * <h2> in the pattern.
 */
.elementor .fx-elementor-section [class*="fx-"].elementor-widget .elementor-heading-title {
	font-family: inherit;
	font-size: inherit;
	line-height: inherit;
	letter-spacing: inherit;
	color: inherit;
	text-wrap: inherit;
	margin: 0;
}

/* ---- /producten/: five families, four combinations ---------------------- */

/*
 * Content batch 2 (29 September 2026) added a fifth family (Marketing) and a
 * fourth combination (all-you-can-eat). products.css lays out four families
 * and three combinations, so each grid left one card alone on its last row.
 * Keyed on the card COUNT, not the page, so the theme pattern (four and three)
 * keeps products.css's layout untouched:
 *
 *   five families   48–64rem: 2 + 2 + 1, the last card centred at the same
 *                   width; from 64rem: 3 + 2, the second row centred.
 *   four cases      from 64rem: 2 + 2 instead of 3 + 1.
 *
 * Cards span tracks of a finer grid (4 or 6), so every card keeps the same
 * width and the subgrid rows in products.css still line up the hairlines.
 */
@media (min-width: 48rem) {
	.elementor .fx-elementor-section .e-con.fx-families:has(> .fx-fam + .fx-fam + .fx-fam + .fx-fam + .fx-fam:last-child) {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}

	.elementor .fx-elementor-section .e-con.fx-families:has(> .fx-fam + .fx-fam + .fx-fam + .fx-fam + .fx-fam:last-child) > .fx-fam {
		grid-column: span 2;
	}

	.elementor .fx-elementor-section .e-con.fx-families:has(> .fx-fam + .fx-fam + .fx-fam + .fx-fam + .fx-fam:last-child) > .fx-fam:last-child {
		grid-column: 2 / span 2;
	}
}

@media (min-width: 64rem) {
	.elementor .fx-elementor-section .e-con.fx-families:has(> .fx-fam + .fx-fam + .fx-fam + .fx-fam + .fx-fam:last-child) {
		grid-template-columns: repeat(6, minmax(0, 1fr));
	}

	.elementor .fx-elementor-section .e-con.fx-families:has(> .fx-fam + .fx-fam + .fx-fam + .fx-fam + .fx-fam:last-child) > .fx-fam:nth-last-child(2) {
		grid-column: 2 / span 2;
	}

	.elementor .fx-elementor-section .e-con.fx-families:has(> .fx-fam + .fx-fam + .fx-fam + .fx-fam + .fx-fam:last-child) > .fx-fam:last-child {
		grid-column: 4 / span 2;
	}

	.elementor .fx-elementor-section .e-con.fx-cases__grid:has(> .fx-case + .fx-case + .fx-case + .fx-case:last-child) {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}
