/* Pingu Scroll Video Background */
.pingu-scroll-video-row {
	position: relative;
	min-height: var(--psv-min-height, 250vh);
	isolation: isolate;
	overflow: visible;
}

.pingu-scroll-video-row > .pingu-scroll-video-bg {
	position: absolute;
	inset: 0;
	z-index: 0;
	pointer-events: none;
}

.pingu-scroll-video-sticky {
	position: -webkit-sticky;
	position: sticky;
	top: 0;
	width: 100%;
	height: 100vh;
	height: 100svh;
	height: 100dvh;
	overflow: hidden;
	background: #000;
}

.pingu-scroll-video {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	max-width: none;
	max-height: none;
	pointer-events: none;
	user-select: none;
}

.pingu-scroll-video-overlay {
	position: absolute;
	inset: 0;
	display: block;
	background: var(--psv-overlay, transparent);
	pointer-events: none;
}

/* Impreza 9.3 content wrapper remains in the normal row flow. Animated
   elements are temporarily portaled to the viewport stage below. */
.pingu-scroll-video-row > .l-section-h {
	position: relative;
	z-index: 2;
}

/* Full-row container with a sticky viewport canvas for automatic scenes. */
.pingu-scroll-fx-stage {
	position: absolute;
	inset: 0;
	z-index: 4;
	pointer-events: none;
}

.pingu-scroll-fx-stage-inner {
	position: sticky;
	top: 0;
	width: 100%;
	height: 100vh;
	height: 100svh;
	height: 100dvh;
	overflow: hidden;
	pointer-events: none;
}

.pingu-scroll-fx-item {
	position: absolute;
	z-index: 1;
	width: min(var(--psv-fx-max-width, 900px), calc(100vw - 48px));
	max-width: calc(100vw - 48px);
	box-sizing: border-box;
	pointer-events: none;
}

.pingu-scroll-fx-motion {
	width: 100%;
	max-width: 100%;
	will-change: transform, opacity;
	backface-visibility: hidden;
	pointer-events: auto;
}

.pingu-scroll-fx-motion > .pingu-scroll-fx-element {
	width: 100%;
	max-width: 100%;
	pointer-events: auto;
}

/* 9 viewport anchors. Edge spacing is configured per element. */
.pingu-scroll-fx-item.psv-pos-top_left {
	top: var(--psv-fx-edge-y, 80px);
	left: var(--psv-fx-edge-x, 80px);
}

.pingu-scroll-fx-item.psv-pos-top_center {
	top: var(--psv-fx-edge-y, 80px);
	left: 50%;
	transform: translateX(-50%);
}

.pingu-scroll-fx-item.psv-pos-top_right {
	top: var(--psv-fx-edge-y, 80px);
	right: var(--psv-fx-edge-x, 80px);
}

.pingu-scroll-fx-item.psv-pos-center_left {
	top: 50%;
	left: var(--psv-fx-edge-x, 80px);
	transform: translateY(-50%);
}

.pingu-scroll-fx-item.psv-pos-center {
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
}

.pingu-scroll-fx-item.psv-pos-center_right {
	top: 50%;
	right: var(--psv-fx-edge-x, 80px);
	transform: translateY(-50%);
}

.pingu-scroll-fx-item.psv-pos-bottom_left {
	bottom: var(--psv-fx-edge-y, 80px);
	left: var(--psv-fx-edge-x, 80px);
}

.pingu-scroll-fx-item.psv-pos-bottom_center {
	bottom: var(--psv-fx-edge-y, 80px);
	left: 50%;
	transform: translateX(-50%);
}

.pingu-scroll-fx-item.psv-pos-bottom_right {
	bottom: var(--psv-fx-edge-y, 80px);
	right: var(--psv-fx-edge-x, 80px);
}

/* Keep theme shape dividers / foreground decoration above the scrub video,
   but below the animated viewport scenes. */
.pingu-scroll-video-row > .l-section-shape,
.pingu-scroll-video-row > .l-section-overlay {
	z-index: 1;
}

.pingu-scroll-video-row.psv-disabled .pingu-scroll-video-bg {
	display: none;
}

/* Scrub-performance hints. */
.pingu-scroll-video-sticky,
.pingu-scroll-video,
.pingu-scroll-fx-stage-inner {
	transform: translateZ(0);
	backface-visibility: hidden;
}


/* Source-order markers used by the automatic scene timeline. */
.pingu-scroll-fx-placeholder {
	display: none !important;
}

/* Inside a Scroll Video sequence, a normal Separator is a timing spacer.
   Keep its place in the source order but do not render it as foreground content. */
.pingu-scroll-video-row.psv-has-scroll-fx .pingu-scroll-timeline-spacer:not(.pingu-scroll-fx-element) {
	visibility: hidden !important;
	pointer-events: none !important;
}

/* Optional floating timeline progress bar. It is appended to <body> so it is
   not affected by row stacking contexts or theme transforms. The timeline is
   inset from the viewport edges and includes automatic scene markers. */
.pingu-scroll-progress {
	position: fixed;
	left: var(--psv-progress-side, 40px);
	right: var(--psv-progress-side, 40px);
	bottom: var(--psv-progress-bottom, 28px);
	height: var(--psv-progress-height, 4px);
	background: var(--psv-progress-track, rgba(255,255,255,.22));
	border-radius: 999px;
	z-index: 999999;
	pointer-events: none;
	opacity: 0;
	visibility: hidden;
	transition: opacity .18s ease, visibility 0s linear .18s;
	transform: translateZ(0);
}

