.forge-cutout {
	position: relative;
	width: 100%;
	overflow-x: clip;
}

.forge-cutout__bg {
	position: relative;
	width: 100%;
	height: 480px;
	overflow: hidden;
	border-radius: 24px;
	/*
	 * The Ken Burns/parallax image below is `will-change: transform` and
	 * animated - on iOS Safari a GPU-composited transformed descendant can
	 * visually escape an ancestor's `overflow: hidden` + border-radius clip
	 * (a known Safari compositing bug), pushing the widget's real horizontal
	 * extent out to the image's full scaled-up width. `contain: paint` forces
	 * an actual clip boundary regardless of child compositing.
	 */
	contain: paint;
}

/*
 * With a background image, the image is a full-bleed backdrop behind the
 * entire widget (not just a "header strip" above the card) - the card then
 * sits on top of it, flush against an edge, so its "feet" (baked into the
 * 9-slice shape) visually run into the photo. Photo and card are stacked in
 * the SAME single-cell CSS grid rather than positioned with `position:
 * absolute`: an auto-sized grid row grows to fit the TALLER of the two
 * overlapping items, so if the card's own content needs more height than
 * the configured background height, the row (and the photo filling it)
 * grows to match instead of the card silently overflowing past the photo
 * and overlapping whatever comes after it on the page.
 */
.forge-cutout--has-bg {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	/* --forge-cutout-bg-height is set by the "Hoogte achtergrond" control (per breakpoint) - see cutout.php. */
	grid-template-rows: minmax(var(--forge-cutout-bg-height, 480px), auto);
}

.forge-cutout--has-bg .forge-cutout__bg {
	grid-area: 1 / 1 / -1 / -1;
	width: 100%;
	height: 100%;
}

.forge-cutout__bg-image {
	/*
	 * !important: Elementor core ships `.elementor img { height: auto;
	 * max-width: 100%; }`, a class+element selector that outranks a plain
	 * single class on specificity - without !important this silently wins
	 * and the image reverts to its natural aspect-ratio height instead of
	 * filling the background box.
	 */
	position: absolute !important;
	inset: 0 !important;
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	display: block;
	object-fit: cover;
	object-position: center center;
}

.forge-cutout__bg-image[data-forge-parallax] {
	top: -15% !important;
	height: 130% !important;
	will-change: transform;
}

/*
 * Ken Burns pan/zoom. All actual numbers (zoom factor, pan start/end %,
 * duration, loop mode) come in per-instance via inline custom properties set
 * in PHP (see Cutout::render()) - the start/end translate% are pre-computed
 * there from the chosen zoom level so the pan can never reveal an edge of the
 * image, regardless of what zoom value the user picks. transform-origin stays
 * at its default (center), matching the math used to derive those values.
 *
 * The base (non-animating) transform mirrors the 0% keyframe exactly, so the
 * image already sits at its start position before .forge-cutout__bg-image--
 * animate is added (paused animations still apply their 0% frame, but setting
 * it explicitly here avoids relying on that and keeps this rule readable on
 * its own).
 */
.forge-cutout__bg-image--ken-burns {
	transform: scale(var(--forge-kb-zoom, 1.3)) translate(var(--forge-kb-start-x, 0%), var(--forge-kb-start-y, 0%));
	animation-name: forge-cutout-ken-burns;
	animation-duration: var(--forge-kb-duration, 60s);
	animation-timing-function: linear;
	animation-iteration-count: var(--forge-kb-iteration, 1);
	animation-direction: var(--forge-kb-direction, normal);
	animation-fill-mode: forwards;
	animation-play-state: paused;
	will-change: transform;
}

/* Added by JS once the section scrolls into view - see cutout.js. */
.forge-cutout__bg-image--ken-burns.forge-cutout__bg-image--animate {
	animation-play-state: running;
}

@keyframes forge-cutout-ken-burns {
	0% {
		transform: scale(var(--forge-kb-zoom, 1.3)) translate(var(--forge-kb-start-x, 0%), var(--forge-kb-start-y, 0%));
	}

	100% {
		transform: scale(var(--forge-kb-zoom, 1.3)) translate(var(--forge-kb-end-x, 0%), var(--forge-kb-end-y, 0%));
	}
}

