Media frames
Put every image and video in a frame that reserves its space, loads from a mosaic, and ships as AVIF.
Every image and video in Mira lives in a frame, and the frame is the only decoration. Each part of it does a job:
- Reserved space. The compiler writes the exact width and height, so the page never jumps.
- Pixel mosaic. An 8×8 mosaic of the image’s real colors paints first, then resolves into the photo in steps. It is the loading state, built from the logo’s pixel module.
- Corner handles. They appear only when the image opens full size, so they tell the reader it is clickable.
- Hairline border. It is the only line, and it doubles as the focus ring.
- Caption line. Mono text that holds the real caption and credit.
Images
In Markdown, keep the whole <mira-frame> tag on one line. Markdown only treats a line as HTML when the opening tag is complete on that line, so a tag split across lines renders as text. In .mira templates, any layout works.
| Attribute | Meaning |
|---|---|
src | The file. ./x.png is relative to the file that contains the frame, /x.png is under public/, and @/x.png is under the project root |
alt | Required. Describe the image, or use alt="" when it is decoration |
caption | Optional caption shown under the frame |
credit | Optional credit, shown after the caption |
zoom | The frame links to the original at full size and shows corner handles |
Frames take PNG, JPEG, GIF, WebP, AVIF, and SVG. A missing alt fails the build with the file and a hint.
Markdown images
Images in Markdown become frames automatically. The title becomes the caption:
An image alone in its paragraph replaces the paragraph, since a figure cannot sit inside one.
Video
Video frames use the same parts. The poster image’s mosaic is the loading state, a rounded pill plays and pauses, a thin progress line runs along the bottom edge, and the corner handles turn ember while the video plays. Mira cannot read a video’s size, so width and height are required. The controls are a small script that loads only on pages with a video frame.
Output
Each file is written once, however many pages use it, under a readable name with a short content hash:
/media/pipeline-7kq2.avif
/media/pipeline-7kq2.png
Raster images are encoded to AVIF beside the original, and pages serve the AVIF with the original as a fallback. Encoding is pure Rust and cached by content hash in .mira/cache/media, so a second build performs no encodes. If the AVIF would be larger than the original, Mira ships the original alone.
media.json
Every build with frames writes /media.json, a manifest of every file:
Hosts and agents read it, and llms.txt links it.
The rule for decoration
Delete it. If something breaks (layout shift, state, clarity, or a click target), it stays. Otherwise it goes. One hue per frame, hairlines only, and no shadows or gradients on media.