/**
 * VIO Social Media Feed — style.css
 *
 * Stacked-deck carousel:
 *  - Active card sits centred on top.
 *  - Next card sits BEHIND active, shifted RIGHT by --vio-sm-peek so only
 *    its RIGHT edge protrudes past active's right side.
 *  - Prev card sits BEHIND active, shifted LEFT by 100% so its right edge
 *    touches active's left edge and its rightmost peek pixels show on the
 *    left strip.
 *  - Far-away cards parked off-screen to the right (translateX(110%)) so
 *    advancing makes them slide in cleanly from the right.
 *
 * Cards stay at opacity 1 — only `transform` animates, so the visible
 * cards GENUINELY SLIDE between positions instead of fading.
 *
 * --vio-sm-peek is set inline on .vio-sm__carousel by render.php (default 24px).
 */

.vio-social-media .vio-sm__body {
	width: 100%;
}

/* ── Carousel container ──────────────────────────────────────────────────── */
.vio-sm__carousel {
	--vio-sm-peek: 24px;
	position: relative;
	width: 100%;
	/* Sized so the whole section (intro + media + caption + section padding +
	   page header) fits within ~900px of vertical space on a 1080p monitor.
	   Media is 1:1 so card width caps card height; 440 keeps the active card
	   under ~540px tall including caption. Tune here if intro height changes. */
	max-width: 440px;
	margin-left: auto;
	margin-right: auto;
	display: flex;
	flex-direction: column;
}

/* Track-wrapper is the clipping window: extends `peek` into the gap each
   side, overflow:hidden clips outside that.                                */
.vio-sm__carousel .vio-carousel-compare__track-wrapper {
	position: relative;
	overflow: hidden;
	width: calc(100% + (var(--vio-sm-peek) * 2));
	margin-left: calc(var(--vio-sm-peek) * -1);
	margin-right: calc(var(--vio-sm-peek) * -1);
	padding-bottom: 20px;
	margin-bottom: -20px;
	cursor: grab;
	/* Container query unit (cqw) on this wrapper lets the arrows pin to the
	   centre of the (square) media tile regardless of card height. The active
	   card is `100cqw - 2*peek` wide; media is 1:1, so its centre is at
	   `(100cqw - 2*peek) / 2` from the top of the card. */
	container-type: inline-size;
}
.vio-sm__carousel .vio-carousel-compare__track-wrapper:active {
	cursor: grabbing;
}

/* Track is just a positioning context. Slides are absolutely stacked. */
.vio-sm__carousel .vio-carousel-compare__track {
	position: relative;
	width: 100%;
}

/* Slide base: every slide is absolutely stacked at the same centred slot.
   Default position is parked off-screen RIGHT so a card sliding in for the
   first time enters from the right edge. */
.vio-sm__carousel .vio-carousel-compare__slide {
	position: absolute;
	top: 0;
	left: var(--vio-sm-peek);
	width: calc(100% - (var(--vio-sm-peek) * 2));
	min-width: 0;
	display: flex;
	flex-direction: column;
	transition: transform 0.4s ease;
	transform: translateX(calc(100% + var(--vio-sm-peek)));
	pointer-events: none;
	z-index: 0;
}
/* Slides further than is-next, parked off-screen RIGHT. */
.vio-sm__carousel .vio-carousel-compare__slide.is-far-next {
	transform: translateX(calc(100% + var(--vio-sm-peek)));
	z-index: 0;
}
/* Slides further than is-prev, parked off-screen LEFT. */
.vio-sm__carousel .vio-carousel-compare__slide.is-far-prev {
	transform: translateX(calc(-100% - var(--vio-sm-peek)));
	z-index: 0;
}

/* Active slide: in normal flow (so the track has real height), centred.
   No box-shadow — the slide is wider than the centered card now (card
   max-width derived from aspect-ratio), so a slide-level shadow would
   show as a faint frame on either side of the reel. */
.vio-sm__carousel .vio-carousel-compare__slide.is-active {
	position: relative;
	left: 0;
	margin-left: var(--vio-sm-peek);
	margin-right: var(--vio-sm-peek);
	transform: translateX(0);
	pointer-events: auto;
	z-index: 3;
	box-shadow: none;
	background: transparent;
}

/* Next: shifted RIGHT by `peek`, scaled to 0.92 from its RIGHT edge so the
   right edge stays flush with the wrapper's right edge as it recedes, and
   nudged DOWN 20px for the stacked-deck depth cue (mirrors 50/50). */
.vio-sm__carousel .vio-carousel-compare__slide.is-next {
	transform: translateX(var(--vio-sm-peek)) translateY(20px) scale(0.92);
	transform-origin: right top;
	z-index: 1;
}

/* Prev: shifted LEFT by `peek`, scaled from LEFT edge so the left edge
   stays flush with the wrapper's left edge, plus the 20px down nudge. */
.vio-sm__carousel .vio-carousel-compare__slide.is-prev {
	transform: translateX(calc(var(--vio-sm-peek) * -1)) translateY(20px) scale(0.92);
	transform-origin: left top;
	z-index: 1;
}

/* Subtle dim on inactive slides for depth (no opacity transition on the
   slide itself — keeps motion reading as sliding, not fading).
   z-index sits ABOVE the card's UI layers (play button at z-4, mute
   toggle, caption, etc.) so the peek dim washes those too. The active
   slide's ::after has opacity 0 + pointer-events:none, so even with a
   high z-index it doesn't block clicks on the play button / mute /
   permalink underneath. */
.vio-sm__carousel .vio-carousel-compare__slide::after {
	content: '';
	position: absolute;
	inset: 0;
	/* Strength of the white wash on peeking neighbours. Set inline by
	   render.php from the `peekDim` block attribute (0-100, written as a
	   0.00-1.00 alpha). Falls back to 0.75 if the var is missing. */
	background: rgba(255, 255, 255, var(--vio-sm-peek-dim, 0.75));
	pointer-events: none;
	transition: opacity 0.4s ease;
	opacity: 1;
	z-index: 10;
}
.vio-sm__carousel .vio-carousel-compare__slide.is-active::after {
	opacity: 0;
}

