/**
 * Mooovy Portfolio - front-end styles.
 * Scoped under .mooovy-portfolio / .mooovy-lightbox so it never leaks into
 * the rest of the theme. Uses CSS custom properties for the few things a
 * site owner is likely to want to tweak from a child theme.
 */

.mooovy-portfolio {
	--mooovy-cols: 3;
	--mooovy-gap: 24px;
	--mooovy-row-gap: 24px;
	--mooovy-radius: 10px;
	--mooovy-accent: #ff3b30;
	--mooovy-text: inherit;
	--mooovy-muted: #6b7280;
	--mooovy-card-bg: #111318;
	--mooovy-filter-bg: #f1f1f3;
	--mooovy-filter-text: #333;
	--mooovy-filter-hover: #00B4D8;
	--mooovy-title-color: var(--mooovy-text);
	--mooovy-overlay-color: rgba(0, 0, 0, .55);
	--mooovy-overlay-height: 100%;
	--mooovy-play-size: 62px;
	--mooovy-play-bg: rgba(0, 0, 0, .45);
	--mooovy-play-color: #fff;
	--mooovy-play-bg-hover: #ff3b30;
	--mooovy-play-color-hover: #fff;
	display: block;
	padding-bottom: 40px !important;
	box-sizing: border-box;
	/* In a column-direction flex Container (Elementor's default), the
	   cross axis is horizontal - so align-self actually controls our
	   WIDTH, not height (a lesson learned the hard way: setting it to
	   flex-start here previously shrank the whole widget to min-content
	   width). Force full width explicitly instead, and only opt out of
	   height-related stretch behavior, which is the axis that actually
	   caused a sibling section to start inside our own visual content. */
	width: 100% !important;
	min-height: 0 !important;
}

.mooovy-portfolio *,
.mooovy-portfolio *::before,
.mooovy-portfolio *::after {
	box-sizing: border-box;
}

/* Same reasoning as above, targeting Elementor's own generated wrapper
   around this widget - it (not our own inner div) is the actual flex/grid
   item inside the surrounding Elementor Container. Width stays 100% (see
   note above about align-self controlling width in a column flex
   Container); only height-related sizing is reset. */
.elementor-widget-mooovy_portfolio,
.elementor-widget-mooovy_portfolio > .elementor-widget-container {
	width: 100% !important;
	min-height: 0 !important;
	height: auto !important;
}

/* ---------------------------------------------------------------------- */
/* Filter bar                                                              */
/* ---------------------------------------------------------------------- */

.mooovy-filters {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 12px 36px;
	margin: 0 0 40px;
}

.mooovy-filter,
.mooovy-filter:hover,
.mooovy-filter:focus,
.mooovy-filter:active,
.mooovy-filter.is-active {
	/* !important: some themes apply their own background/border to generic
	   buttons on hover/focus/active, which would otherwise show through as
	   an unwanted colored box behind the filter text. */
	background: none !important;
	background-color: transparent !important;
	border: 0 !important;
	box-shadow: none !important;
}

.mooovy-filter {
	appearance: none;
	outline: none;
	cursor: pointer;
	/* !important: these are real <button> elements, and some themes apply
	   their own default text color to generic buttons at a specificity (or
	   with an !important of their own) that a plain single-class selector
	   can't beat - same reasoning as the background/border !important
	   above. */
	color: var(--mooovy-filter-text) !important;
	font-size: 15px;
	line-height: 1;
	font-weight: 500;
	letter-spacing: .02em;
	padding: 4px 0;
	border-radius: 2px;
	transition: color .2s ease;
}

.mooovy-filter.is-active {
	color: var(--mooovy-filter-hover) !important;
}

/* Only show a focus ring for keyboard navigation, not on mouse click. */
.mooovy-filter:focus-visible {
	outline: 2px solid var(--mooovy-filter-hover);
	outline-offset: 3px;
}

/* ---------------------------------------------------------------------- */
/* Grid                                                                    */
/* ---------------------------------------------------------------------- */

.mooovy-grid {
	display: grid;
	grid-template-columns: repeat(var(--mooovy-cols, 3), 1fr);
	column-gap: var(--mooovy-gap);
	row-gap: var(--mooovy-row-gap);
}

@media (max-width: 1024px) {
	.mooovy-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 640px) {
	.mooovy-portfolio {
		padding-bottom: 24px !important;
	}

	.mooovy-grid {
		grid-template-columns: 1fr;
		--mooovy-gap: 18px;
		--mooovy-row-gap: 18px;
	}
}

.mooovy-item {
	position: relative;
	display: flex;
	flex-direction: column;
}

.mooovy-item.is-hidden {
	display: none;
}

/* ---------------------------------------------------------------------- */
/* Cover / hover preview / play button                                    */
/* ---------------------------------------------------------------------- */

.mooovy-item__media {
	position: relative;
	overflow: hidden;
	border-radius: var(--mooovy-radius);
	background: var(--mooovy-card-bg);
	aspect-ratio: 16 / 10;
	cursor: pointer;
}

