/* PrettyWellFit Elements — Reveal Scroll Video
   Structure:
   .pwf-reveal            widget root (finale API attaches here)
   .pwf-reveal__stage     viewport-sized frame inside its slide
     .pwf-reveal__video   full-bleed cover video, scrubbed by donated scroll
     .pwf-reveal__window  invisible measuring element (the resting window)
     .pwf-reveal__mask    SVG surround with an expanding rounded-rect hole
     .pwf-reveal__content kicker / headline / bullets / CTA, fades out first
*/

.pwf-reveal {
	--pwf-rev-surround: #FBFFE5;
	--pwf-rev-content: 1;
	position: relative;
	width: 100%;
}

.pwf-reveal__stage {
	position: relative;
	width: 100%;
	height: 100vh;
	height: 100dvh;
	overflow: hidden;
}

/* On its own the widget is its own track: the root is one screen plus
   the Scroll Span, the stage pins to the top, and the runtime walks the
   track. Inside Horizontal Scroll Slides the slides engine owns both. */
.pwf-reveal--solo {
	height: calc( 100vh + var(--pwf-rev-span, 300vh) + var(--pwf-rev-tail, 0px) );
}

/* An End Frame taller than the screen grows to its content instead of
   being cut at the stage edge; the runtime scrolls it up through the
   tail once the video has landed, so every line is reachable. */
.pwf-reveal--tail .pwf-reveal__end > * {
	height: auto;
	min-height: 100%;
}

.pwf-reveal--solo .pwf-reveal__stage {
	position: sticky;
	top: 0;
}

.pwf-reveal__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center center;
}

/* The window's picture fades in once its poster has arrived; Window
   Fill shows until then. Same idea as the collage frame. */
@keyframes pwf-reveal-media-in {
	to { opacity: 1; }
}

/* Same fade under a second name: a running animation keeps its clock
   when only its delay changes, so the ready state starts a fresh one. */
@keyframes pwf-reveal-media-in-now {
	to { opacity: 1; }
}

body:not(.elementor-editor-active) .pwf-reveal__video {
	opacity: 0;
	animation: pwf-reveal-media-in 600ms ease 4s forwards;
}

body:not(.elementor-editor-active) .pwf-reveal__video.is-ready {
	animation: pwf-reveal-media-in-now 600ms ease 0s forwards;
}

.pwf-reveal__window {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	/* The framed window never outgrows the stage: a width set for a
	   desktop still lands as a framed window on a phone, inside a
	   small edge. Per-device Window Width and Height still apply. */
	max-width: calc(100% - 48px);
	max-height: calc(100% - 48px);
	visibility: hidden;
	pointer-events: none;
}

.pwf-reveal__mask {
	position: absolute;
	left: -200px;
	top: -200px;
	width: calc(100% + 400px);
	height: calc(100% + 400px);
	pointer-events: none;
}

.pwf-reveal.is-full .pwf-reveal__mask {
	display: none;
}

.pwf-reveal__mask-path {
	fill: var(--pwf-rev-surround);
}

/* ---------- content layer ---------- */

.pwf-reveal__content {
	position: absolute;
	inset: 0;
	opacity: var(--pwf-rev-content);
	pointer-events: auto;
}

.pwf-reveal.is-departing .pwf-reveal__content {
	pointer-events: none;
}

.pwf-reveal__kicker {
	position: absolute;
	top: 12vh;
	left: 5vw;
	font-size: 0.75rem;
	letter-spacing: 0.3em;
	text-transform: uppercase;
}

.pwf-reveal__headline {
	position: absolute;
	top: 24vh;
	left: 5vw;
	margin: 0;
	width: min(34vw, 30rem);
	font-size: 2.6rem;
	line-height: 1.2;
	font-weight: 400;
}

.pwf-reveal__bullets {
	position: absolute;
	top: 38vh;
	right: 5vw;
	width: min(24vw, 22rem);
	font-size: 0.95rem;
	line-height: 1.5;
}