/*
 * The card's shape (corners + "feet") is built from 9 fixed-size SVG slices
 * laid out in a CSS grid - a "9-slice"/"scale-9" technique. Corners and feet
 * stay pixel-crisp at any card size because only the straight edges (1
 * dimension) and the center (both dimensions) are in flexible 1fr tracks;
 * the fixed-size tracks never stretch. This mirrors a proven reference
 * implementation (see project notes) rather than the previous approach of
 * separately positioned corner divs, which didn't line up correctly once
 * the card overlapped a background image.
 */
.forge-cutout__card {
	--forge-cutout-card-color: #2a4039;
	--forge-cutout-accent-color: #f6f6f1;
	position: relative;
	isolation: isolate;
	box-sizing: border-box;
	overflow: visible;
	/*
	 * display:flex + centering here (rather than width/height:100% on
	 * .forge-cutout__content) is what makes content centering work together
	 * with fit-content sizing without a circular reference: .forge-cutout__
	 * content is a normal flex child sized by its own intrinsic content, and
	 * the card wraps around THAT. Making the content 100% of a fit-content
	 * card (both trying to size from each other) collapsed to a near-zero
	 * width in testing, with text overflowing outside the visible card.
	 * When the card IS given an explicit width/height, this same flex setup
	 * centers the (still intrinsically-sized) content within the extra
	 * space instead.
	 */
	display: flex;
	align-items: center;
	justify-content: center;
	/*
	 * Unset by default: the card shrink-wraps to its content plus padding.
	 * "Breedte kaart" sets --forge-cutout-card-width (see cutout.php); an
	 * untouched control never defines that property, so var()'s own
	 * fallback (fit-content) applies with zero extra CSS needed here -
	 * "Hoogte kaart" ("min-height" below) still uses the older pattern
	 * (only generates a declaration once actually set) since nothing else
	 * on the page ever needs to override its default.
	 */
	width: var(--forge-cutout-card-width, fit-content);
	/*
	 * Without a cap, long text (e.g. the subtitle) has no reason to wrap at
	 * all in a fit-content box and would render as one very long line,
	 * making the card as wide as that line. 480px is a sensible default
	 * paragraph measure; min() keeps it from overflowing on narrow screens.
	 * Once "Breedte kaart" is set, max-width matches it exactly (same
	 * variable, same value as width above - a fixed width shouldn't still
	 * have a lower max-width ceiling fighting it).
	 */
	max-width: var(--forge-cutout-card-width, min(480px, 100%));
	min-height: fit-content;
	/*
	 * No generic default here - each shape sets its own safe padding below,
	 * because the two shapes need genuinely different minimums (see there).
	 */
}

.forge-cutout__shape {
	position: absolute;
	inset: 0;
	z-index: -1;
	display: grid;
	width: 100%;
	height: 100%;
	pointer-events: none;
}

.forge-cutout__slice {
	display: block;
	width: 100%;
	height: 100%;
	min-width: 0;
	min-height: 0;
}

.forge-cutout__slice--tl { grid-area: 1 / 1; }
.forge-cutout__slice--t  { grid-area: 1 / 2; }
.forge-cutout__slice--tr { grid-area: 1 / 3; }
.forge-cutout__slice--l  { grid-area: 2 / 1; }
.forge-cutout__slice--c  { grid-area: 2 / 2; }
.forge-cutout__slice--r  { grid-area: 2 / 3; }
.forge-cutout__slice--bl { grid-area: 3 / 1; }
.forge-cutout__slice--b  { grid-area: 3 / 2; }
.forge-cutout__slice--br { grid-area: 3 / 3; }

/* Everything except the shape layer renders above it. */
.forge-cutout__card > :not(.forge-cutout__shape) {
	position: relative;
	z-index: 1;
}

/*
 * Without a background photo behind the card at all, the shape's light-
 * accent "foot" paths have nothing to contrast against but the plain page
 * background - which, being a similarly light tone (pixel-identical to this
 * site's page background, confirmed by sampling), makes that opaque accent
 * patch either blend in invisibly or (where the source SVG has genuinely
 * empty canvas rather than a real path - see square below) show a stray
 * void. Recoloring it to match the card color instead keeps the card
 * reading as one solid, complete shape.
 *
 * An in-between attempt tried keeping square's foot at its native light
 * color to mirror desktop's two-tone look - reverted after pixel-sampling
 * the rendered result showed the foot really was just invisible (exactly
 * the blending problem described above, confirmed with the user against
 * their own reference image, which turned out to show a plain uniform card
 * with no visible foot/border detail at all once checked at the pixel
 * level). Recoloring here is the correct, confirmed behavior for both
 * shapes, not just rectangle.
 */
