/*** Module: Scrolling Value Props ***/

/* Coordinated with script.js `svp` block. */

/* The content can only ever be about as tall as it is wide (the media is
   width-constrained by its 748/756 ratio), so a flat viewport-height stage strands it
   in dead space on a tall, narrow viewport — ~400px above and below on iPad Pro
   portrait. Capping against vw hugs the content there and is a no-op on any landscape
   screen, where the viewport height is always the smaller of the two.

   svh, not vh: on mobile/tablet browsers vh is the LARGE viewport (chrome hidden), so
   a vh-sized stage overflows below the fold whenever the URL bar is showing — and
   because the stage is pinned, scrolling can't reveal the cut-off part. svh is the
   chrome-visible height, so it fits in either state; dvh would resize the stage
   mid-scroll as the chrome collapses. Every length in the stage's scroll math uses
   the same unit or the pinning drifts. */
.module.scrolling-value-props {
	--svp-stage: min(100svh, 85vw);
	position: relative;
}

/* top re-centres a capped stage in the viewport; resolves to 0 at the full height. */
.module.scrolling-value-props .svp-sticky {
	height: var(--svp-stage);
	position: sticky;
	top: calc((100svh - var(--svp-stage)) / 2);
	z-index: 1; /* above .svp-steps so content stays interactive */
}

/* Centre within the space below the fixed header (not the raw viewport) so the
   content isn't biased high.

   The block padding is tolerance, not taste. The media's height is width-derived
   (748/756 of its column), so on a short landscape viewport it grows to fill this
   box exactly — flush under the header, flush against the fold — and any gap
   between the browser's reported svh and its real visible area then clips the
   animation for good, because the pinned stage can't be scrolled to reveal it.
   header-height + text-spacing-large is the same clearance html's scroll-padding-top
   uses to land an anchor clear of the sticky chrome; the matching bottom padding
   keeps the content centred, so nothing moves on a viewport with room to spare. */
.module.scrolling-value-props .svp-sticky .container.grid {
	align-content: center;
	height: 100%;
	padding-bottom: var(--text-spacing-large);
	padding-top: calc(var(--header-height) + var(--text-spacing-large));
}

/* Invisible scroll-distance + observer targets — must never catch clicks on the content beneath. */
.module.scrolling-value-props .svp-steps {
	margin-top: calc(var(--svp-stage) * -1);
	pointer-events: none;
}

/* Matches --svp-stage's unit — one step of scroll must equal one stage of travel. */
.module.scrolling-value-props .svp-step {
	height: 100svh;
}

.module.scrolling-value-props .svp-text {
	display: flex;
	flex-direction: column;
	gap: var(--text-spacing-xsmall);
	grid-column: 1 / span 6;
	justify-content: center;
	margin-right: calc(var(--gap) * -1);
}

/* Image right (default): 24px from the viewport edge, 24px off the text. */
.module.scrolling-value-props .svp-media {
	aspect-ratio: 748 / 756;
	grid-column: 7 / span 6;
	height: 100%;
	margin-left: var(--text-spacing-small);
	margin-right: calc(var(--viewport-edge) + var(--text-spacing-small));
	overflow: hidden;
	position: relative;
}

/* Image left: mirror the edge/text spacing to the opposite sides. */
.module.scrolling-value-props:not(.style-proof-points-scroll)[data-image-position="left"] .svp-media {
	grid-column: 1 / span 6;
	margin-left: calc(var(--viewport-edge) + var(--text-spacing-small));
	margin-right: var(--text-spacing-small);
}

.module.scrolling-value-props:not(.style-proof-points-scroll)[data-image-position="left"] .svp-text {
	grid-column: 7 / span 6;
	margin-left: calc(var(--gap) * -1);
	margin-right: 0;
}

/* Crossfade rotators stack children in one grid cell; .is-active fades in. */
.module.scrolling-value-props .svp-rotator,
.module.scrolling-value-props .svp-copy-rotator,
.module.scrolling-value-props .svp-proof-rotator,
.module.scrolling-value-props .svp-media {
	display: grid;
}