.pwf-reveal__bullets ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.pwf-reveal__bullets li {
	position: relative;
	padding-left: 1.1em;
	margin-bottom: 1.1em;
}

.pwf-reveal__bullets li::before {
	content: '\2022';
	position: absolute;
	left: 0;
	top: 0;
}

.pwf-reveal__cta {
	position: absolute;
	right: 5vw;
	bottom: 12vh;
	display: inline-block;
	padding: 0.9em 2.2em;
	border: 1px solid currentColor;
	border-radius: 999px;
	text-decoration: none;
	transition: opacity 0.3s ease;
}

.pwf-reveal__cta:hover {
	opacity: 0.7;
}

/* ---------- end frame (full bleed) ---------- */

.pwf-reveal__end {
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.pwf-reveal.is-end-revealed .pwf-reveal__end {
	pointer-events: auto;
}

.pwf-reveal__er {
	opacity: 0;
	translate: 0 24px;
	transition-property: opacity, translate;
	transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

.pwf-reveal__er.pwf-anim--fade-in {
	translate: 0 0;
}

.pwf-reveal__er.pwf-anim--instant {
	transition-duration: 0ms !important;
	transition-delay: 0ms !important;
}

.pwf-reveal.is-end-revealed .pwf-reveal__er {
	opacity: 1;
	translate: 0 0;
}

/* Blur-aware end reveal: with a Background Blur container inside, the
   wrapper hides with visibility instead of opacity so the blur samples
   the video from the first visible pixel; the rise still plays. */
.pwf-reveal__er.pwf-bgblur,
.pwf-reveal__er:has(.pwf-bgblur) {
	opacity: 1;
	visibility: hidden;
}

.pwf-reveal.is-end-revealed .pwf-reveal__er.pwf-bgblur,
.pwf-reveal.is-end-revealed .pwf-reveal__er:has(.pwf-bgblur) {
	visibility: visible;
}

.pwf-reveal.is-end-unrevealing .pwf-reveal__er {
	transition-duration: 300ms !important;
	transition-delay: 0ms !important;
}

/* The nested end-frame container fills the layer, whatever Elementor
   generation produced it. */
.pwf-reveal__end > * {
	height: 100%;
	max-width: none;
}

/* Composed Frame 1 (Frames item 2): a nested container replacing the
   built-in kicker, headline, bullets, and CTA. Fills the content layer;
   its elements use PrettyWellFit Entrance natively (viewport trigger). */
.pwf-reveal__content--composed > * {
	height: 100%;
	max-width: none;
}

/* A finale inside Horizontal Scroll Slides never stacks: the slides
   engine pins and drives it on every screen, so every stacked rule
   below carries :not(.pwf-hslides *) and the runtime drops the stack
   classes there too. */

/* ---------- mobile stack mode ----------
   Below the breakpoint the driven choreography is off (nothing forwards
   scroll to a stacked finale), so the widget shows the landed state
   honestly in flow: Frame 1 content, the video as an ambient looping
   block, the End Frame as a normal section. Every choreography layer is
   torn down; entrances inside the containers still fire on viewport. */

@media (max-width: 1024px) {
body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__stage {
	height: auto;
	min-height: 0;
	overflow: visible;
	display: flex;
	flex-direction: column;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__mask,
body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__window {
	display: none;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__content {
	position: relative;
	inset: auto;
	order: 1;
	opacity: 1;
	pointer-events: auto;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__content--composed > * {
	min-height: 0 !important;
	height: auto !important;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__video {
	position: relative;
	inset: auto;
	order: 2;
	width: 100%;
	height: var(--pwf-rev-stackvh, 62svh);
	display: block;
}

/* The runtime gives the video its own box in the stack: the scrub
   engine draws into whatever box the video fills, so this keeps the
   canvas on the block instead of the whole column. Video and canvas
   both fill it, cropping from the center. */
body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__vbox {
	position: relative;
	order: 2;
	width: 100%;
	height: var(--pwf-rev-stackvh, 62svh);
	overflow: hidden;
	display: block;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__vbox .pwf-reveal__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__end {
	position: relative;
	inset: auto;
	order: 3;
	pointer-events: auto;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__er {
	opacity: 1;
	translate: 0 0;
	visibility: visible;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__er.pwf-bgblur,
body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__er:has(.pwf-bgblur) {
	opacity: 1;
	visibility: visible;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-tablet:not(.pwf-hslides *) .pwf-reveal__end > * {
	min-height: 0 !important;
	height: auto !important;
}
}

@media (max-width: 767px) {
body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__stage {
	height: auto;
	min-height: 0;
	overflow: visible;
	display: flex;
	flex-direction: column;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__mask,
body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__window {
	display: none;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__content {
	position: relative;
	inset: auto;
	order: 1;
	opacity: 1;
	pointer-events: auto;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__content--composed > * {
	min-height: 0 !important;
	height: auto !important;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__video {
	position: relative;
	inset: auto;
	order: 2;
	width: 100%;
	height: var(--pwf-rev-stackvh, 62svh);
	display: block;
}

/* The runtime gives the video its own box in the stack: the scrub
   engine draws into whatever box the video fills, so this keeps the
   canvas on the block instead of the whole column. Video and canvas
   both fill it, cropping from the center. */
body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__vbox {
	position: relative;
	order: 2;
	width: 100%;
	height: var(--pwf-rev-stackvh, 62svh);
	overflow: hidden;
	display: block;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__vbox .pwf-reveal__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	display: block;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__end {
	position: relative;
	inset: auto;
	order: 3;
	pointer-events: auto;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__er {
	opacity: 1;
	translate: 0 0;
	visibility: visible;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__er.pwf-bgblur,
body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__er:has(.pwf-bgblur) {
	opacity: 1;
	visibility: visible;
}

body:not(.elementor-editor-active) .pwf-reveal--mb-stack.pwf-reveal--sbp-mobile:not(.pwf-hslides *) .pwf-reveal__end > * {
	min-height: 0 !important;
	height: auto !important;
}
}

/* ---------- small screens ---------- */

@media (max-width: 767px) {
	.pwf-reveal__kicker {
		top: 6vh;
		left: 6vw;
	}
	.pwf-reveal__headline {
		top: 10vh;
		left: 6vw;
		width: 88vw;
		font-size: 1.6rem;
	}
	.pwf-reveal__bullets {
		top: auto;
		bottom: 16vh;
		left: 6vw;
		right: 6vw;
		width: auto;
		font-size: 0.85rem;
	}
	.pwf-reveal__bullets li {
		margin-bottom: 0.7em;
	}
	.pwf-reveal__cta {
		right: auto;
		left: 6vw;
		bottom: 5vh;
	}
}



/* ---------- Elementor editor: composed state ---------- */

.elementor-editor-active .pwf-reveal {
	--pwf-rev-content: 1;
}

/* The editor shows the true composed state: the video, window, and mask
   pin to a viewport-height region, Frame 1 overlays it exactly as it
   renders live, and the End Frame flows beneath as its own labeled
   editing block. (Children are stored end-first; position handles the
   visual order.) */
.elementor-editor-active .pwf-reveal__stage {
	height: auto;
	min-height: 100vh;
}

.elementor-editor-active .pwf-reveal__mask {
	top: 0;
	bottom: auto;
	height: 100vh;
}

/* The video is a viewport-height sticky layer at the widget root,
   showing its final frame: correct cover scale through the window above
   and behind the End Frame block below, exactly the state the widget
   finishes on live. The root keeps a viewport minimum so the video band
   always fits inside it even while the frames are still sparse, and the
   clip bounds the paint so the video can never spill behind whatever
   follows the widget in the canvas. */
.elementor-editor-active .pwf-reveal {
	min-height: 100vh;
	overflow: clip;
}

.elementor-editor-active .pwf-reveal > .pwf-reveal__video {
	position: sticky;
	top: 0;
	bottom: auto;
	height: calc( 100vh + var(--pwf-rvl-blend-h, 0vh) );
	width: 100%;
	display: block;
	margin-bottom: calc( -100vh - var(--pwf-rvl-blend-h, 0vh) );
}

/* The window is a control-sized measurement proxy: width and height stay
   the controls' so those previews are live. Only its anchor moves —
   centered within the top viewport-height band. */
.elementor-editor-active .pwf-reveal__window {
	top: 50vh;
	bottom: auto;
	transform: translate(-50%, -50%);
}

.elementor-editor-active .pwf-reveal .pwf-reveal__end {
	position: static;
	display: block;
	opacity: 1;
	visibility: visible;
	translate: none;
	transition: none;
	will-change: auto;
	padding-top: 100vh;
	pointer-events: auto;
}

/* Frame 1: overlaid on the masked video, edited in place. */
.elementor-editor-active .pwf-reveal .pwf-reveal__end > :nth-last-child(1 of .e-con) {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	height: 100vh;
	overflow: hidden;
}

/* End Frame: labeled block in flow below the stage. */
.elementor-editor-active .pwf-reveal .pwf-reveal__end::before {
	content: 'END FRAME';
	display: block;
	padding: 10px 10px 6px;
	font-size: 10px;
	letter-spacing: 0.2em;
	opacity: 0.5;
}

.elementor-editor-active .pwf-reveal .pwf-reveal__end > :nth-child(1 of .e-con) {
	min-height: 30vh;
	outline: 1px dashed rgba(0, 0, 0, 0.25);
	outline-offset: -1px;
}

/* Blend strip: extra canvas hanging off the bottom of the section the
   reveal finishes. The engine re-homes it onto the enclosing slides
   track at boot, so it escapes the stage clip and rides in exactly as
   the section releases. Height and background come from the widget's
   Blend controls via the ID class; it never takes layout space. */
.pwf-rvl-blend {
	position: absolute;
	top: 100%;
	left: 0;
	right: 0;
	height: 0;
	pointer-events: none;
	z-index: 6;
}

/* The media continues into the bleed: inside a blend-active slides
   track the reveal video paints taller by the blend height, escaping
   the stage clip at the bottom as one continuous element, so the
   gradient strip dissolves live footage instead of sitting past a
   hard media edge. */
.pwf-hslides--blend .pwf-reveal__video {
	height: calc( 100% + var(--pwf-rvl-blend-h, 0vh) );
}

.pwf-hslides--blend .pwf-reveal__stage {
	overflow: visible;
	overflow-x: clip;
}

/* The End Frame is the layer on screen at rest, so under an active
   blend its composed child stretches with it and the child's own
   background — the imagery the visitor is actually seeing — continues
   into the zone beneath the gradient. */
.pwf-hslides--blend .pwf-reveal__end > * {
	min-height: 100%;
}

.elementor-editor-active .pwf-rvl-blend {
	position: relative;
	display: block;
	width: 100%;
	overflow: hidden;
	z-index: 7;
}

/* Editor-only footage echo: the strip carries a bottom-anchored slice
   of the same video so the canvas shows the gradient dissolving live
   footage, exactly as the front renders — no dependence on the main
   preview band's layout. The gradient repaints above it via the
   overlay, since a container's own background sits under its
   children. */
.elementor-editor-active .pwf-rvl-blend__echo {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	height: calc( 100vh + var(--pwf-rvl-blend-h, 0vh) );
	object-fit: cover;
	object-position: center bottom;
	display: block;
}

.elementor-editor-active .pwf-rvl-blend::after {
	content: '';
	position: absolute;
	inset: 0;
	background: inherit;
	pointer-events: none;
}

.pwf-rvl-blend__echo {
	display: none;
}