.forge-cutout:not(.forge-cutout--has-bg) .forge-cutout__slice path {
	fill: var(--forge-cutout-card-color);
}

/*
 * Rectangle has a further problem the fill recolor above can't reach: its
 * top-left/top-right/left-edge/right-edge tiles aren't just wrong-colored,
 * large parts of them have NO path at all - confirmed by rendering tl.svg in
 * isolation, which is almost entirely blank. A background-color behind the
 * whole card fills that in safely because rectangle's real rounded corners
 * happen to sit close enough to their tile's edge that a square backing
 * doesn't visibly square them off.
 */
.forge-cutout--rectangle:not(.forge-cutout--has-bg) .forge-cutout__card {
	background-color: var(--forge-cutout-card-color);
}

/*
 * Square has the same class of void as rectangle (confirmed across tr.svg,
 * r.svg and t.svg, whose paths all stop well short of their tile's real
 * bounding box) plus the same "foot blends into the page" problem the fill
 * recolor above handles - a flat background-color + border-radius on the
 * card itself fixes both at once: void-proof regardless of how many gaps
 * the source SVG has, and it's what the user's reference image for a card
 * with no photo behind it actually shows (a plain, uniform-radius rounded
 * rectangle, confirmed by pixel-zooming its corners - no foot/notch detail
 * survives there either). 24px matches the radius already used on
 * .forge-cutout__bg, so the photo above and the card below read as a
 * consistent pair.
 */
.forge-cutout--square:not(.forge-cutout--has-bg) .forge-cutout__card {
	background-color: var(--forge-cutout-card-color);
	border-radius: 24px;
}

/*
 * Square: foot at top-left, foot at bottom-right. The left column is 96px,
 * not the source canvas's full 136px - the outer 40px of the original
 * Figma export was a dead transparent margin (an artboard edge, not part of
 * the drawn shape) on every left-column slice, trimmed from the SVGs.
 */
.forge-cutout--square .forge-cutout__shape {
	grid-template-columns: 96px minmax(0, 1fr) 208px;
	grid-template-rows: 208px minmax(0, 1fr) 96px;
}

.forge-cutout--square .forge-cutout__card {
	/* Structural floor only, so the fixed slices always have room to render - unrelated to the "Hoogte kaart" setting. */
	min-width: calc(96px + 208px + 1px);
	min-height: calc(208px + 96px + 1px);
	/*
	 * The top-left and bottom-right "feet" aren't just decoration sitting
	 * outside the card - within the shape's own top row and right column,
	 * solid card color only covers part of the fixed-size track (the rest
	 * is the light foot / fully transparent open background), confirmed via
	 * a real rendered computed-style + pixel-sampled dump, not guesswork:
	 * top row (208px track) is solid only from 112px down; right column
	 * (208px track) is solid only in its first 96px nearest the center.
	 * Centered/wrapped text with too little padding on those sides put text
	 * in that unsafe zone - readable-colored text over a same-or-no-colored
	 * background becomes invisible. 150px/150px keeps a deliberate margin
	 * past each confirmed minimum (112px top, 112px right) - bottom/left
	 * are already fully safe at any size and stay modest (50px), since
	 * padding them out further just reads as excess empty space below the
	 * button with nothing protecting it there.
	 */
	padding: 150px 150px 50px 50px;
}

/* Rectangle: feet at bottom-left and bottom-right. */
.forge-cutout--rectangle .forge-cutout__shape {
	grid-template-columns: 112px minmax(0, 1fr) 112px;
	grid-template-rows: 112px minmax(0, 1fr) 96px;
}

.forge-cutout--rectangle .forge-cutout__card {
	min-width: calc(112px + 112px + 1px);
	min-height: calc(112px + 96px + 1px);
	/*
	 * Rectangle's feet are bottom-left/bottom-right, not top, and the card's
	 * top/bottom edges are solid color almost immediately for the center-x
	 * range - top/bottom padding can stay modest. Left and right, though,
	 * are only solid within their innermost pixels; confirmed via a real
	 * rendered pixel-color scan that the 112px side columns are otherwise
	 * transparent (only their bottom 96px shows the light foot) for their
	 * full height, so content needs the full 112px + a buffer to stay clear.
	 * Top/bottom are already fully safe at any size and stay modest (50px)
	 * rather than reading as excess empty space above/below the content.
	 */
	padding: 50px 150px 50px 150px;
}

