/**
 * CCI Responsive Video
 *
 * A click-to-play video player that shows a landscape (16:9) or portrait (9:16)
 * source depending on the viewport. Both sources may be present in the markup;
 * exactly one is shown per breakpoint based on the cci-rv--{device}-{orientation}
 * classes set by the widget. An optional message overlaps the video and fades
 * out while it plays.
 *
 * Layout: the wrapper is a plain block and the active frame is an inline-block
 * centred via text-align. The frame's height comes from the in-flow media,
 * which uses a padding-bottom ratio box, so the aspect ratio holds in any
 * container. overflow:hidden clips the media, scrim and player to the rounded
 * corners, and the wrapper isolates its own stacking context so the overlays
 * never paint onto adjacent widgets.
 *
 * Elementor default breakpoints: tablet <= 1024px, mobile <= 767px.
 */

/* Plain block layout (no flexbox) so the widget never inherits or interacts
   with a parent Elementor container's flex-wrap on mobile. The frame is an
   inline-block centred via text-align, and its height comes from the in-flow
   media below — no flex needed. */
.cci-rv {
	display: block;
	width: 100%;
	text-align: center;
	/* Own stacking context: keeps the scrim/play/message/iframe z-indexes
	   contained inside the widget so they can't paint over adjacent widgets. */
	isolation: isolate;
}

/* --- Frames + aspect ratios --------------------------------------------- */

