<script lang="ts">
	// Crossfade + slow zoom and pan (the "Ken Burns" effect). Image-only — videos
	// fall back to the crossfade behaviour to avoid double-animation.

	interface Props {
		src: string;
		isVideo: boolean;
		durationMs: number;
		/** Fired when a video slide finishes so the parent can advance early. */
		onended?: () => void;
	}

	let { src, isVideo, durationMs, onended }: Props = $props();

	// Mild random pan so each slide feels different. Range chosen so the image never
	// pans out of frame given the object-fit: cover.
	const panX = Math.round((Math.random() - 0.5) * 6); // -3% .. +3%
	const panY = Math.round((Math.random() - 0.5) * 6);
</script>

<!-- Both animations live in scoped classes rather than inline `style="animation:…"`.
	 Svelte scopes `@keyframes` names and only rewrites `animation` references inside this
	 <style> block, so an inline animation name never matches the scoped keyframe and the
	 effect silently dies. Dynamic values (fade duration, pan origin) pass through as inline
	 custom properties / properties that Svelte leaves untouched. -->
<div
	class="kb absolute inset-0 flex items-center justify-center overflow-hidden bg-black"
	style="--fade-dur: {durationMs}ms"
>
	{#if isVideo}
		<!-- svelte-ignore a11y_media_has_caption -->
		<video {src} autoplay muted playsinline {onended} class="h-full w-full object-contain"></video>
	{:else}
		<img
			{src}
			alt=""
			class="kb-img h-full w-full object-cover"
			style="transform-origin: {50 + panX}% {50 + panY}%;"
		/>
	{/if}
</div>

<style>
	.kb {
		animation: kb-fade var(--fade-dur, 600ms) ease-out forwards;
	}
	.kb-img {
		animation: kb-zoom 10s ease-out forwards;
	}
	@keyframes kb-fade {
		from {
			opacity: 0;
		}
		to {
			opacity: 1;
		}
	}
	@keyframes kb-zoom {
		from {
			transform: scale(1);
		}
		to {
			transform: scale(1.1);
		}
	}
</style>