/*
 * Flush against the image edge, per variant - this is what makes the fixed
 * "feet" baked into the shape read as running into the photo above/beside
 * them, no manual overlap margin needed. Placed in the same grid cell as
 * .forge-cutout__bg (see above) instead of `position: absolute`, so the
 * card can't silently overflow past a wrapper sized only for the photo.
 */
.forge-cutout--has-bg .forge-cutout__card {
	grid-area: 1 / 1 / -1 / -1;
	z-index: 2;
	align-self: end;
}

.forge-cutout--has-bg.forge-cutout--square .forge-cutout__card {
	justify-self: start;
}

.forge-cutout--has-bg.forge-cutout--rectangle .forge-cutout__card {
	justify-self: center;
}

/*
 * The "Rand" (border) style control draws a straight-edged box border on
 * .forge-cutout__card, but on desktop/tablet with a background image the
 * card's real visible silhouette (rounded corners + notched "feet") is a
 * separate 9-slice SVG layer drawn behind it, not this box's own shape -
 * .forge-cutout__card has no border-radius at all here. A plain border can
 * only ever trace the rectangle, so it cuts straight across where the real
 * shape curves or has a foot cut out of it, instead of following it -
 * confirmed live (screenshot from the actual site: a square-cornered line
 * floating disconnected from the rounded photo notches). There's no way to
 * make a CSS box-model border hug that silhouette, so it's suppressed here
 * entirely rather than shipping a border that's guaranteed to look broken.
 * min-width media query (not an unscoped rule) so it never touches mobile,
 * where .forge-cutout__card IS already a plain flat rounded rect that a
 * border traces correctly - see the mobile media query further down, where
 * this simply doesn't apply and the control's own border renders normally.
 *
 * Tablet-portrait (768-1024px, portrait orientation) is deliberately excluded
 * too, alongside mobile: it falls back to the same stacked/flat-rect layout
 * below (see the stacked media query's own comment for why), so a border
 * there is just as correct as it is on mobile. Only "real" desktop widths and
 * tablet-LANDSCAPE keep the overlapping 9-slice layout that this rule exists
 * to protect.
 */
@media (min-width: 1025px), (min-width: 768px) and (orientation: landscape) {
	.forge-cutout--has-bg .forge-cutout__card {
		border: none !important;
	}
}

.forge-cutout__content {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 16px;
	min-width: 0;
	max-width: 100%;
}

/*
 * Title/subtitle/USPs are grouped in their own flex column so the "button
 * naast tekst" (inline) layout below can treat them as a single row item
 * sitting next to the button, without changing their own internal spacing.
 * Same 16px gap as .forge-cutout__content used between these items before
 * this wrapper existed, so the stacked (default) layout renders identically.
 */
.forge-cutout__text {
	display: flex;
	flex-direction: column;
	gap: 16px;
	min-width: 0;
	max-width: 100%;
}

/*
 * width:fit-content so the title/subtitle block shrinks to its own content
 * instead of stretching across the full available width, so .forge-cutout__
 * card's justify-content:center has real slack to center the block within
 * a card that's set wider than the content needs.
 *
 * Caveat (fundamental CSS limitation, not fixable with a CSS-only trick):
 * shrink-to-fit sizing (which is what fit-content, display:table and plain
 * block auto-width all reduce to under the hood) is defined as min(max
 * (min-content, available), max-content) - if the text's unbroken max-
 * content width exceeds the available space and the browser has to
 * AUTO-wrap it, the box ends up exactly at the available-width ceiling, not
 * at the width of the actual widest wrapped line, because that formula has
 * no notion of "wrap first, then measure." A manual line break (<br>, which
 * the title field supports) sidesteps this entirely: with an explicit break
 * the max-content width becomes the width of the longer authored line, and
 * fit-content then hugs it correctly.
 */
.forge-cutout__title,
.forge-cutout__subtitle {
	width: fit-content;
	max-width: 100%;
}

/*
 * The "left" variant (title + USP checklist + button) reads as one
 * left-aligned block in the reference designs - the checklist was already
 * left-aligned internally, but the title and button stayed centered by the
 * base rule above, creating a mismatched look where the title's centered
 * line didn't line up with the checkmarks under it.
 */
.forge-cutout--left .forge-cutout__content {
	align-items: flex-start;
	text-align: left;
}