/* ── Arrows ──────────────────────────────────────────────────────────────── */
.vio-sm__carousel .vio-carousel-compare__arrow {
	position: absolute;
	/* Pin to the vertical midpoint of the FIRST card (set on init + resize
	   by view.js as --vio-sm-locked-card-h). Stays stable as the user
	   navigates to cards with different aspect ratios. Falls back to the
	   container-query formula (half the carousel-wrapper width, assuming
	   a square card) when the locked var isn't yet set. */
	top: calc(var(--vio-sm-locked-card-h, calc(100cqw - (var(--vio-sm-peek) * 2))) / 2);
	transform: translateY(-50%);
	z-index: 5;
	background: none;
	border: none;
	padding: 4px;
	cursor: pointer;
	opacity: 0.85;
	transition: opacity 0.2s ease;
	width: 44px;
	height: 44px;
	display: flex;
	align-items: center;
	justify-content: center;
}
.vio-sm__carousel .vio-carousel-compare__arrow:hover { opacity: 1; }
.vio-sm__carousel .vio-carousel-compare__arrow:focus-visible {
	opacity: 1;
	outline: 2px solid var(--wp--preset--color--vio-ink, #030303);
	outline-offset: 2px;
	border-radius: 50%;
}
/* Arrows sit just outside the active card's edges (8px gap). Card
   width is `50svh * --vio-sm-aspect` (set per card by render.php);
   carousel uses the same default aspect ratio (0.5625 for 9:16
   reels — overridden when a different aspect dominates the carousel)
   to compute where the active card's edges land. The formula:
     prev arrow right edge = 50% - (half-card-width) - 8px gap
     next arrow left edge  = 50% + (half-card-width) + 8px gap
   Falls back gracefully to container-edge positioning when an aspect
   var isn't present. */
.vio-sm__carousel {
	--vio-sm-active-aspect: 0.5625; /* default 9:16 — JS can override */
}
/* Horizontal arrow positioning — prefer the locked first-card width
   (set by view.js on init + resize) so arrows sit just outside the
   first card's edges and stay there even when the user navigates to
   cards with different aspect ratios. Falls back to the live-aspect
   formula when the locked var isn't set yet. */
.vio-sm__carousel .vio-carousel-compare__arrow--prev {
	left: auto;
	right: calc(50% + (var(--vio-sm-locked-card-w, calc(50svh * var(--vio-sm-active-aspect, 0.5625))) / 2) + 8px);
}
.vio-sm__carousel .vio-carousel-compare__arrow--next {
	left: calc(50% + (var(--vio-sm-locked-card-w, calc(50svh * var(--vio-sm-active-aspect, 0.5625))) / 2) + 8px);
	right: auto;
}
.vio-sm__carousel .vio-carousel-compare__arrow[hidden] { display: none; }

/* ── Progress bar ─────────────────────────────────────────────────────────
   Width matches one card's outer width (set by view.js on init/resize) so the
   progress indicator is visually aligned with the centered active slide.
   Falls back to peek-aware width if JS hasn't initialized yet. */
.vio-sm__carousel .vio-carousel-compare__progress {
	position: relative;
	height: 4px;
	border-radius: 999px;
	background: rgba(0, 0, 0, 0.12);
	margin-top: var(--wp--preset--spacing--500, 20px);
	width: var(--vio-sm-card-w, calc(100% - (var(--vio-sm-peek) * 2)));
	margin-left: auto;
	margin-right: auto;
}
.vio-sm__carousel .vio-carousel-compare__progress-bar {
	position: absolute;
	top: 0;
	left: 0;
	height: 100%;
	border-radius: 999px;
	background: rgba(0, 0, 0, 0.55);
	transition: left 0.4s ease, width 0.4s ease;
}

/* ── Card (square corners — matches the 50/50 carousel cards) ───────────── */
.vio-sm__card {
	position: relative;
	display: flex;
	flex-direction: column;
	width: 100%;
	/* Transparent frame — only the media and the caption text show. The
	   former cream background + border are gone so reels/videos sit
	   directly on the section bg with no surrounding "card chrome". */
	background: transparent;
	border: 0;
	overflow: hidden;
}

/* ── Media tile ──────────────────────────────────────────────────────────── */
.vio-sm__media {
	position: relative;
	width: 100%;
	aspect-ratio: 1 / 1;
	/* Transparent — the video / image fills the box; nothing should be
	   visible behind it. The greige placeholder background was visible
	   as a frame around reels and other non-fully-covering media. */
	background: transparent;
	overflow: hidden;
}

.vio-sm__image {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

/* Videos use object-fit: contain with a black backdrop so portrait clips
   (most IG/FB videos are 9:16) letterbox cleanly inside the 1:1 media tile
   instead of being cropped to a tall sliver. Landscape clips get bars top
   and bottom, portrait clips get bars left and right. */
.vio-sm__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: contain;
	display: block;
	background: #000;
}

/* Once a video is playing the play overlay hides — clicking the video
   itself toggles pause/resume, so signal that with a pointer cursor. */
.vio-sm__card--playing .vio-sm__video {
	cursor: pointer;
}

/* Reel cards — the inline `style="aspect-ratio: 9/16"` from render.php
   handles sizing; this rule just forces `object-fit: cover` so the
   vertical video fills the tile without left/right black bars. */
.vio-sm__card--reel .vio-sm__video {
	object-fit: cover !important;
}

/* Hard ceiling: no card taller than 50% of the viewport (one third
   smaller than the previous 75svh cap). render.php emits
   `--vio-sm-aspect: <ratio>` (e.g. 0.5625 for 9:16) as an inline CSS
   variable on every card. We cap the card's max-width to
   `50svh * aspect`, so when aspect-ratio drives the media taller than
   50svh, the WHOLE card shrinks proportionally (width and height
   together) and stays centered in the slide. The full video is
   visible at correct aspect; nothing is cropped. */
.vio-sm__card {
	max-width: calc(50svh * var(--vio-sm-aspect, 1));
	max-width: calc(50vh * var(--vio-sm-aspect, 1)); /* fallback */
	margin-inline: auto;
}

/* ── Overlays on media ──────────────────────────────────────────────────── */
.vio-sm__platform-badge {
	position: absolute;
	top: 10px;
	left: 10px;
	z-index: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.55);
	color: #fff;
	pointer-events: none;
}
.vio-sm__platform-badge .vio-sm__platform-icon {
	width: 18px;
	height: 18px;
}

