One prompt, four fictional video models. The clips run 7 to 21 seconds and line up by percentage, so halfway is halfway in all of them. Stack them and move up and down to flip between outputs on the same frame.
@keyframeui
registry/demos/sync-grid-models-demo.tsx
import { SyncGrid, SyncGridItem } from "@/components/ui/sync-grid";
const prompt = "A paper boat drifting down a rain-soaked street";
// Four clips of different lengths, lined up by percentage: halfway through
// one is halfway through all of them.
const outputs = [
{ model: "Bramble 2", clip: 49029, time: "38s", cost: "$0.09" },
{ model: "Fernlight XL", clip: 17291, time: "1m 12s", cost: "$0.31" },
{ model: "Quarry", clip: 28088, time: "54s", cost: "$0.18" },
{ model: "Nimbus v4", clip: 31551, time: "27s", cost: "$0.06" },
];
const video = (id: number) => `https://assets.mixkit.co/videos/${id}/${id}-720.mp4`;
const poster = (id: number) => `https://assets.mixkit.co/videos/${id}/${id}-thumb-720-0.jpg`;
export function SyncGridModelsDemo() {
return (
<div className="w-full max-w-3xl">
<div className="mb-4 flex items-center gap-3 rounded-2xl border border-zinc-200 bg-white px-3 py-2.5 shadow-sm dark:border-zinc-800 dark:bg-zinc-900">
<span className="grid size-7 shrink-0 place-items-center rounded-lg bg-zinc-950 text-white dark:bg-white dark:text-zinc-950">
<SparkIcon />
</span>
<p className="min-w-0 flex-1 truncate text-sm text-zinc-900 dark:text-zinc-100">{prompt}</p>
<span className="hidden shrink-0 font-mono text-[11px] text-zinc-500 sm:block">4 outputs · 16:9</span>
</div>
<SyncGrid columns={2} duration={12}>
{outputs.map((output) => (
<SyncGridItem key={output.model} label={output.model} src={video(output.clip)} poster={poster(output.clip)}>
<div className="absolute top-9 left-2.5 flex gap-1">
<Stat>{output.time}</Stat>
<Stat>{output.cost}</Stat>
</div>
</SyncGridItem>
))}
</SyncGrid>
</div>
);
}
function Stat({ children }: { children: React.ReactNode }) {
return (
<span className="rounded-full bg-black/45 px-1.5 py-0.5 font-mono text-[10px] text-white/90 tabular-nums backdrop-blur-md">
{children}
</span>
);
}
function SparkIcon() {
return (
<svg viewBox="0 0 16 16" aria-hidden className="size-3.5 fill-current">
<path d="M8 1.5c.3 2.9 1.6 4.2 4.5 4.5-2.9.3-4.2 1.6-4.5 4.5-.3-2.9-1.6-4.2-4.5-4.5 2.9-.3 4.2-1.6 4.5-4.5ZM12.5 10c.15 1.4.75 2 2 2.1-1.25.15-1.85.75-2 2.15-.15-1.4-.75-2-2.1-2.15 1.35-.1 1.95-.7 2.1-2.1Z" />
</svg>
);
}
Live preview, examples and props: https://keyframeui.com/components/sync-grid#sync-grid-models-demo



