/*
 * "Positie knop: Naast de tekst" - the text block and button sit side by
 * side on one row instead of stacked. flex-wrap is a safety net for very
 * narrow containers, but the real fix for the button not being forced onto
 * its own line is on .forge-cutout__text below: a flex item with the
 * default flex-basis:auto is sized (for wrap-decision purposes) off its
 * unwrapped max-content width - for a full sentence that's easily wider
 * than the space left after the button, so the browser wrapped the button
 * to a new line even though the text could have shrunk to fit (confirmed
 * via computed styles + bounding boxes: flex-direction was already "row",
 * the button just landed on its own line below). flex-basis:0 + flex-grow:1
 * makes the text item's width purely a function of the remaining space
 * next to the button instead, which is what actually keeps them on one row.
 */
.forge-cutout--button-inline .forge-cutout__content {
	flex-direction: row;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	row-gap: 16px;
	column-gap: 24px;
}

.forge-cutout--button-inline .forge-cutout__text {
	flex: 1 1 0%;
	min-width: 0;
}

/*
 * !important: overrides the "Uitlijning" style control's align-self
 * (emitted by Elementor as {{WRAPPER}}-scoped CSS, loaded after this
 * stylesheet) in case an instance already has a non-"Standaard" value saved
 * from before switching to inline mode - see the PHP condition on
 * 'button_alignment' for why that control's own axis stops making sense
 * once the button sits beside the text instead of below it.
 */
.forge-cutout--button-inline .forge-cutout__button {
	margin-top: 0;
	flex-shrink: 0;
	align-self: center !important;
}

.forge-cutout__title {
	margin: 0;
	font-size: 32px;
	font-weight: 700;
	line-height: 1.2;
	color: #f6f6f1;
}

.forge-cutout__subtitle {
	font-size: 16px;
	line-height: 1.5;
	color: #f6f6f1;
}

.forge-cutout__usps {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
	margin: 0;
	padding: 0;
	list-style: none;
	/*
	 * min-width:0 on this and the two rules below: flex items default to
	 * min-width:auto, which (combined with align-items:flex-start instead
	 * of stretch, needed for left-aligned checklist text) lets each level
	 * assert its own unwrapped max-content width instead of shrinking to
	 * fit - with the card's overflow:visible, a long USP line then spilled
	 * out past the card's right edge instead of wrapping.
	 */
	min-width: 0;
	max-width: 100%;
}

.forge-cutout__usp {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: 14px;
	color: #f6f6f1;
	min-width: 0;
	max-width: 100%;
}

.forge-cutout__usp span {
	min-width: 0;
	overflow-wrap: break-word;
}

.forge-cutout__usp-icon {
	flex: 0 0 16px;
	color: #f6f6f1;
	/*
	 * font-size only affects the custom-icon path (Elementor renders picked
	 * icons, e.g. Font Awesome, as inline SVG with a text-sized viewBox on
	 * this install) - the default checkmark is inline SVG with explicit
	 * width/height and ignores font-size entirely, so this is a no-op for
	 * the untouched default look.
	 */
	font-size: 16px;
	line-height: 1;
}

/*
 * Elementor's icon-picker SVG output has no fill attribute of its own
 * (confirmed via rendered markup: a bare <path> with no fill/currentColor),
 * so it falls back to the SVG default of solid black instead of picking up
 * the color set above - unlike the default checkmark, which explicitly uses
 * stroke="currentColor" and therefore already respects it without this
 * rule. Only targets the custom-icon path (a descendant svg), not the
 * default checkmark (which the class is directly on, not a parent of).
 */
.forge-cutout__usp-icon svg {
	fill: currentColor;
}

.forge-cutout__button {
	display: inline-flex;
	align-items: center;
	/*
	 * space-between rather than flex-start: with the button's default
	 * shrink-to-content width this is a no-op (no free space between the two
	 * items to distribute, so it renders identically to before), but once
	 * "Breedte knop"/"Volledige breedte" gives the button more width than its
	 * content needs, this is what pins the text to the left edge and the
	 * icon to the right edge instead of leaving them bunched together with
	 * empty space on one side.
	 */
	justify-content: space-between;
	gap: 8px;
	margin-top: 8px;
	padding: 14px 24px;
	background-color: #ec4b26;
	color: #ffffff;
	font-size: 15px;
	font-weight: 700;
	text-decoration: none;
	border-radius: 30px;
	transition: background-color 0.2s ease, color 0.2s ease;
}