.vio-sm__type-pill {
	position: absolute;
	top: 10px;
	right: 10px;
	z-index: 2;
	padding: 3px 8px;
	font-size: 11px;
	line-height: 1;
	letter-spacing: 0.04em;
	text-transform: uppercase;
	color: #fff;
	background: rgba(0, 0, 0, 0.55);
	border-radius: 999px;
	display: inline-flex;
	align-items: center;
	gap: 4px;
	pointer-events: none;
}

.vio-sm__permalink {
	position: absolute;
	inset: 0;
	z-index: 1;
	text-indent: -9999px;
	overflow: hidden;
}
.vio-sm__permalink:focus-visible {
	outline: 2px solid var(--wp--preset--color--vio-ink, #030303);
	outline-offset: -3px;
}

/* Play / pause control.
   - Paused (default): large, fully visible, centered "play" glyph.
   - Playing: shrinks to a small circle in the bottom-left corner with the
     "pause" glyph, mirroring the sound toggle in the bottom-right. Stays
     subtle so the video stays watchable, but always visible/tappable.
*/
.vio-sm__play-button {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	z-index: 4;
	width: 64px;
	height: 64px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.55);
	color: #fff;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition:
		background 0.2s ease,
		transform 0.2s ease,
		top 0.25s ease,
		left 0.25s ease,
		width 0.25s ease,
		height 0.25s ease,
		opacity 0.2s ease;
}
.vio-sm__play-button:hover {
	background: rgba(0, 0, 0, 0.75);
}

/* Play glyph is offset slightly to look optically centered; pause glyph is
   not. Show one at a time based on the playing state of the card. */
.vio-sm__play-button .vio-sm__icon--play-glyph  { margin-left: 3px; display: inline-flex; }
.vio-sm__play-button .vio-sm__icon--pause-glyph { display: none; }
.vio-sm__card--playing .vio-sm__play-button .vio-sm__icon--play-glyph  { display: none; }
.vio-sm__card--playing .vio-sm__play-button .vio-sm__icon--pause-glyph { display: inline-flex; }

/* Playing state: small corner button. Mirrors the sound toggle's size + style
   in the opposite corner so the controls are visually balanced. */
.vio-sm__card--playing .vio-sm__play-button {
	top: auto;
	left: 10px;
	bottom: 10px;
	transform: none;
	width: 32px;
	height: 32px;
	background: rgba(0, 0, 0, 0.6);
	opacity: 0.85;
}
.vio-sm__card--playing .vio-sm__play-button:hover {
	transform: none;
	opacity: 1;
}
.vio-sm__card--playing .vio-sm__play-button .vio-sm__icon--pause-glyph {
	width: 16px;
	height: 16px;
}

/* Sound toggle (videos only) — appears once the video is playing. */
.vio-sm__play-toggle {
	position: absolute;
	bottom: 10px;
	right: 10px;
	z-index: 3;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(0, 0, 0, 0.55);
	color: #fff;
	cursor: pointer;
	display: none;
	align-items: center;
	justify-content: center;
}
.vio-sm__card--playing .vio-sm__play-toggle { display: inline-flex; }
.vio-sm__play-toggle:hover { background: rgba(0, 0, 0, 0.75); }
.vio-sm__play-toggle .vio-sm__icon--sound { display: none; }
.vio-sm__play-toggle .vio-sm__icon--muted { display: block; }
.vio-sm__play-toggle[aria-pressed="true"] .vio-sm__icon--sound { display: block; }
.vio-sm__play-toggle[aria-pressed="true"] .vio-sm__icon--muted { display: none; }

