/* Mobile Project Showcase widget — a swipe/drag-navigated, infinitely
   looping, scroll-snapping filmstrip of phone screenshots with your
   uploaded phone mockup image fixed in the center (inspired by
   microbits.co's "Featured Projects" section). The slide box is derived
   from --mps-frame-w × --mps-frame-ratio (the mockup's real pixel
   ratio, computed server-side) minus the configured screen insets, so
   screenshots fill the mockup's screen exactly. */

.mps {
	background-color: transparent;
	text-align: center;
	font-family: 'Poppins', sans-serif;
}

/* ---------- Viewport / track ---------- */
.mps__viewport {
	--mps-frame-w: 220px;
	--mps-frame-ratio: 2.0909; /* height / width, e.g. 916/440 */
	/* % of the frame's own width/height that is bezel on each side —
	   independent per side, since most mockups aren't perfectly
	   symmetric (unitless numbers, e.g. 4.3 not "4.3%"). */
	--mps-inset-top: 0;
	--mps-inset-right: 0;
	--mps-inset-bottom: 0;
	--mps-inset-left: 0;
	--mps-gap: 20px;

	--mps-frame-h: calc( var(--mps-frame-w) * var(--mps-frame-ratio) );
	--mps-slide-w: calc( var(--mps-frame-w) * ( 1 - ( var(--mps-inset-left) + var(--mps-inset-right) ) / 100 ) );
	--mps-slide-h: calc( var(--mps-frame-h) * ( 1 - ( var(--mps-inset-top) + var(--mps-inset-bottom) ) / 100 ) );

	/* When insets aren't symmetric, the screen's own center isn't the
	   frame image's geometric center — these offset the frame (not the
	   slide) so the *screen* lines up with the viewport's center, where
	   the scrolling slide actually sits. */
	--mps-frame-offset-x: calc( var(--mps-frame-w) * ( var(--mps-inset-left) - var(--mps-inset-right) ) / 200 );
	--mps-frame-offset-y: calc( var(--mps-frame-h) * ( var(--mps-inset-top) - var(--mps-inset-bottom) ) / 200 );

	position: relative;
	max-width: 100%;
	background-color: transparent;
	padding: 40px 0;
}

.mps__track {
	display: flex;
	align-items: center;
	gap: var(--mps-gap);
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-ms-overflow-style: none;
	cursor: grab;
	touch-action: pan-x;
	/* Keeps the swipe gesture confined to the filmstrip itself — without
	   this, dragging past either physical end of the track (before the
	   infinite-loop recentering kicks in) can hand the gesture off to the
	   surrounding page, scrolling it vertically too. */
	overscroll-behavior-x: contain;
	/* Deliberately no scroll-behavior: smooth — it would also apply to
	   the JS-driven initial centering and infinite-loop recentering
	   jumps (per spec it affects any scrollLeft change, not just
	   scrollBy()/scrollTo()), making both visibly animate instead of
	   snapping instantly. Native touch/snap settling is unaffected by
	   this property either way. Center the first/last slide under the
	   fixed frame instead of pinning them to the viewport edge. */
	padding: 0 calc( 50% - var(--mps-slide-w) / 2 );
}

.mps__track::-webkit-scrollbar {
	display: none;
}

.mps__track.mps--dragging {
	cursor: grabbing;
	scroll-snap-type: none;
	user-select: none;
}

.mps__track.mps--dragging .mps__slide {
	pointer-events: none;
}

/* ---------- Slides ---------- */
.mps__slide {
	position: relative;
	flex: 0 0 auto;
	width: var(--mps-slide-w);
	height: var(--mps-slide-h);
	border-radius: 24px;
	overflow: hidden;
	display: block;
	text-decoration: none;
	background-color: #EAEAEA;
	scroll-snap-align: center;
	/* transform/filter (scale + blur, based on distance from center)
	   are applied inline by JS on every scroll frame — this transition
	   just smooths between those updates. transform-origin: center
	   keeps the shrink centered instead of pulling toward one edge. */
	transform-origin: center center;
	transition: transform 0.12s linear, filter 0.12s linear;
	will-change: transform, filter;
}

.mps__slide img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: 50% 50%;
	display: block;
	-webkit-user-drag: none;
	user-select: none;
}

/* Panorama mode: a screenshot taller than the mockup's own screen (e.g.
   a full-page or full-feed capture) pans down through itself instead of
   being cropped by object-fit: cover. object-position is animated as a
   percentage, which CSS defines relative to the *overflow* amount — 0%
   shows the top of the image, 100% the bottom — so this works at any
   image height without knowing its pixel dimensions.

   Keyframe stops (not the timing-function) create a gentle fast → slow →
   fast pace: the first/last 20% of the time each cover 30% of the
   distance (1.5x average speed), the middle 60% of the time covers the
   remaining 40% (0.67x average speed) — a mild difference, not a jolt. */
.mps__slide--panorama img {
	--mps-pano-duration: 22s;
	object-position: 50% 0%;
	animation: mps-pano-scroll var(--mps-pano-duration) linear infinite alternate;
	animation-delay: 1.2s;
	/* Paused until JS marks this slide as the one currently centered
	   inside the phone mockup (`.is-centered`, toggled every scroll frame
	   in applyEmphasis()) — off-center slides sit still on their first
	   frame instead of panning in the background. */
	animation-play-state: paused;
}

.mps__slide.is-centered.mps__slide--panorama img {
	animation-play-state: running;
}

@keyframes mps-pano-scroll {
	0% {
		object-position: 50% 0%;
	}
	20% {
		object-position: 50% 30%;
	}
	80% {
		object-position: 50% 70%;
	}
	100% {
		object-position: 50% 100%;
	}
}

/* A small info panel, not a full-slide dark overlay — it sits below the
   visible frame at rest and slides up into view on hover (clipped by
   the slide's own overflow: hidden while hidden). */
.mps__overlay {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: 14px 18px;
	background: rgba( 20, 21, 21, 0.82 );
	transform: translateY( 100% );
	transition: transform 0.3s ease;
}

.mps__slide:hover .mps__overlay {
	transform: translateY( 0 );
}

.mps__overlay-title {
	margin-bottom: 6px;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.4px;
	line-height: 1.4;
	text-transform: uppercase;
	color: #ffffff;
}

.mps__overlay-subtitle {
	font-size: 11px;
	letter-spacing: 0.3px;
	text-transform: uppercase;
	color: rgba( 255, 255, 255, 0.7 );
}

.mps__overlay-subtitle strong {
	font-weight: 700;
	color: #ffffff;
}

/* ---------- Phone frame overlay ---------- */
.mps__frame-wrap {
	position: absolute;
	top: 50%;
	left: 50%;
	/* Centers the frame, then nudges it by --mps-frame-offset-*  so the
	   mockup's *screen* (not the frame image's own geometric center)
	   lines up with the viewport's center, where the slide sits. */
	transform: translate( calc( -50% - var(--mps-frame-offset-x) ), calc( -50% - var(--mps-frame-offset-y) ) );
	width: var(--mps-frame-w);
	height: var(--mps-frame-h);
	pointer-events: none;
	z-index: 3;
}

.mps__frame-img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: contain;
}

@media ( max-width: 767px ) {
	.mps__viewport {
		/* Same full-width filmstrip as desktop — however many slides fit
		   the section's actual width show, same as any other breakpoint.
		   Only the padding is trimmed a bit for mobile's tighter spacing;
		   sizing itself is already handled by the widget's responsive
		   Frame Width control. */
		padding: 28px 0;
	}
}