/*
 * inline-block: a plain (non-replaced) inline element is not a "transformable
 * element" per the CSS Transforms spec - browsers silently ignore `transform`
 * on a bare <span> without this.
 */
.forge-cutout__button > span {
	display: inline-block;
	transition: transform 0.2s ease;
}

.forge-cutout__button-icon {
	display: inline-flex;
	transition: transform 0.2s ease;
}

/* Subtle inward slide on hover: text and icon nudge toward each other instead of the icon sliding away. */
.forge-cutout__button:hover > span {
	transform: translateX(3px);
}

.forge-cutout__button:hover .forge-cutout__button-icon {
	transform: translateX(-3px);
}

/*
 * Also matches tablet-PORTRAIT (768-1024px wide, e.g. an iPad held upright):
 * Elementor's own "tablet" band spans both orientations, and tablet-landscape
 * has enough width for the desktop overlap layout below to still work fine,
 * but tablet-portrait doesn't - the card/button overflow past the screen
 * edge there otherwise. Reusing this exact block (rather than a second,
 * separately-maintained one) means tablet-portrait gets 100% the same
 * stacked treatment as mobile - same card width/positioning, same shape
 * scale-down, same safe padding, same button-inline fallback.
 */
@media (max-width: 767px), (max-width: 1024px) and (orientation: portrait) {
	/* Scale the fixed slice tracks down proportionally, feet stay mutually equal. */
	.forge-cutout--square .forge-cutout__shape {
		grid-template-columns: calc(96px * 0.65) minmax(0, 1fr) calc(208px * 0.65);
		grid-template-rows: calc(208px * 0.65) minmax(0, 1fr) calc(96px * 0.65);
	}

	.forge-cutout--rectangle .forge-cutout__shape {
		grid-template-columns: calc(112px * 0.65) minmax(0, 1fr) calc(112px * 0.65);
		grid-template-rows: calc(112px * 0.65) minmax(0, 1fr) calc(96px * 0.65);
	}

	/*
	 * Safety ceiling for every scenario, with or without a background image:
	 * if "Breedte kaart" was set to a desktop pixel value (e.g. 600px) and
	 * the mobile tier of that same responsive control was left unset,
	 * Elementor's desktop rule still applies at every width (there's no
	 * mobile-tier rule to take over), and its {{WRAPPER}}-scoped selector
	 * outranks a plain class - so the card would render wider than the
	 * phone screen and overflow the container. max-width doesn't fight a
	 * smaller intentional width (mobile or desktop), it only ever clips a
	 * width that's too big for the viewport.
	 */
	.forge-cutout__card {
		max-width: 100% !important;
	}

	/*
	 * With a background image, mobile drops the desktop "card overlaps the
	 * photo, flush against an edge" treatment (the feet reading as running
	 * into the photo needs room the photo doesn't have at mobile widths) for
	 * two stacked, non-overlapping sections instead: photo on top, card
	 * below. The photo height comes from the same --forge-cutout-bg-height
	 * variable as the desktop rule above (set by "Hoogte achtergrond", which
	 * is a normal per-breakpoint responsive control - the 50vh here is only
	 * the FALLBACK for an instance that never touches the mobile tier, not a
	 * hardcoded mobile height). A previous version hardcoded 50vh directly
	 * with !important, which silently ignored the control at this breakpoint
	 * entirely - confirmed live (the control showed 200px, the rendered
	 * photo stayed the same regardless of what it was set to). The card row
	 * is plain `auto` (pure content height), NOT tied to the photo height at
	 * all - an earlier version forced a 50vh floor on the card row too so
	 * short content still got a "balanced" 50/50 split, but combined with
	 * the card's `align-self` stretching it to fill that row, short content
	 * (e.g. just a title/subtitle/button, no USPs) ended up centered inside
	 * a box far taller than its own content, reading as a large,
	 * unexplained gap above/below the text. `auto` makes the row (and the
	 * visible card) exactly as tall as its content, whatever that content
	 * is - still free to grow taller for a long USP list, just never
	 * artificially taller than needed.
	 *
	 * height uses vh here (not %) for the fallback: percentage row/height
	 * values need a definite parent size to resolve against - vh sidesteps
	 * that by resolving directly off the viewport.
	 */
	.forge-cutout--has-bg {
		grid-template-columns: minmax(0, 1fr) !important;
		grid-template-rows: var(--forge-cutout-bg-height, 50vh) auto !important;
	}

	.forge-cutout--has-bg .forge-cutout__bg {
		grid-area: 1 / 1 / 2 / 2;
		height: var(--forge-cutout-bg-height, 50vh) !important;
	}

	/*
	 * width/max-width read the same --forge-cutout-card-width variable as
	 * the base rule (see there), falling back to 100% - not fit-content -
	 * when untouched: a fixed-width card here would leave the photo above
	 * it wider than the card below it, which reads as broken, not
	 * intentional. !important is still needed even with a shared variable:
	 * it's what makes 100% win over the base rule's OWN different fallback
	 * (fit-content) for an untouched control - confirmed live, an earlier
	 * version hardcoded a bare "100%" here with no variable at all, which
	 * meant an explicit MOBILE "Breedte kaart" value on a has-bg card was
	 * silently ignored (the !important always won regardless of what the
	 * control said), never actually configurable despite the control being
	 * visible and seemingly working. Once the variable IS set (by the
	 * control), both this rule and the base rule resolve to the identical
	 * value, so which one "wins" no longer matters.
	 *
	 * Height is deliberately NOT forced/capped here - the card is free to
	 * grow for its own content (or a left-over desktop "Hoogte kaart"
	 * min-height), same reasoning as the row track above.
	 *
	 * align-self: start (not stretch) - now that the row is `auto`-sized to
	 * the card's own content, stretch vs. start renders identically in the
	 * common case, but start is the semantically correct one: it means the
	 * card's box is only ever as tall as ITS OWN content dictates, never
	 * pulled taller by its grid row for any other reason.
	 */
	.forge-cutout--has-bg .forge-cutout__card {
		grid-area: 2 / 1 / 3 / 2;
		width: var(--forge-cutout-card-width, 100%) !important;
		/*
		 * min(): this rule's own higher specificity (vs. the general
		 * ".forge-cutout__card { max-width:100%!important; }" safety cap a
		 * few rules up) means an explicit but oversized mobile "Breedte
		 * kaart" (e.g. a stray 900px) would otherwise win outright here and
		 * visually overflow past the screen edge (clipped by the page, not
		 * the widget - not truly "broken", but reads that way). min() keeps
		 * that same 100% ceiling for THIS rule specifically, without
		 * blocking a legitimate smaller explicit value the way a flat
		 * "100%" fallback would.
		 */
		max-width: min(var(--forge-cutout-card-width, 100%), 100%) !important;
		align-self: start;
	}

	.forge-cutout--has-bg.forge-cutout--square .forge-cutout__card,
	.forge-cutout--has-bg.forge-cutout--rectangle .forge-cutout__card {
		justify-self: stretch;
	}

	/*
	 * Mobile equivalent of the same-named rules outside this media query -
	 * see there for why both shapes recolor the foot (not just rectangle)
	 * and why square also gets a plain rounded-rect background-color.
	 */
	.forge-cutout--has-bg .forge-cutout__slice path {
		fill: var(--forge-cutout-card-color);
	}

	.forge-cutout--has-bg.forge-cutout--rectangle .forge-cutout__card {
		background-color: var(--forge-cutout-card-color) !important;
	}

	.forge-cutout--has-bg.forge-cutout--square .forge-cutout__card {
		background-color: var(--forge-cutout-card-color) !important;
		border-radius: 24px;
	}

	/*
	 * The desktop safe-padding values (130-150px) are sized for the
	 * desktop-scale shape tracks. The shape's own fixed corner tracks are
	 * already scaled by 0.65 above for mobile, so the matching unsafe zone
	 * shrinks by the same factor - keeping the desktop px values here would
	 * eat a disproportionate chunk of a ~350-400px-wide phone screen and
	 * force extra text wrapping, making the (now height-constrained) content
	 * taller than it needs to be.
	 */
	.forge-cutout--square .forge-cutout__card {
		padding: 85px 85px 50px 50px;
	}

	.forge-cutout--rectangle .forge-cutout__card {
		padding: 50px 85px 50px 85px;
	}

	/* No room for text-beside-button on a phone screen - fall back to stacked, left-aligned. */
	.forge-cutout--button-inline .forge-cutout__content {
		flex-direction: column;
		align-items: flex-start;
	}

	.forge-cutout--button-inline .forge-cutout__button {
		margin-top: 8px;
	}
}