.pingu-scroll-progress.is-visible {
	opacity: 1;
	visibility: visible;
	transition: opacity .18s ease, visibility 0s linear 0s;
}

.pingu-scroll-progress-cue {
	position: absolute;
	left: 50%;
	bottom: calc(100% + 16px);
	display: inline-flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 8px;
	transform: translateX(-50%);
	color: var(--psv-progress-color, #fff);
	pointer-events: none;
	white-space: nowrap;
}

.pingu-scroll-progress-cue-label {
	display: block;
	font-size: 11px;
	line-height: 1;
	font-weight: 600;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: inherit;
	opacity: .92;
}

.pingu-scroll-progress-cue-mouse {
	position: relative;
	display: block;
	width: 18px;
	height: 30px;
	border: 1.5px solid currentColor;
	border-radius: 999px;
	box-sizing: border-box;
	opacity: .95;
}

.pingu-scroll-progress-cue-wheel {
	position: absolute;
	left: 50%;
	top: 6px;
	width: 2px;
	height: 6px;
	background: currentColor;
	border-radius: 999px;
	transform: translateX(-50%);
	animation: psvMouseWheel 1.35s ease-in-out infinite;
}

@keyframes psvMouseWheel {
	0% { opacity: 1; transform: translate(-50%, 0); }
	65% { opacity: .15; transform: translate(-50%, 7px); }
	100% { opacity: 0; transform: translate(-50%, 9px); }
}

.pingu-scroll-progress-fill {
	position: absolute;
	inset: 0;
	display: block;
	background: var(--psv-progress-color, #fff);
	border-radius: inherit;
	transform: scaleX(0);
	transform-origin: 0 50%;
	will-change: transform;
	backface-visibility: hidden;
	z-index: 1;
}

.pingu-scroll-progress-markers {
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
}

.pingu-scroll-progress-marker {
	position: absolute;
	top: 50%;
	width: 1px;
	height: var(--psv-progress-marker-height, 12px);
	background: var(--psv-progress-color, #fff);
	opacity: .42;
	transform: translate(-50%, -50%);
	transform-origin: 50% 50%;
	transition: opacity .16s ease, transform .16s ease;
}

.pingu-scroll-progress-marker.is-active {
	opacity: 1;
	transform: translate(-50%, -50%) scaleY(1.35);
}

@media (max-width: 600px) {
	.pingu-scroll-progress {
		left: min(var(--psv-progress-side, 40px), 24px);
		right: min(var(--psv-progress-side, 40px), 24px);
		bottom: min(var(--psv-progress-bottom, 28px), 20px);
	}
}

@media (max-width: 600px) {
	.pingu-scroll-progress-cue {
		bottom: calc(100% + 12px);
		gap: 6px;
	}

	.pingu-scroll-progress-cue-label {
		font-size: 10px;
		letter-spacing: .14em;
	}

	.pingu-scroll-progress-cue-mouse {
		width: 16px;
		height: 26px;
	}
}

/* Optional cover transition: keep the scrub video's final frame pinned for one
   extra viewport while the immediately following Impreza row rises over it.
   The negative margin keeps the page's overall flow length unchanged. */
.pingu-scroll-video-row.psv-following-cover {
	min-height: calc(var(--psv-min-height, 250vh) + var(--psv-cover-tail, 100vh));
	margin-bottom: calc(-1 * var(--psv-cover-tail, 100vh));
	z-index: 0;
}

.pingu-scroll-covering-row {
	position: relative;
	z-index: 6;
}


/* Mobile sticky support: keep the video canvas attached to the viewport while
   the Scroll Video row owns the scroll range. */
@media (max-width: 900px) {
	.pingu-scroll-video-row {
		overflow: visible !important;
	}

	.pingu-scroll-video-row > .pingu-scroll-video-bg {
		top: 0;
		bottom: 0;
		height: auto;
		overflow: visible;
	}

	.pingu-scroll-video-sticky {
		top: 0;
		height: 100svh;
		height: 100dvh;
	}
}


/* Mobile pinning fallback. Mobile Safari and some Android browsers can break
   position: sticky when theme/layout ancestors establish special containing
   blocks. While the Scroll Video row is active, JS pins the background and
   scene viewport directly to the visual viewport instead. */
@media (max-width: 900px), (pointer: coarse) {
	.pingu-scroll-video-row > .pingu-scroll-video-bg.psv-mobile-pinned {
		position: fixed !important;
		inset: 0 !important;
		width: 100vw !important;
		height: var(--psv-mobile-vh, 100dvh) !important;
		min-height: 0 !important;
		z-index: 0;
		transform: none !important;
	}

	.pingu-scroll-video-bg.psv-mobile-pinned > .pingu-scroll-video-sticky {
		position: absolute !important;
		inset: 0 !important;
		width: 100% !important;
		height: 100% !important;
		transform: none !important;
	}

	.pingu-scroll-fx-stage-inner.psv-mobile-pinned {
		position: fixed !important;
		inset: 0 !important;
		width: 100vw !important;
		height: var(--psv-mobile-vh, 100dvh) !important;
		transform: none !important;
	}

	.pingu-scroll-video-row.psv-mobile-active > .l-section-h {
		position: relative;
		z-index: 2;
	}
}