/* ── Caption ─────────────────────────────────────────────────────────────── */
.vio-sm__caption-wrap {
	padding: 14px 16px 16px;
	display: flex;
	flex-direction: column;
	gap: 6px;
	flex: 1 1 auto;
	/* Opaque background so the caption block reads cleanly even when the
	   card itself is transparent (the card transparency lets the reel /
	   video tile sit directly on the section bg, but text needs its own
	   solid surface so the dim peek-card overlay doesn't bleed through). */
	background: var(--wp--preset--color--vio-lotion, #FEFFF9);
}

/* Captions are visually distracting on the peeking neighbours — only the
   active card shows its text. visibility:hidden keeps the layout box so the
   neighbour silhouettes still match the active card height. */
.vio-sm__carousel .vio-carousel-compare__slide:not(.is-active) .vio-sm__caption-wrap {
	visibility: hidden;
}
.vio-sm__username {
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.02em;
	color: #725C50;
}
.vio-sm__caption {
	margin: 0;
	font-size: 14px;
	line-height: 1.5;
	color: var(--wp--preset--color--vio-ink, #030303);
	white-space: pre-line;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}
.vio-sm__card--expanded .vio-sm__caption {
	display: block;
	-webkit-line-clamp: unset;
	overflow: visible;
}
.vio-sm__caption-toggle {
	margin-top: 4px;
	align-self: flex-start;
	background: transparent;
	border: 0;
	padding: 0;
	cursor: pointer;
	font-size: 13px;
	font-weight: 600;
	color: var(--wp--preset--color--vio-ink, #030303);
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* ── Empty state ─────────────────────────────────────────────────────────── */
.vio-sm__empty {
	text-align: center;
	padding: 32px 16px;
	border: 1px dashed var(--wp--preset--color--vio-mtn-greige, #E9E3DC);
	color: var(--wp--preset--color--vio-mouse, #B29D92);
}
.vio-sm__empty p { margin: 4px 0; }

/* ── Per-card native aspect ratio ────────────────────────────────────────────
   render.php emits inline `style="aspect-ratio: …"` on .vio-sm__media when
   the item carries native width/height (feed cache items, uploaded
   videos, and oEmbed-resolved iframes all provide this). The inline style
   wins over the default `aspect-ratio: 1/1` here.

   `object-fit: cover` lets the video/image fill the card without black
   bars — that's the whole point of the per-item aspect override. Embed
   iframes obviously can't be `object-fit`'d; their wrapper just inherits
   100% × 100% and the iframe stretches into it. */
.vio-sm__media[style*="aspect-ratio"] .vio-sm__video,
.vio-sm__media[style*="aspect-ratio"] .vio-sm__image {
	object-fit: cover;
	background: transparent;
}
.vio-sm__embed,
.vio-sm__embed iframe,
.vio-sm__embed video,
.vio-sm__embed .vio-sm__embed-video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	display: block;
}
/* When the embed is a raw <video> (cache-hit path for IG reels/posts),
   cover the card edge-to-edge with no letterbox bars. */
.vio-sm__embed video {
	object-fit: cover;
	background: #000;
}

/* ── Instagram poster fallback (no iframe) ──────────────────────────────────
   When a pasted IG URL isn't in the social-media feed cache, embeds.php
   renders this static poster card instead of the chrome-heavy /embed/
   iframe. Anywhere on the card → opens the post on instagram.com in a
   new tab. Hover dims the poster and brightens the overlay. */
.vio-sm__embed-card {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	overflow: hidden;
	background: #000;
	color: #fff;
	text-decoration: none;
}
.vio-sm__embed-poster {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transition: opacity 0.25s ease, transform 0.4s ease;
}
.vio-sm__embed-overlay {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 10px;
	color: #fff;
	background: linear-gradient(
		180deg,
		rgba(0, 0, 0, 0.05) 0%,
		rgba(0, 0, 0, 0.35) 60%,
		rgba(0, 0, 0, 0.55) 100%
	);
	opacity: 1;
	transition: background 0.25s ease;
	pointer-events: none;
}
.vio-sm__embed-ig-icon {
	display: block;
	color: #fff;
	filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
}
.vio-sm__embed-cta {
	font-family: var(--wp--preset--font-family--nunito-sans, 'Nunito Sans', sans-serif);
	font-size: 14px;
	font-weight: 600;
	letter-spacing: 0.04em;
	text-transform: none;
	text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
.vio-sm__embed-card:hover .vio-sm__embed-poster {
	transform: scale(1.02);
}
.vio-sm__embed-card:hover .vio-sm__embed-overlay {
	background: linear-gradient(
		180deg,
		rgba(0, 0, 0, 0.15) 0%,
		rgba(0, 0, 0, 0.55) 60%,
		rgba(0, 0, 0, 0.7) 100%
	);
}

/* ── Instagram embed chrome crop ─────────────────────────────────────────────
   Instagram's /embed/ page always renders an account-header bar above the
   media and an action/footer bar below it. The iframe shows them too.
   We hide both by:
     1. Inflating the iframe taller than its container so the header and
        footer fall outside the visible box.
     2. Scaling the iframe up so vertical-reel letterboxing on the left
        and right gets clipped by the container edges, leaving just the
        video pixels visible.
   `.vio-sm__ig-crop` is emitted by embeds.php around the IG iframe. */
.vio-sm__ig-crop {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	overflow: hidden;
	background: #000;
}
/* Override the generic `.vio-sm__embed iframe` rule (inset: 0, 100%×100%)
   so the crop can reposition and inflate the iframe freely. The doubled
   class bumps specificity above the catch-all embed rule. */
.vio-sm__ig-crop.vio-sm__ig-crop iframe {
	position: absolute;
	inset: auto;
	border: 0;
	display: block;
	transform-origin: center center;
}
/* Reel / vertical media — IG's embed page is roughly:
     ~55px  profile header (avatar + username + "View profile")
     ~60%   video player
     ~40%   footer chrome (View more, ♡ 💬 ↗, Add comment…, IG logo)
   We inflate the iframe to 250% height and shift it UP so the header
   scrolls past the top edge and the footer past the bottom. Width at
   130% hides the black letterbox bars on either side of the 9:16 video
   within Instagram's wider embed frame. */
.vio-sm__ig-crop[data-aspect="reel"] iframe {
	width: 130%;
	height: 250%;
	top: -6%;
	left: 50%;
	transform: translateX(-50%);
}
.vio-sm__ig-crop[data-aspect="post"] iframe {
	width: 120%;
	height: 200%;
	top: -4%;
	left: 50%;
	transform: translateX(-50%);
}

/* ── 50/50 split layout ──────────────────────────────────────────────────────
   When `layoutMode = 'split'`, render.php wraps the carousel and a
   content column in `.vio-social-media__grid`. Modifier classes pick
   the desktop side and the mobile stacking order.

   Desktop sizing/spacing intentionally mirrors the 50/50 accordion
   block at 1280+:
     - Section is at least 100dvh tall (full viewport height), padded
       50px on every side, flex column.
     - Every section-shell wrapper passes the full height down to the
       grid (flex 1 1 auto + min-height 0).
     - Grid is 2 columns, 100px gap, row min = calc(100dvh - 100px).
     - Content column = 50px top/bottom + 100px left/right padding,
       flex column, content centered vertically (matches accordion).
     - Strip the global .vio-section__inner max-width:1440 so both
       columns can use the full section width edge-to-edge. */
@media (min-width: 1280px) {
	.vio-section.vio-social-media.vio-social-media--layout-split,
	section.vio-section.vio-social-media.vio-social-media--layout-split {
		padding: 50px;
		overflow: visible;
		display: flex;
		flex-direction: column;
		contain: layout paint;
	}
	.vio-section.vio-social-media.vio-social-media--layout-split .vio-section__inner,
	.vio-section.vio-social-media.vio-social-media--layout-split .vio-section__content,
	.vio-section.vio-social-media.vio-social-media--layout-split .vio-section__body {
		flex: 0 1 auto;
		min-height: 0;
		display: flex;
		flex-direction: column;
		max-width: none;
		padding-left: 0;
		padding-right: 0;
		margin-left: 0;
		margin-right: 0;
	}
	.vio-social-media--layout-split .vio-social-media__grid {
		min-height: 0;
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: clamp(32px, 4vw, 64px);
		align-items: center;
	}
	/* Content column — flex centering with comfortable padding.
	   text-align is handled by the --align-* modifier classes emitted
	   by render.php. Horizontal padding reduced from 100px to 24px so
	   titles and lead text have room to breathe in the 50% column. */
	.vio-social-media--layout-split .vio-social-media__col--content {
		min-height: 0;
		padding: 0 24px;
		display: flex;
		flex-direction: column;
		justify-content: center;
	}
	/* Media column — fills the column. The carousel inside has its own
	   max-width (440px) and auto-centers; the column just provides
	   vertical centering via flex. */
	.vio-social-media--layout-split .vio-social-media__col--media {
		min-height: 0;
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-self: stretch;
	}

	/* Lift the carousel's default 440px width cap in split mode so the
	   active card can grow to fill the section's viewport height. The
	   card's max-width is rewritten from `50svh × aspect` to
	   `(100dvh − 100px − 50px) × aspect` so a vertical reel fills the
	   full section content area (100dvh − 100px section padding) minus
	   a ~50px buffer for the progress bar + bottom margin. Card height
	   stays driven by aspect-ratio (no explicit height set), so the
	   card scales proportionally to whatever the per-item ratio is. */
	.vio-social-media--layout-split .vio-sm__carousel {
		max-width: none;
	}
	.vio-social-media--layout-split .vio-sm__card {
		max-width: calc((100vh  - 150px) * var(--vio-sm-aspect, 1)); /* fallback */
		max-width: calc((100dvh - 150px) * var(--vio-sm-aspect, 1));
	}

	/* Arrow positions now lock to the first card's measured size via
	   --vio-sm-locked-card-w + --vio-sm-locked-card-h (set by view.js
	   on init + window resize). Works in both feed and split layouts
	   without per-mode overrides — the JS reads the actual rendered
	   card dimensions whatever they are. */
}

/* Title / Lead alignment for the split content column. The
   render.php-emitted modifier class (--align-left | --align-center |
   --align-right) is mirrored from the introAlign attribute. text-align
   on the column hits every text node (eyebrow, title, title-alt, lead,
   content body); the CTA wrapper needs explicit justify-content so the
   <a> button anchors to the same edge instead of staying flex-start. */
.vio-social-media__content--align-left  { text-align: left;   }
.vio-social-media__content--align-center { text-align: center; }
.vio-social-media__content--align-right { text-align: right;  }

.vio-social-media__content--align-left  .vio-section__cta { justify-content: flex-start; }
.vio-social-media__content--align-center .vio-section__cta { justify-content: center;     }
.vio-social-media__content--align-right .vio-section__cta { justify-content: flex-end;   }

/* When content is centered or right-aligned, also center/right-align
   the eyebrow (which has its own letterspacing/uppercase style) since
   inline text-align doesn't always reach it through the wrapper. */
.vio-social-media__content--align-center .vio-section__eyebrow,
.vio-social-media__content--align-center .vio-section__title,
.vio-social-media__content--align-center .vio-section__lead,
.vio-social-media__content--align-center .vio-section__content-copy { text-align: center; }
.vio-social-media__content--align-right  .vio-section__eyebrow,
.vio-social-media__content--align-right  .vio-section__title,
.vio-social-media__content--align-right  .vio-section__lead,
.vio-social-media__content--align-right  .vio-section__content-copy { text-align: right;  }

.vio-social-media__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 40px;
	align-items: center;
}
@media (min-width: 1024px) {
	.vio-social-media__grid {
		grid-template-columns: 1fr 1fr;
		gap: 50px;
	}
}
.vio-social-media__col {
	min-width: 0;
	/* Each column is a flex column whose contents (carousel on one side,
	   eyebrow + title + lead + content + CTAs on the other) are
	   vertically centered. Combined with the grid's `align-items:
	   center`, this guarantees both halves visually center in their
	   columns no matter which side has more content. */
	display: flex;
	flex-direction: column;
	justify-content: center;
}
/* Desktop: media on the LEFT (default). When `mediaSide = 'right'`,
   swap the grid order. */
@media (min-width: 1024px) {
	.vio-social-media__grid--media-left  .vio-social-media__col--media   { order: 0; }
	.vio-social-media__grid--media-left  .vio-social-media__col--content { order: 1; }
	.vio-social-media__grid--media-right .vio-social-media__col--media   { order: 1; }
	.vio-social-media__grid--media-right .vio-social-media__col--content { order: 0; }
}
/* Mobile (under 1024): when `mobileContentFirst` is on, render content
   above the media regardless of desktop side. */
@media (max-width: 1023px) {
	.vio-social-media__grid--mobile-content-first .vio-social-media__col--content { order: 0; }
	.vio-social-media__grid--mobile-content-first .vio-social-media__col--media   { order: 1; }
}

.vio-social-media__content {
	display: flex;
	flex-direction: column;
	gap: 24px;
}
.vio-social-media__content .vio-section__eyebrow {
	font-family: var(--wp--preset--font-family--nunito, 'Nunito Sans', sans-serif);
	font-weight: 700;
	font-size: 13px;
	line-height: 30px;
	letter-spacing: 0.1538em;
	color: var(--wp--preset--color--vio-mouse, #B29D92);
	text-transform: uppercase;
}
.vio-social-media__content .vio-section__title {
	margin: 0;
}
.vio-social-media__content .vio-section__lead p,
.vio-social-media__content .vio-section__content-copy p {
	margin: 0 0 0.75em;
}

/* ─────────────────────────────────────────────────────────────────────
   Coverflow carousel layout
   Five visible cards: active centered + full size, prev/next scaled
   down on either side, far-prev/far-next clipped at edges. Infinite
   loop is forced in render.php so the side cards always have
   neighbors. Centered prev/next chevron nav sits below.

   Reuses the existing is-active / is-prev / is-next / is-far-prev /
   is-far-next class machinery from view.js — no JS changes needed.

   Selectors chain BOTH `.vio-sm__carousel` and
   `.vio-sm__carousel--layout-coverflow` on the wrapper so they out-
   specify the existing stack rules (which target `.vio-sm__carousel
   .vio-carousel-compare__slide.is-XXX`). Without that chain the
   stack `is-active { position:relative; margin-left:peek; }` etc.
   leak through and break the centered layout.
   ───────────────────────────────────────────────────────────────────── */

.vio-sm__carousel.vio-sm__carousel--layout-coverflow {
	position: relative;
	/* Override the default 440px cap from .vio-sm__carousel — coverflow
	   needs a wide canvas so the prev/next side cards have room to sit
	   beside the active card without falling off the wrapper edge. */
	max-width: min(1400px, 100%);
	width: 100%;
	margin-left: auto;
	margin-right: auto;
	padding-bottom: 0;
}

.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__track-wrapper {
	/* Drop the peek bleed that the stack layout uses to extend slides
	   past the section edge — coverflow positions slides via CSS
	   transforms keyed to the wrapper's own width. Wrapper height
	   comes from the active slide (which is `position: relative`),
	   NOT from a fixed clamp — that way 50/50 split mode (narrow
	   carousel column) doesn't get a huge empty box. */
	width: 100%;
	margin-left: 0;
	margin-right: 0;
	overflow: hidden;
	padding-bottom: 0;
	margin-bottom: 0;
	cursor: default;
}

/* Full-bleed wrapper for feed-mode coverflow: the track-wrapper escapes
   the section's content padding so peek cards remain visible all the
   way out to the viewport edges instead of being clipped at the
   section's content boundary. The active card stays where it sits in
   normal flow (centered inside the constrained carousel container);
   the absolute-positioned side cards center on the 100vw wrapper and
   so spread to the viewport edges before the wrapper's overflow:hidden
   clips them. Split mode keeps the carousel column-constrained, so it
   gets the default non-bleed wrapper. */
.vio-social-media--layout-feed .vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__track-wrapper {
	width: 100vw;
	max-width: 100vw;
	margin-left: calc(50% - 50vw);
	margin-right: calc(50% - 50vw);
}

/* Track is a positioning context for the absolutely-placed side
   slides. The active slide stays `position:relative` so it gives
   the wrapper its natural height. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__track {
	position: relative;
	width: 100%;
	min-height: 0;
}

/* Every slide: same width as the active so all cards share aspect.
   Inactive slides are absolutely positioned and transformed off
   center; active slide stays in normal flow so it defines wrapper
   height. Width bumped vs. original so cards read as portrait-phone
   sized; aspect-ratio fallback below makes them tall even when the
   item has no width/height metadata. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide {
	position: absolute;
	top: 0;
	left: 50%;
	width: clamp(240px, 26%, 380px);
	margin: 0;
	padding: 0;
	/* Longer, eased transition — matches a designer "soft slide" feel.
	   Cubic-bezier(0.22, 1, 0.36, 1) is the easeOutQuint curve: fast
	   start, gentle finish. Opacity fades slightly faster than the
	   movement so cards arrive into place before fully appearing,
	   which reads cleaner than a sync fade. */
	transition:
		transform 0.75s cubic-bezier(0.22, 1, 0.36, 1),
		opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1);
	will-change: transform, opacity;
	transform: translateX(-50%) scale(0.4);
	opacity: 0;
	pointer-events: none;
	z-index: 0;
	display: block;
}

/* Coverflow cards default to 9:16 portrait so the carousel reads as
   "phone screens lined up" even when items lack intrinsic aspect
   metadata. Per-item --vio-sm-aspect (set by render.php) still wins
   when present. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__media {
	aspect-ratio: 9 / 16;
}

/* Hide the white-wash peek dim that stack uses — coverflow wants
   the side cards visible, not washed out. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide::after {
	display: none !important;
	content: none;
	background: none;
	opacity: 0;
}

/* Active: relative (gives wrapper its height), centered via auto
   margins on the inner card. We use margin auto instead of
   translateX(-50%) so the slide sits in normal flow. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-active {
	position: relative;
	top: 0;
	left: 0;
	margin: 0 auto;
	transform: scale(1);
	opacity: 1;
	z-index: 3;
	pointer-events: auto;
	background: transparent;
	box-shadow: none;
}

/* Direct neighbors: nearly touching the active card with a small
   visual gap. Active half-width = 50%, side half-width (scaled to
   0.85) = 42.5% — edges touch at 92.5% center-to-center offset.
   100% gives ~8% gap (clean separation, no overlap). transform-
   origin center so scale shrinks toward each card's own center. */
/* Every non-active slide positions itself by its signed distance from
   the active slide. view.js sets --vio-cf-d to the distance value
   (e.g. -1 for is-prev, +2 for the slide just past is-next). This
   means each slide gets its OWN slot at d * 100% offset, instead of
   every distant slide stacking together at the same ±200% position.
   On wide viewports the wrapper's overflow:hidden naturally lets more
   peek cards become visible; on narrow viewports it clips them. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-prev,
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-next,
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-far-prev,
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-far-next {
	transform: translateX(calc(-50% + (var(--vio-cf-d, 0) * 100%))) scale(0.85);
	transform-origin: center center;
	opacity: var(--vio-cf-side-opacity, 0.8);
}
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-prev,
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-next {
	z-index: 2;
}
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-far-prev,
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-far-next {
	z-index: 1;
}

/* Each card is transparent (no chrome) — the media is the card. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__card {
	width: 100%;
	background: transparent;
	box-shadow: none;
	max-width: none;
}

/* Coverflow footer nav: prev + progress bar + next in a single flex
   row below the carousel — matches the testimonials / providers
   block pattern. The .vio-sm__nav wrapper is only emitted by
   render.php when coverflow is active; arrows sit inside it
   instead of as edge overlays. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav {
	display: flex;
	align-items: center;
	gap: 16px;
	margin-top: 28px;
	padding: 0 8px;
	max-width: 600px;
	margin-left: auto;
	margin-right: auto;
}

.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav .vio-carousel-compare__arrow {
	position: relative;
	flex: 0 0 auto;
	top: auto;
	left: auto;
	right: auto;
	bottom: auto;
	transform: none;
	width: 40px;
	height: 40px;
	color: var(--wp--preset--color--vio-ink, #030303);
	opacity: 0.7;
	background: none;
	border: none;
	padding: 4px;
	cursor: pointer;
	z-index: auto;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: opacity 0.2s ease;
}
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav .vio-carousel-compare__arrow:hover,
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav .vio-carousel-compare__arrow:focus-visible {
	opacity: 1;
	outline-offset: 2px;
}

/* Progress bar fills the space between the two arrows — overrides
   the stack-layout's centered-below-track positioning. */
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav .vio-carousel-compare__progress {
	position: relative;
	flex: 1;
	height: 4px;
	border-radius: 999px;
	background: rgba(0, 0, 0, 0.12);
	margin: 0;
	width: auto;
	max-width: none;
	top: auto;
	left: auto;
}
.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav .vio-carousel-compare__progress-bar {
	background: rgba(0, 0, 0, 0.55);
}
/* Dark-section variants — lift contrast on ink bg. */
.vio-bg--vio-ink .vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav .vio-carousel-compare__arrow {
	color: var(--wp--preset--color--vio-lotion, #FEFFF9);
}
.vio-bg--vio-ink .vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav .vio-carousel-compare__progress {
	background: rgba(255, 255, 255, 0.18);
}
.vio-bg--vio-ink .vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-sm__nav .vio-carousel-compare__progress-bar {
	background: rgba(255, 255, 255, 0.75);
}

/* Tablet: slightly larger cards relative to viewport, side cards
   still cleanly separated, far cards still partially off-screen. */
@media (max-width: 1024px) {
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide {
		width: clamp(220px, 32%, 320px);
	}
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-prev,
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-next,
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-far-prev,
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-far-next {
		transform: translateX(calc(-50% + (var(--vio-cf-d, 0) * 95%))) scale(0.8);
	}
}

/* Mobile: active + small peek of prev/next; cards at |d|>=2 fully clipped. */
@media (max-width: 640px) {
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide {
		width: clamp(220px, 62%, 320px);
	}
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-prev,
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-next {
		transform: translateX(calc(-50% + (var(--vio-cf-d, 0) * 85%))) scale(0.55);
		opacity: var(--vio-cf-side-opacity, 0.7);
	}
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-far-prev,
	.vio-sm__carousel.vio-sm__carousel--layout-coverflow .vio-carousel-compare__slide.is-far-next {
		opacity: 0;
	}
}

/* ─────────────────────────────────────────────────────────────────────
   Hybrid carousel layout
   N uniform cards laid out in a horizontal flex row. The track is
   translated by `-current * (cardWidth + gap)` via view.js so the
   active card snaps into the leftmost visible slot. No scaling /
   no opacity dim on side cards — all visible cards read at full
   weight. Slides-per-view is responsive via data attributes set
   on the carousel root by render.php.

   Selectors chain `.vio-sm__carousel` AND
   `.vio-sm__carousel--layout-hybrid` to out-specify the inherited
   stack rules (same approach the coverflow block uses).
   ───────────────────────────────────────────────────────────────────── */

.vio-sm__carousel.vio-sm__carousel--layout-hybrid {
	position: relative;
	max-width: none;
	width: 100%;
	margin-left: auto;
	margin-right: auto;
	padding-bottom: 0;
}

.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__track-wrapper {
	width: 100%;
	margin-left: 0;
	margin-right: 0;
	overflow: hidden;
	padding-bottom: 0;
	margin-bottom: 0;
	cursor: grab;
}
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__track-wrapper:active {
	cursor: grabbing;
}

/* Flex row of uniform cards. view.js sets transform: translateX(...)
   inline based on current index × card width. */
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__track {
	display: flex;
	flex-wrap: nowrap;
	gap: 16px;
	width: auto;
	transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
	will-change: transform;
}

/* Each slide takes 1 / slidesDesktop of the wrapper width minus
   the gap contribution. Default desktop 3-up; tablet + mobile
   breakpoints below override. */
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__slide {
	position: relative;
	top: auto;
	left: auto;
	flex: 0 0 calc((100% - 16px * 2) / 3);
	min-width: 0;
	margin: 0;
	padding: 0;
	transform: none;
	opacity: 1;
	pointer-events: auto;
	z-index: 0;
	display: block;
	transition: none;
}

/* Kill the white-wash peek-dim from stack mode — hybrid wants every
   visible card at full strength. */
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__slide::after {
	display: none !important;
	content: none;
	background: none;
	opacity: 0;
}

/* Uniform card media — default 9/16 phone aspect, matches the
   Figma reference. Per-item --vio-sm-aspect (when set by render
   for items that carry intrinsic metadata) still wins via the
   element style attribute. */
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__media {
	aspect-ratio: 9 / 16;
}

.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__card {
	width: 100%;
	background: transparent;
	box-shadow: none;
	max-width: none;
}

/* Footer nav (prev + progress + next) — identical treatment to
   coverflow. Same .vio-sm__nav wrapper from render.php. */
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav {
	display: flex;
	align-items: center;
	gap: 16px;
	margin-top: 28px;
	padding: 0 8px;
	max-width: 600px;
	margin-left: 0;       /* anchor left under the carousel (matches Figma) */
	margin-right: auto;
}

.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav .vio-carousel-compare__arrow {
	position: relative;
	flex: 0 0 auto;
	top: auto;
	left: auto;
	right: auto;
	bottom: auto;
	transform: none;
	width: 40px;
	height: 40px;
	color: var(--wp--preset--color--vio-ink, #030303);
	opacity: 0.7;
	background: none;
	border: none;
	padding: 4px;
	cursor: pointer;
	z-index: auto;
	display: flex;
	align-items: center;
	justify-content: center;
	transition: opacity 0.2s ease;
}
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav .vio-carousel-compare__arrow:hover,
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav .vio-carousel-compare__arrow:focus-visible {
	opacity: 1;
}

.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav .vio-carousel-compare__progress {
	position: relative;
	flex: 1;
	height: 4px;
	border-radius: 999px;
	background: rgba(0, 0, 0, 0.12);
	margin: 0;
	width: auto;
	max-width: none;
	top: auto;
	left: auto;
}
.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav .vio-carousel-compare__progress-bar {
	background: rgba(0, 0, 0, 0.55);
	transition: left 0.4s ease, width 0.4s ease;
}
.vio-bg--vio-ink .vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav .vio-carousel-compare__arrow {
	color: var(--wp--preset--color--vio-lotion, #FEFFF9);
}
.vio-bg--vio-ink .vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav .vio-carousel-compare__progress {
	background: rgba(255, 255, 255, 0.18);
}
.vio-bg--vio-ink .vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__nav .vio-carousel-compare__progress-bar {
	background: rgba(255, 255, 255, 0.75);
}

/* Tablet: 2 cards visible. */
@media (max-width: 1023px) {
	.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__slide {
		flex: 0 0 calc((100% - 16px) / 2);
	}
}

/* Mobile: ~1.2 cards visible (peek of the next). */
@media (max-width: 639px) {
	.vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__slide {
		flex: 0 0 calc(100% / 1.2);
	}
}

/* ─────────────────────────────────────────────────────────────────────
   Hybrid + Split layout overrides
   Per the Figma reference: content column = 1/4 of the section width,
   media column = 3/4 with 3 uniform cards each ≈ 1/4 of the section.
   Card height ≈ 75% of the section's visible content area. Nav row
   (prev + progress + next) moves OUT of the media column and sits
   under the CONTENT column (bottom-left of the section).

   Implementation:
     1. Override the split grid template from 1fr/1fr to 1fr/3fr.
     2. Drive each card by HEIGHT (75% of section content area), with
        width derived from the 9/16 aspect — so 3 cards tile across
        the 3/4 media column at the target proportions.
     3. Make the grid the absolute-positioning container, set the
        carousel back to position:static (overriding the
        `.vio-sm__carousel--layout-hybrid { position: relative }`
        rule above), and absolutely anchor `.vio-sm__nav` to the
        bottom-left of the grid under the content column.
   ───────────────────────────────────────────────────────────────────── */
@media (min-width: 1024px) {
	.vio-social-media--layout-split .vio-social-media__grid:has(.vio-sm__carousel--layout-hybrid) {
		grid-template-columns: 1fr 3fr;
		position: relative;
	}

	/* When hybrid is in a split layout, the carousel itself is no
	   longer the positioning context — the grid is. */
	.vio-social-media--layout-split .vio-sm__carousel.vio-sm__carousel--layout-hybrid {
		position: static;
		padding-bottom: 0;
	}

	/* Track wrapper inside hybrid+split: stretch to column height, no
	   internal vertical padding (the cards drive their own height). */
	.vio-social-media--layout-split .vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__track-wrapper {
		min-height: 0;
	}

	/* Each card: height = 75% of section content area (≈ 75% of
	   `100dvh - 100px`), width derived from the 9/16 aspect set on
	   `.vio-sm__media`. flex: 0 0 auto so the basis comes from the
	   inner card width, not a percentage of the column. */
	.vio-social-media--layout-split .vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-carousel-compare__slide {
		flex: 0 0 auto;
		width: calc((100vh  - 100px) * 0.75 * (9 / 16));
		width: calc((100dvh - 100px) * 0.75 * (9 / 16));
	}
	.vio-social-media--layout-split .vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__card {
		max-width: none;
	}
	.vio-social-media--layout-split .vio-sm__carousel.vio-sm__carousel--layout-hybrid .vio-sm__media {
		height: calc((100vh  - 100px) * 0.75);
		height: calc((100dvh - 100px) * 0.75);
		aspect-ratio: 9 / 16;
	}

	/* Move the nav row under the content column. Absolutely positioned
	   relative to the grid; aligned bottom + left to sit beneath the
	   content (which lives in the left column at 1fr / 4 of section).
	   Width matches the content column (1/(1+3) of grid width minus
	   the gap). Margin-top resets to 0 since absolute positioning
	   ignores it but keep it explicit. */
	.vio-social-media--layout-split .vio-social-media__grid:has(.vio-sm__carousel--layout-hybrid) .vio-sm__nav {
		position: absolute;
		bottom: 0;
		left: 0;
		width: calc((100% - 100px) / 4);
		margin: 0;
		padding: 0;
		max-width: none;
	}
}
