---
/**
* A short video.
*
* The file itself is not in git — it lives on the server under
* /opt/eratic/media and is referenced by path:
*
* <Video src="video/2026/harbour.mp4" poster="video/2026/harbour.jpg"
* alt="Boats moving in a harbour at dusk" />
*
* Both `src` and `poster` go through mediaUrl(), so the day ird ships IPFS you
* can change this one reference to "ipfs://bafy…", set MEDIA.ipfsGateway in
* config.ts, and nothing else in the codebase moves.
*
* `preload="metadata"` means a page with five clips on it downloads five
* headers, not five videos.
*/
import { mediaUrl } from '../config.js';
interface Props {
src: string;
/** Still frame shown before playback. Strongly recommended. */
poster?: string;
/** Describes the video for anyone who cannot see it. */
alt?: string;
caption?: string;
width?: 'content' | 'wide' | 'full';
/** Silent looping clip with no controls — treat it as a moving photograph. */
ambient?: boolean;
}
const { src, poster, alt, caption, width = 'wide', ambient = false } = Astro.props;
const source = mediaUrl(src);
const posterUrl = poster ? mediaUrl(poster) : undefined;
const type = source.endsWith('.webm') ? 'video/webm' : 'video/mp4';
---
<figure class:list={[width === 'wide' && 'u-wide', width === 'full' && 'u-full']}>
{/* eslint-disable-next-line jsx-a11y/media-has-caption -- short silent clips */}
<video
poster={posterUrl}
controls={!ambient}
autoplay={ambient}
loop={ambient}
muted={ambient}
playsinline
preload="metadata"
aria-label={alt}
>
<source src={source} type={type} />
<p>
Your browser cannot play this video. <a href={source}>Download it instead</a>.
</p>
</video>
{caption && <figcaption>{caption}</figcaption>}
</figure>
<style>
video {
inline-size: 100%;
block-size: auto;
background: var(--surface-sunk);
border-radius: var(--radius);
}
</style>