.module.scrolling-value-props .svp-word,
.module.scrolling-value-props .svp-copy,
.module.scrolling-value-props .svp-proof,
.module.scrolling-value-props .svp-frame {
	grid-area: 1 / 1;
	opacity: 0;
	pointer-events: none; /* stacked-but-hidden items mustn't catch clicks */
	transition: opacity 0.4s ease;
}

.module.scrolling-value-props .svp-word.is-active,
.module.scrolling-value-props .svp-copy.is-active,
.module.scrolling-value-props .svp-proof.is-active,
.module.scrolling-value-props .svp-frame.is-active {
	opacity: 1;
	pointer-events: auto;
}

.module.scrolling-value-props .svp-copy-rotator {
	position: relative;
}

/* Height tracks the active copy only — others overlay out of flow so a longer
   copy's wrapped height doesn't get reserved for every one (same trick as .svp-rotator). */
.module.scrolling-value-props .svp-copy-rotator .svp-copy {
	left: 0;
	position: absolute;
	top: 0;
	width: 100%;
}

.module.scrolling-value-props .svp-copy-rotator .svp-copy.is-active {
	position: relative;
}

.module.scrolling-value-props .svp-proof-rotator {
	margin-top: var(--text-spacing-small);
}

.module.scrolling-value-props .svp-word {
	font-weight: 400;
}

/* Only orange the predicate when there's a prefix to contrast against — otherwise let WYSIWYG
   drive emphasis. Scoped to .predicate so the trailing period keeps the base text colour. */
.module.scrolling-value-props .svp-lede:has(.svp-prefix) .svp-word .predicate {
	color: var(--orange);
}

/* Height tracks the active word only — others overlay it out of flow so short predicates don't reserve a taller one's space. */
.module.scrolling-value-props .svp-rotator {
	position: relative;
}

.module.scrolling-value-props .svp-rotator .svp-word {
	left: 0;
	position: absolute;
	top: 0;
	width: 100%;
}

.module.scrolling-value-props .svp-rotator .svp-word.is-active {
	position: relative;
}