.mooovy-item__media--no-video {
	cursor: default;
}

.mooovy-item__cover,
.mooovy-item__preview {
	position: absolute;
	inset: 0;
	width: 100% !important;
	height: 100% !important;
	max-width: none !important;
	/* !important: some hosts (LiteSpeed's image auto-sizing among them)
	   inject their own object-fit:contain rule for images that don't match
	   the container's aspect ratio, which would otherwise letterbox the
	   cover and reveal the dark card background behind it. Covers always
	   need to crop-to-fill instead, regardless of their native ratio. */
	object-fit: cover !important;
	display: block;
}

.mooovy-item__cover {
	transition: transform .5s ease, opacity .35s ease;
}

.mooovy-item__cover--placeholder {
	background: linear-gradient(135deg, #23262f, #14161b);
}

.mooovy-item__preview {
	opacity: 0;
	transition: opacity .35s ease;
	pointer-events: none;
}

.mooovy-item__media.is-previewing .mooovy-item__cover {
	opacity: 0;
}

.mooovy-item__media.is-previewing .mooovy-item__preview {
	opacity: 1;
}

.mooovy-item__play {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	z-index: 3;
	width: var(--mooovy-play-size);
	height: var(--mooovy-play-size);
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--mooovy-play-bg);
	color: var(--mooovy-play-color);
	backdrop-filter: blur(2px);
	transition: background-color .2s ease, color .2s ease, transform .2s ease, opacity .2s ease;
}

.mooovy-item__play svg {
	width: 38%;
	height: 38%;
	margin-left: 6%;
}

.mooovy-item__media.is-previewing .mooovy-item__play {
	opacity: 0;
}

/* ---------------------------------------------------------------------- */
/* Hover-only effects - gated behind an actual hover-capable pointer so    */
/* touch devices never see a lingering ":hover" style. Many mobile         */
/* browsers require a *second* tap to actually fire a click on any        */
/* element that has hover styles (the first tap only "previews" hover),   */
/* so keeping these out of touch devices entirely means the first tap     */
/* activates the video immediately instead of needing two taps.           */
/* ---------------------------------------------------------------------- */

@media (hover: hover) and (pointer: fine) {
	.mooovy-filter:hover {
		color: var(--mooovy-filter-hover) !important;
	}

	.mooovy-item__media:hover .mooovy-item__cover {
		transform: scale(1.04);
	}

	.mooovy-item__media:hover .mooovy-item__play {
		background: var(--mooovy-play-bg-hover);
		color: var(--mooovy-play-color-hover);
		transform: translate(-50%, -50%) scale(1.08);
	}

	.mooovy-title-overlay .mooovy-item__media:hover ~ .mooovy-item__body::before {
		background: transparent;
	}

	.mooovy-title-overlay .mooovy-item__media:hover ~ .mooovy-item__body .mooovy-item__title {
		opacity: 0;
	}
}

/* ---------------------------------------------------------------------- */
/* Inline playback (touch devices - no lightbox, plays in the card)       */
/* ---------------------------------------------------------------------- */

.mooovy-item__inline-player {
	position: absolute;
	inset: 0;
	z-index: 4;
	background: #000;
}

.mooovy-item__inline-player iframe,
.mooovy-item__inline-player video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	display: block;
	background: #000;
}

.mooovy-item__media.is-playing-inline .mooovy-item__cover,
.mooovy-item__media.is-playing-inline .mooovy-item__preview,
.mooovy-item__media.is-playing-inline .mooovy-item__play {
	opacity: 0;
	pointer-events: none;
}

.mooovy-title-overlay .mooovy-item__media.is-playing-inline ~ .mooovy-item__body {
	opacity: 0;
	pointer-events: none;
}

/* ---------------------------------------------------------------------- */
/* Card body / title (never a link)                                       */
/* ---------------------------------------------------------------------- */

.mooovy-item__body {
	padding: 16px 2px 0;
}

.mooovy-item__title {
	margin: 0 0 6px;
	font-size: 18px;
	line-height: 1.35;
	font-weight: 600;
	color: var(--mooovy-title-color);
	cursor: default;
}

/* ---------------------------------------------------------------------- */
/* "Title on cover" mode - the play button stays at the optical center of */
/* the cover, with the title sitting just below it, on a colored tint.    */
/* On hover, both the tint and the title fade out so the hover preview    */
/* video plays clean, with nothing drawn over it.                         */
/* ---------------------------------------------------------------------- */

.mooovy-title-overlay .mooovy-item__body {
	position: absolute;
	inset: 0;
	z-index: 2;
	pointer-events: none;
}