.cci-rv__frame {
	position: relative;
	width: 100%;
	margin: 0;
	display: none; /* shown per breakpoint by the device/orientation classes */
	overflow: hidden; /* clip media / scrim / iframe to the rounded corners */
	vertical-align: top;
	text-align: initial;
	box-sizing: border-box;
	/*
	 * Optional frame border. Off by default (0 width), so existing instances are
	 * unchanged. When the Border Width control sets a width, the transparent
	 * border reveals the frame's own background in the border box: the CCI gold
	 * gradient by default. The Border Colour control overrides this `background`
	 * with a solid colour (as a linear-gradient) only when a colour is set — so
	 * an empty colour keeps the gold gradient (a CSS var fallback would break if
	 * Elementor emits the colour property empty). The in-flow media fills the
	 * padding box and hides the same layer behind it, so only the ring shows.
	 */
	border: var(--cci-rv-border-width, 0px) solid transparent;
	background: linear-gradient(90deg, #856220, #f4e683, #bf923d) border-box;
}

/* Reserve the aspect height with the padding-bottom ratio hack on the MEDIA,
   not the frame. Percentage padding resolves against the PARENT's width, so it
   must sit on an element whose width equals the frame's own (capped) width. The
   media is width:100% of the frame, so its padding tracks the frame's real
   width even when the frame has a smaller max-width than its container. Putting
   the padding on the frame made the box taller than 16:9 (a black band under
   the video) because the % resolved against the wider wrapper. */
.cci-rv__frame--landscape .cci-rv__media {
	padding-bottom: 56.25%; /* 9 / 16 */
}

.cci-rv__frame--portrait .cci-rv__media {
	padding-bottom: 177.78%; /* 16 / 9 */
}

.cci-rv__media {
	position: relative;
	width: 100%;
	height: 0;
	overflow: hidden;
	background: #000;
}

/* Pin the poster to all four edges (not just height:100%) so it always fills
   the frame even when the theme/WordPress forces `img { height: auto }`. */
.cci-rv__thumb {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.cci-rv__iframe {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	width: 100%;
	height: 100%;
	border: 0;
	opacity: 0;
	transition: opacity 0.4s ease;
	z-index: 5;
}

.cci-rv__media.is-video-ready .cci-rv__iframe {
	opacity: 1;
}

/* --- iOS "Tap for sound" ------------------------------------------------- */
/* iOS starts embedded video muted from a tap; this centred pill lets a second
   tap (a direct gesture on the playing video) turn the sound on. Sits above the
   iframe (z-index 5). */
.cci-rv__unmute {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	z-index: 6;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin: 0;
	padding: 11px 18px;
	border: 0;
	border-radius: 999px;
	background: rgba(0, 5, 16, 0.82);
	color: #ffffff;
	font-family: "Inter", sans-serif;
	font-size: 14px;
	font-weight: 600;
	line-height: 1;
	white-space: nowrap;
	cursor: pointer;
	-webkit-appearance: none;
	appearance: none;
	box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
	-webkit-backdrop-filter: blur(4px);
	backdrop-filter: blur(4px);
}

.cci-rv__unmute:hover {
	background: rgba(0, 5, 16, 0.92);
}

.cci-rv__unmute-icon {
	width: 18px;
	height: 18px;
	display: block;
	flex: 0 0 auto;
}

/* --- Play button -------------------------------------------------------- */

.cci-rv__play {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	margin: 0;
	/* Override theme button styling that would otherwise show a background. */
	background: none !important;
	border: none;
	box-shadow: none;
	-webkit-appearance: none;
	appearance: none;
	cursor: pointer;
	transition: transform 0.2s ease, width 0.2s ease, height 0.2s ease,
		opacity 0.4s ease;
	z-index: 3;
}

.cci-rv__media--playable {
	cursor: pointer;
}

/* Fallback grow-on-hover matching the control default (the exact size comes
   from the Play Icon Hover Size control). */
.cci-rv__media--playable:hover .cci-rv__play {
	width: 50px;
	height: 50px;
}

.cci-rv__play:focus-visible {
	outline: none;
}

.cci-rv__play-icon {
	width: 100%;
	height: 100%;
	display: block;
	object-fit: contain;
	pointer-events: none;
}

/* The thumbnail + play button fade out once the video starts. */
.cci-rv__media.is-playing .cci-rv__thumb,
.cci-rv__media.is-playing .cci-rv__play {
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.4s ease;
}

/* Loading spinner: shown from the play tap until the embed is ready to play, so
   a slow-loading player shows a clear "loading" state instead of a blank frame.
   The engine adds .is-playing on tap and .is-video-ready once the player is up,
   which removes the spinner. */
.cci-rv__media--playable.is-playing:not(.is-video-ready)::after {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 46px;
	height: 46px;
	margin: -23px 0 0 -23px;
	border-radius: 50%;
	border: 3px solid rgba(255, 255, 255, 0.28);
	border-top-color: #ffffff;
	animation: cci-rv-spin 0.8s linear infinite;
	z-index: 4;
	pointer-events: none;
}

@keyframes cci-rv-spin {
	to {
		transform: rotate(360deg);
	}
}

/* "Tap for sound" only appears once the player is ready (i.e. after the loading
   spinner clears), never over the still-loading frame. */
.cci-rv__media:not(.is-video-ready) .cci-rv__unmute {
	display: none;
}

/* --- Overlay message ---------------------------------------------------- */

.cci-rv__message {
	--cci-rv-msg-offset: 24px;
	position: absolute;
	left: 50%;
	transform: translateX(-50%);
	max-width: 90%;
	width: max-content;
	z-index: 4;
	color: #fff;
	font-size: 18px;
	line-height: 28px;
	font-weight: 600;
	text-align: center;
	/* Even out wrapped lines so line 1 and line 2 are close to the same width. */
	text-wrap: balance;
	pointer-events: none;
	transition: opacity 0.4s ease, visibility 0.4s ease;
}

.cci-rv__message--top {
	top: var(--cci-rv-msg-offset);
}

.cci-rv__message--bottom {
	bottom: var(--cci-rv-msg-offset);
}

.cci-rv__message--middle {
	top: 50%;
	transform: translate(-50%, calc(-50% + var(--cci-rv-msg-offset)));
}

/* Hide the message while the video is playing; show it otherwise. */
.cci-rv.is-playing .cci-rv__message {
	opacity: 0;
	visibility: hidden;
}

/* --- Optional readability scrim (full width of the video, top/bottom) --- */

.cci-rv--scrim-top .cci-rv__frame::after,
.cci-rv--scrim-bottom .cci-rv__frame::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	height: 45%;
	pointer-events: none;
	z-index: 2;
	transition: opacity 0.4s ease;
}

.cci-rv--scrim-top .cci-rv__frame::after {
	top: 0;
	background: linear-gradient(to bottom, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
}

.cci-rv--scrim-bottom .cci-rv__frame::after {
	bottom: 0;
	background: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
}

.cci-rv.is-playing .cci-rv__frame::after {
	opacity: 0;
}

/* --- Responsive source switching ---------------------------------------- */

/* Desktop (and the base for all widths until a query overrides it). */
.cci-rv--desktop-landscape .cci-rv__frame--landscape,
.cci-rv--desktop-portrait .cci-rv__frame--portrait {
	display: inline-block;
}

@media (max-width: 1024px) {
	.cci-rv--tablet-landscape .cci-rv__frame--landscape,
	.cci-rv--tablet-portrait .cci-rv__frame--portrait {
		display: inline-block;
	}

	.cci-rv--tablet-landscape .cci-rv__frame--portrait,
	.cci-rv--tablet-portrait .cci-rv__frame--landscape {
		display: none;
	}
}

@media (max-width: 767px) {
	.cci-rv--mobile-landscape .cci-rv__frame--landscape,
	.cci-rv--mobile-portrait .cci-rv__frame--portrait {
		display: inline-block;
	}

	.cci-rv--mobile-landscape .cci-rv__frame--portrait,
	.cci-rv--mobile-portrait .cci-rv__frame--landscape {
		display: none;
	}

	/* Elementor sets flex-wrap:wrap on .e-con.e-flex containers at the mobile
	   breakpoint. On a column-direction container this spills the tall video
	   into a second column that overlaps neighbouring widgets.

	   Elementor drives wrap through the custom property --flex-wrap, which the
	   inner flex container consumes via `flex-wrap: var(--flex-wrap)`. Setting
	   the literal flex-wrap on the outer .e-con doesn't reach that inner layout
	   element, so we override the VARIABLE (which inherits down to it) instead.
	   Scoped via :has() to this widget's ancestry; degrades gracefully where
	   :has() is unsupported. */
	.e-con.e-flex:has(.elementor-widget-cci_responsive_video) {
		--flex-wrap: nowrap;
		--flex-wrap-mobile: nowrap;
	}
}