/* script.js flips --svp-dir and toggles .is-leaving to drive the directional rotate. */
.module.scrolling-value-props .svp-word.is-active {
	animation: svp-word-enter 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

.module.scrolling-value-props .svp-word.is-leaving {
	animation: svp-word-leave 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}

/* --svp-dir: 1 = rise (down-scroll), -1 = descend (up-scroll). */
@keyframes svp-word-enter {
	from {
		opacity: 0;
		transform: translateY(calc(var(--svp-dir, 1) * 0.4em));
	}
	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes svp-word-leave {
	from {
		opacity: 1;
		transform: translateY(0);
	}
	to {
		opacity: 0;
		transform: translateY(calc(var(--svp-dir, 1) * -0.4em));
	}
}

@media (prefers-reduced-motion: reduce) {

	.module.scrolling-value-props .svp-word.is-active,
	.module.scrolling-value-props .svp-word.is-leaving {
		animation: none;
	}

	/* The scroll-driven crossfade switches content instantly rather than fading. */
	.module.scrolling-value-props :is(.svp-word, .svp-copy, .svp-proof, .svp-frame) {
		transition: none;
	}

}

.module.scrolling-value-props .svp-lede {
	display: flex;
	flex-direction: column;
}

.module.scrolling-value-props .svp-copy {
	align-items: flex-start;
	display: flex;
	flex-direction: column;
	gap: var(--text-spacing-medium);
	padding-right: var(--text-spacing-large);
}

/* Media right (default): the contained image hugs the text it sits beside, so it's
   left-aligned in its box — and mirrored when the media moves to the left. */
.module.scrolling-value-props .svp-frame img,
.module.scrolling-value-props .svp-frame .media-source {
	aspect-ratio: 748 / 756;
	height: 100%;
	left: 0;
	object-fit: contain;
	object-position: left center;
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	width: 100%;
	max-height: 1200px;
}

.module.scrolling-value-props[data-image-position="left"] .svp-frame img,
.module.scrolling-value-props[data-image-position="left"] .svp-frame .media-source {
	object-position: right center;
}

/* "Product" image display — screenshot on the teal gradient panel. Mirrors the
   global .media.product; SVP media can't reuse that selector directly because
   the crossfade stage owns each frame's sizing and absolute fill. */
.module.scrolling-value-props :is(.svp-frame, .svp-point-media, .svp-stacked-media).product {
	aspect-ratio: 748 / 756;
	background: var(--teal-gradient);
	overflow: hidden;
	position: relative;
}

.module.scrolling-value-props :is(.svp-frame, .svp-point-media, .svp-stacked-media).product img {
	filter: drop-shadow(8px 8px 24px rgba(0, 0, 0, 0.14));
	height: 100%;
	left: 0;
	object-fit: contain;
	padding: var(--text-spacing-small);
	position: absolute;
	top: 0;
	transform: none;
	width: 100%;
}

/* Anchor the screenshot to a corner — drop the padding on the anchored sides. */
.module.scrolling-value-props :is(.svp-frame, .svp-point-media, .svp-stacked-media).product.anchor-top-left img {
	object-position: top left;
	padding: 0 var(--text-spacing-small) var(--text-spacing-small) 0;
}

.module.scrolling-value-props :is(.svp-frame, .svp-point-media, .svp-stacked-media).product.anchor-top-right img {
	object-position: top right;
	padding: 0 0 var(--text-spacing-small) var(--text-spacing-small);
}

.module.scrolling-value-props :is(.svp-frame, .svp-point-media, .svp-stacked-media).product.anchor-bottom-left img {
	object-position: bottom left;
	padding: var(--text-spacing-small) var(--text-spacing-small) 0 0;
}

.module.scrolling-value-props :is(.svp-frame, .svp-point-media, .svp-stacked-media).product.anchor-bottom-right img {
	object-position: bottom right;
	padding: var(--text-spacing-small) 0 0 var(--text-spacing-small);
}

/** Stat media — centres the shared orbit graphic (global) and overlays its
    count-up figure + caption. The orbit visual + animation live in style.css. **/

.module.scrolling-value-props .svp-frame:has(.big-stat-graphic),
.module.scrolling-value-props .svp-point-media:has(.big-stat-graphic),
.module.scrolling-value-props .svp-stacked-media:has(.big-stat-graphic) {
	align-items: center;
	display: flex;
	justify-content: center;
}

/* Figure + caption are one stack centred on the RING (cx 285 / cy 307 of the 602×592
   viewBox = 47.34% / 51.86%) — not the graphic box, which the decorative circles pull
   off-centre. Type comes from the global .big-stat; cqw scales the caption. */
/* Overlay geometry, figure colour and caption type are global (style.css, beside
   .big-stat-graphic) — shared with the stat tile. Only the crossfade-replay
   motion below is specific to this module. */

@media (prefers-reduced-motion: no-preference) {

	/* Keyframes (not transitions) so the rise replays on each crossfade re-activation
	   when script.js toggles .animated-in + reflows — mirrors the orbit ring/dot. */
	.module.scrolling-value-props .big-stat-number,
	.module.scrolling-value-props .big-stat-caption {
		opacity: 0;
		transform: translateY(20px);
	}

	.module.scrolling-value-props .big-stat-graphic.animated-in .big-stat-number {
		animation: big-stat-rise 700ms cubic-bezier(0.4, 0, 0.2, 1) 400ms forwards;
	}

	.module.scrolling-value-props .big-stat-graphic.animated-in .big-stat-caption {
		animation: big-stat-rise 700ms cubic-bezier(0.4, 0, 0.2, 1) 550ms forwards;
	}

	@keyframes big-stat-rise {
		to {
			opacity: 1;
			transform: translateY(0);
		}
	}

}

.module.scrolling-value-props .stat {
	align-items: center;
	column-gap: var(--text-spacing-xsmall);
	display: grid;
	grid-template-columns: auto 1fr;
}

.module.scrolling-value-props .stat-text {
	display: flex;
	flex-direction: column;
}

/* Flat lavender is a fallback — angular gradients aren't possible on SVG strokes. */
.module.scrolling-value-props .metric-icon {
	--metric-icon-size: 40px;
	--metric-icon-accent: var(--electric-lavender);
	--metric-icon-arrow-color: var(--electric-lavender);
}

/* Default plus nearly fills the ring — shrink just the glyph so it reads as a
   badge with breathing room inside the ring. fill-box keeps the scale centred
   on the path's own box (32,32 = ring centre). */
.module.scrolling-value-props .metric-icon.type-plus .plus {
	transform: scale(0.7);
	transform-box: fill-box;
	transform-origin: center;
}

/* Re-fire the chart bar climb on every proof activation (not just on SVP's
   first viewport entry — JazzyScroll's .animated-in fires once for all stacked
   proofs at the same time and animation-fill-mode: both then locks the bars at
   scaleY(1), so subsequent proofs never re-animate). Drive off .is-active
   instead so each swap triggers a fresh run. */
@media (prefers-reduced-motion: no-preference) {

	.module.scrolling-value-props .metric-icon.type-chart .bar {
		animation-name: none;
	}

	/* Re-fire on each proof activation. Three layouts, gated the same way: the
	   rotator's active card (.svp-proof.is-active — re-fires on every swap), and
	   the two scroll-driven layouts (.svp-proof-point subpages, .svp-stacked-prop
	   mobile) that JazzyScroll marks .animated-in as each enters view. Without the
	   proof-point context the subpages bars stayed disabled by the rule above. */
	.module.scrolling-value-props :is(.svp-proof.is-active, .svp-proof-point.animated-in, .svp-stacked-prop.animated-in) .metric-icon.type-chart .bar {
		animation: metric-icon-bar-grow 0.55s cubic-bezier(0.5, 0, 0.1, 1) both;
	}

	.module.scrolling-value-props :is(.svp-proof.is-active, .svp-proof-point.animated-in, .svp-stacked-prop.animated-in) .metric-icon.type-chart .bar:nth-child(1) {
		animation-delay: 0.00s;
	}
	.module.scrolling-value-props :is(.svp-proof.is-active, .svp-proof-point.animated-in, .svp-stacked-prop.animated-in) .metric-icon.type-chart .bar:nth-child(2) {
		animation-delay: 0.08s;
	}
	.module.scrolling-value-props :is(.svp-proof.is-active, .svp-proof-point.animated-in, .svp-stacked-prop.animated-in) .metric-icon.type-chart .bar:nth-child(3) {
		animation-delay: 0.16s;
	}
	.module.scrolling-value-props :is(.svp-proof.is-active, .svp-proof-point.animated-in, .svp-stacked-prop.animated-in) .metric-icon.type-chart .bar:nth-child(4) {
		animation-delay: 0.24s;
	}
	.module.scrolling-value-props :is(.svp-proof.is-active, .svp-proof-point.animated-in, .svp-stacked-prop.animated-in) .metric-icon.type-chart .bar:nth-child(5) {
		animation-delay: 0.32s;
	}
	.module.scrolling-value-props :is(.svp-proof.is-active, .svp-proof-point.animated-in, .svp-stacked-prop.animated-in) .metric-icon.type-chart .bar:nth-child(6) {
		animation-delay: 0.40s;
	}

}

.module.scrolling-value-props .stat-number {
	color: var(--electric-lavender);
}

.module.scrolling-value-props .svp-quote .heading-6 {
	color: var(--electric-lavender);
}

/* Grid-areas place the headshot left while DOM stays SR-friendly (quote, attribution, then decorative headshot). */
.module.scrolling-value-props .svp-quote.has-headshot {
	align-items: center;
	display: grid;
	grid-template-areas:
		"headshot quote"
		"headshot attribution";
	gap: 2px var(--text-spacing-xsmall);
	grid-template-columns: auto 1fr;
}

.module.scrolling-value-props .svp-quote.has-headshot .heading-6 {
	grid-area: quote;
}
.module.scrolling-value-props .svp-quote.has-headshot .medium-text {
	grid-area: attribution;
}
.module.scrolling-value-props .svp-quote-headshot {
	grid-area: headshot;
}

/* overflow: hidden on the <picture> is what clips the inner img to border-radius. */
.module.scrolling-value-props .svp-quote-headshot {
	border-radius: 50%;
	display: block;
	height: 60px;
	overflow: hidden;
	width: 60px;
}

.module.scrolling-value-props .svp-quote-headshot img {
	height: 100%;
	object-fit: cover;
	width: 100%;
}

.module.scrolling-value-props .jazzy-dots {
	justify-content: flex-start;
	margin-left: 9px;
	margin-top: var(--text-spacing-xsmall);
}

.module.scrolling-value-props .jazzy-dot {
	background: var(--electric-lavender);
}

/* Mobile-only stacked layout — hidden until the desktop stage drops out at 1100. */
.module.scrolling-value-props .svp-stacked {
	display: none;
}

/** Style: proof-points-scroll **/

/* --svp-slot drives both proof-point height and the media's centring lead-in — keep tied. */
.module.scrolling-value-props.style-proof-points-scroll {
	/*padding-block: var(--module-spacing-medium);*/
	--svp-slot: 50vh;
}

/* Same grid/size/spacing as the default (Outcomes) media; sticky positioning is
   this style's own. script.js sets --svp-media-top/--svp-media-lead from measured
   height and clears the transform; the fallbacks + transform centre pre-JS. */
.module.scrolling-value-props.style-proof-points-scroll .svp-media {
	/*aspect-ratio: auto;*/
	align-self: start;
	grid-column: 7 / span 6;
	grid-row: 1;
	/* The base 100% would resolve against this row — which is as tall as the whole
	   proof-points list — so the media measures in the thousands and drives
	   solveLead() to a runaway lead. Here it's content-sized, capped below. */
	height: auto;
	/* Fallback is load-bearing: --svp-media-top isn't set until script.js measures,
	   and an invalid var() makes the whole calc() invalid, dropping the cap entirely.
	   svh so the cap is the height actually visible with browser chrome showing.
	   The extra step is the same fold tolerance the pinned stage above takes, and for
	   the same reason: script.js clamps --svp-media-top below the pinned chrome, so on
	   a short landscape viewport this cap would otherwise land the media's bottom edge
	   exactly on the fold with nothing to absorb a browser-chrome discrepancy. */
	max-height: calc(100svh - var(--svp-media-top, 50svh) - var(--text-spacing-large));
	margin-left: var(--text-spacing-small);
	margin-right: calc(var(--viewport-edge) + var(--text-spacing-small));
	margin-top: var(--svp-media-lead, calc(var(--svp-slot) / 2));
	position: sticky;
	top: var(--svp-media-top, 50vh);
	transform: translateY(-50%);
}

/* Per-point media is mobile-only; desktop uses the shared sticky .svp-media stage. */
.module.scrolling-value-props.style-proof-points-scroll .svp-point-media {
	display: none;
}

/* Full-bleed images fill the sticky media box instead of letterboxing; product
   images keep their contained-on-panel treatment (:not(.product) = the full display). */
.module.scrolling-value-props.style-proof-points-scroll .svp-frame:not(.product) img {
	object-fit: cover;
}

.module.scrolling-value-props.style-proof-points-scroll .svp-proof-points {
	display: flex;
	flex-direction: column;
	grid-column: 1 / span 6;
	grid-row: 1;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* One viewport-tall slot per point gives the JS observer one clean centring moment per frame to crossfade against. */
.module.scrolling-value-props.style-proof-points-scroll .svp-proof-point {
	align-items: flex-start;
	display: flex;
	flex-direction: column;
	gap: var(--text-spacing-xsmall);
	justify-content: center;
	min-height: var(--svp-slot);
	padding-block: var(--module-spacing-xlarge);
}

/* A media taller than a point can't be pulled up or down (script.js floors its lead
   at 0), so the opening and closing points absorb the offset instead — otherwise
   each centres in its own box while the media's centre sits far off it, stranding
   the first copy high and the last copy low. Solved per point from the MEASURED
   heights (not --svp-slot, which is only their min-height): the two ends usually
   hold different copy, so one shared value can't centre both. */
.module.scrolling-value-props.style-proof-points-scroll .svp-proof-point:first-child {
	padding-top: calc(var(--module-spacing-xlarge) + var(--svp-point-lead-start, 0px));
}

.module.scrolling-value-props.style-proof-points-scroll .svp-proof-point:last-child {
	padding-bottom: calc(var(--module-spacing-xlarge) + var(--svp-point-lead-end, 0px));
}

.module.scrolling-value-props.style-proof-points-scroll .large-text + .btn {
	margin-top: var(--text-spacing-xsmall);
}

.module.scrolling-value-props.style-proof-points-scroll .svp-cards-wrap {
	margin-top: var(--text-spacing-small);
}

/* Multi-card variant becomes a fade carousel and uses the global .jazzy-fade grid. */
.module.scrolling-value-props.style-proof-points-scroll .svp-proof-cards:not(.jazzy-carousel) {
	display: flex;
	flex-direction: column;
	gap: var(--text-spacing-small);
}

.module.scrolling-value-props.style-proof-points-scroll[data-image-position="left"] .svp-media {
	grid-column: 1 / span 6;
	margin-left: calc(var(--viewport-edge) + var(--text-spacing-small));
	margin-right: var(--text-spacing-small);
}

.module.scrolling-value-props.style-proof-points-scroll[data-image-position="left"] .svp-proof-points {
	grid-column: 7 / span 6;
}

/***************************************************************************************************************************************************************************************/
/* MQ MAX-WIDTH 1200 - Smaller Desktop Sizes / Larger Tablet Sizes */
/***************************************************************************************************************************************************************************************/

@media only screen and (max-width: calc(1200rem / 16)) {

	.module.scrolling-value-props.style-proof-points-scroll .svp-proof-point:first-child {
		padding-top: calc(var(--text-spacing-medium) + var(--svp-point-lead-start, 0px));
	}

	.module.scrolling-value-props.style-proof-points-scroll .svp-proof-point:last-child {
		padding-bottom: calc(var(--text-spacing-medium) + var(--svp-point-lead-end, 0px));
	}

}

/***************************************************************************************************************************************************************************************/
/* MQ MAX-WIDTH 1100 - Mobile Header / Nav */
/***************************************************************************************************************************************************************************************/

@media only screen and (max-width: calc(1100rem / 16)) {

	/* Reclaims the header clearance the narrower stage needs — but keeps the fold
	   tolerance the base rule explains, or the animation goes flush again here. */
	.module.scrolling-value-props .svp-sticky .container.grid {
		padding-top: var(--text-spacing-large);
	}

}

/***************************************************************************************************************************************************************************************/
/* MQ MAX-WIDTH 950 - Tablet Sizes */
/***************************************************************************************************************************************************************************************/

/* Kept in sync with the svpStacked query in script.js. */
@media only screen and (max-width: calc(950rem / 16)) {

	.module.scrolling-value-props .svp-sticky,
	.module.scrolling-value-props .svp-steps {
		display: none;
	}

	.module.scrolling-value-props .svp-stacked {
		display: flex;
		flex-direction: column;
		gap: var(--module-spacing-medium);
		padding-block: var(--module-spacing-medium) var(--module-spacing-small);
	}

	.module.scrolling-value-props .svp-stacked-prop {
		display: flex;
		flex-direction: column;
		row-gap: 0;
	}

	.module.scrolling-value-props .svp-stacked-prop > * + * {
		margin-top: var(--text-spacing-small);
	}

	/* Mirrors the desktop .svp-text rhythm: 16 → 32 → 40, not a uniform gap. */
	.module.scrolling-value-props .svp-stacked-prop > .svp-stacked-lede + .large-text {
		margin-top: var(--text-spacing-xsmall);
	}

	.module.scrolling-value-props .svp-stacked-prop > .large-text + .btn {
		margin-top: var(--text-spacing-small);
	}

	.module.scrolling-value-props .svp-stacked-prop > .btn + .svp-cards-wrap,
	.module.scrolling-value-props .svp-stacked-prop > .large-text + .svp-cards-wrap {
		margin-top: var(--text-spacing-medium);
	}

	.module.scrolling-value-props .svp-stacked-prop > .btn {
		align-self: flex-start;
	}

	.module.scrolling-value-props .svp-stacked-lede:has(.svp-prefix) .svp-stacked-word {
		font-weight: 400;
	}

	.module.scrolling-value-props .svp-stacked-lede:has(.svp-prefix) .svp-stacked-word .predicate {
		color: var(--orange);
	}

	/* Media leads each prop visually; DOM keeps heading-first reading order. Its
	   spacing is a margin-bottom — a margin-top would land above the reordered item. */
	.module.scrolling-value-props .svp-stacked-prop > .svp-stacked-media {
		margin-bottom: var(--text-spacing-medium);
		margin-top: 0;
		order: -1;
	}

	.module.scrolling-value-props .svp-stacked-prop > .svp-stacked-media:has(video) {
		margin-bottom: 0;
	}

	.module.scrolling-value-props .svp-stacked-media img,
	.module.scrolling-value-props .svp-stacked-media video {
		display: block;
		height: auto;
		width: 100%;
	}

	.module.scrolling-value-props.style-proof-points-scroll {
		padding-block: var(--text-spacing-xlarge);
	}

	/* No sticky stage on mobile — each point carries its own media instead. */
	.module.scrolling-value-props.style-proof-points-scroll .svp-media {
		display: none;
	}

	.module.scrolling-value-props.style-proof-points-scroll .svp-point-media {
		display: block;
		order: -1;
		width: 100%;
	}

	.module.scrolling-value-props.style-proof-points-scroll .svp-cards-wrap {
		margin-top: var(--text-spacing-xxsmall);
	}

	.module.scrolling-value-props.style-proof-points-scroll .svp-point-media img,
	.module.scrolling-value-props.style-proof-points-scroll .svp-point-media video {
		display: block;
		height: auto;
		width: 100%;
	}

	/* Image media (full or product) gets breathing room below before the copy. */
	.module.scrolling-value-props.style-proof-points-scroll .svp-point-media:has(img) {
		margin-bottom: var(--text-spacing-xsmall);
	}

	/* The stat orbit's caption sits tight to its baseline — it needs more than an image does. */
	.module.scrolling-value-props.style-proof-points-scroll .svp-point-media:has(.big-stat-graphic) {
		margin-bottom: var(--text-spacing-small);
	}

	.module.scrolling-value-props.style-proof-points-scroll .svp-proof-points,
	.module.scrolling-value-props.style-proof-points-scroll[data-image-position="left"] .svp-proof-points {
		gap: var(--module-spacing-medium);
		grid-column: 1 / -1;
	}

	.module.scrolling-value-props.style-proof-points-scroll .svp-proof-point {
		justify-content: flex-start;
		min-height: auto;
		padding-block: 0;
	}

	/* Stacked — there's no sticky media to centre against, so the end points drop
	   their lead. Echo the :first-child/:last-child selectors: those outrank the
	   padding-block reset above (0,5,0 vs 0,4,0) and would otherwise keep the
	   desktop lead, leaving a huge gap at the top and bottom of the list. */
	.module.scrolling-value-props.style-proof-points-scroll .svp-proof-point:first-child {
		padding-top: 0;
	}

	.module.scrolling-value-props.style-proof-points-scroll .svp-proof-point:last-child {
		padding-bottom: 0;
	}

	.module.scrolling-value-props.style-proof-points-scroll .large-text + .btn {
		margin-top: var(--text-spacing-xxsmall);
	}

}

/***************************************************************************************************************************************************************************************/
/* MQ MAX-WIDTH 650 - Mobile Sizes */
/***************************************************************************************************************************************************************************************/

@media only screen and (max-width: calc(650rem / 16)) {

	/* Video breaks the container to sit edge-to-edge; images + stat graphics keep the
	   gutters. width:auto is load-bearing — the base width:100% pins the box to the
	   container, so the negative margins would shift it rather than widen it. The
	   point-media selector echoes .style-proof-points-scroll to clear the width:100%
	   that style sets at 950 (0,4,0) — without it this override is 0,3,1 and no-ops. */
	.module.scrolling-value-props.style-proof-points-scroll .svp-point-media:has(video),
	.module.scrolling-value-props .svp-stacked-media:has(video),
	.module.scrolling-value-props .svp-stacked-prop > .svp-stacked-media:has(video) {
		margin: 0 var(--viewport-edge);
		width: auto;
	}

}