/* The tint lives on its own pseudo-element, sized/anchored independently
   of .mooovy-item__body - which stays full-size so the title's "top: 50%"
   below keeps meaning 50% of the whole cover, not 50% of a shrunk tint
   band. This is what lets "Cover Overlay Height" resize the tint without
   dragging the title's own position along with it.
   .mooovy-item__body is a sibling of .mooovy-item__media (not a child of
   it - see templates/item.php), so it falls outside .mooovy-item__media's
   own overflow:hidden/border-radius and needs its own rounding here to
   match the cover's corners instead of showing square ones. Only the
   bottom corners are rounded - the top ones stay square, since once the
   tint is shorter than the full cover (Cover Overlay Height < 100%) its
   top edge floats over the middle of the image rather than sitting on an
   actual card corner, where a rounded corner would look like a stray
   notch rather than matching anything. */
.mooovy-title-overlay .mooovy-item__body::before {
	content: '';
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: var(--mooovy-overlay-height, 100%);
	border-radius: 0 0 var(--mooovy-radius) var(--mooovy-radius);
	background: var(--mooovy-overlay-color);
	transition: background-color .25s ease, height .25s ease;
}

.mooovy-title-overlay .mooovy-item__title {
	position: absolute;
	left: 50%;
	top: 50%;
	width: calc(100% - 40px);
	margin: 0;
	opacity: 1;
	transition: opacity .25s ease;
	transform: translate(-50%, var(--mooovy-title-offset, 30px));
	text-align: var(--mooovy-title-align, center);
	text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
}

.mooovy-title-overlay .mooovy-item__excerpt {
	display: none;
}

.mooovy-item__excerpt {
	margin: 0;
	font-size: 14px;
	line-height: 1.5;
	color: var(--mooovy-muted);
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.mooovy-empty {
	text-align: center;
	color: var(--mooovy-muted);
	padding: 40px 0;
}

.mooovy-portfolio-notice {
	padding: 12px 16px;
	border-left: 3px solid var(--mooovy-accent, #ff3b30);
	background: rgba(0, 0, 0, .04);
	font-size: 14px;
}

/* ---------------------------------------------------------------------- */
/* Lightbox                                                                */
/* ---------------------------------------------------------------------- */

.mooovy-lightbox {
	position: fixed;
	inset: 0;
	z-index: 100000;
	display: none;
}

.mooovy-lightbox.is-open {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
}

.mooovy-lightbox__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(8, 8, 10, .92);
}

.mooovy-lightbox__dialog {
	position: relative;
	z-index: 1;
	/* Capped at 1280px: Bunny Stream's own iframe player page internally
	   caps its video wrapper at max-width:1280px and centers it, filling
	   any extra width with its own page background (#04192c) - which we
	   have no way to reach or restyle from here, being cross-origin
	   content. Staying at or under 1280px keeps their player always
	   filling the full width, so that background never shows. */
	width: min(1280px, 92vw);
	max-height: 92vh;
	/* !important: some themes style any [role="dialog"] generically (a
	   background color, padding, border), which would otherwise show as an
	   unwanted colored frame around the video. */
	background: transparent !important;
	padding: 0 !important;
	border: 0 !important;
	box-shadow: none !important;
}

.mooovy-lightbox__content {
	position: relative;
	width: 100%;
	aspect-ratio: 16 / 9;
	background: #000;
	border-radius: 8px;
	overflow: hidden;
}

.mooovy-lightbox__content iframe,
.mooovy-lightbox__content video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	display: block;
	background: #000;
}

.mooovy-lightbox__close,
.mooovy-lightbox__close:focus,
.mooovy-lightbox__close:active {
	/* !important: some themes apply their own background/border/outline to
	   generic buttons by default (not just on hover/focus), which would
	   otherwise show through as a solid colored dot with the "x" icon
	   inside it hidden. */
	background: rgba(255, 255, 255, .12) !important;
	border: 0 !important;
	outline: none !important;
	box-shadow: none !important;
	color: #fff !important;
}

.mooovy-lightbox__close {
	position: absolute;
	top: -46px;
	right: 0;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	transition: background-color .2s ease;
}

.mooovy-lightbox__close svg {
	/* Fixed px (not %): some themes normalize all svg/icon sizing (e.g. to
	   1em), which a percentage width/height doesn't reliably override. */
	width: 22px !important;
	height: 22px !important;
	flex-shrink: 0 !important;
	fill: currentColor !important;
	pointer-events: none;
}

.mooovy-lightbox__close:hover {
	background: #00B4D8 !important;
}

@media (max-width: 640px) {
	.mooovy-lightbox.is-open {
		padding: 0;
	}

	.mooovy-lightbox__dialog {
		width: 100vw;
		max-height: 100vh;
	}

	.mooovy-lightbox__content {
		border-radius: 0;
	}

	.mooovy-lightbox__close {
		top: 10px;
		right: 10px;
		background: rgba(0, 0, 0, .55);
	}
}

html.mooovy-lightbox-open {
	overflow: hidden;
}

/* Respect users who've asked for reduced motion. */
@media (prefers-reduced-motion: reduce) {
	.mooovy-item__cover,
	.mooovy-item__preview,
	.mooovy-item__play,
	.mooovy-filter {
		transition: none !important;
	}

	.mooovy-item__media:hover .mooovy-item__cover {
		transform: none;
	}
}
