Sequential offsetting of animations across items.
100ms between each item · forward order
<div class="mot-stg-stage" data-direction="forward">
<span class="mot-stg-chip mot-stg-chip--1" style="background:#BFD9F2;"></span>
<span class="mot-stg-chip mot-stg-chip--2" style="background:#BFD9F2;"></span>
<span class="mot-stg-chip mot-stg-chip--3" style="background:#BFD9F2;"></span>
<span class="mot-stg-chip mot-stg-chip--4" style="background:#BFD9F2;"></span>
<span class="mot-stg-chip mot-stg-chip--5" style="background:#BFD9F2;"></span>
<p class="mot-stg-caption">100ms between each item · forward order</p>
</div>
<style>
.mot-stg-stage { width: 100%; max-width: 320px; padding: 16px; background: #FAF7F2; border: 1px solid #24143022; border-radius: 12px; display: flex; gap: 8px; font: 12px system-ui, sans-serif; color: #241430aa; flex-wrap: wrap; }
.mot-stg-chip { width: 32px; height: 32px; border-radius: 8px; }
.mot-stg-caption { flex-basis: 100%; margin: 8px 0 0; }
@media (prefers-reduced-motion: no-preference) {
.mot-stg-chip { animation: mot-stg-in 450ms ease-out infinite; }
[data-direction="forward"] .mot-stg-chip--1 { animation-delay: calc(100ms * 0); }
[data-direction="forward"] .mot-stg-chip--2 { animation-delay: calc(100ms * 1); }
[data-direction="forward"] .mot-stg-chip--3 { animation-delay: calc(100ms * 2); }
[data-direction="forward"] .mot-stg-chip--4 { animation-delay: calc(100ms * 3); }
[data-direction="forward"] .mot-stg-chip--5 { animation-delay: calc(100ms * 4); }
[data-direction="reverse"] .mot-stg-chip--1 { animation-delay: calc(100ms * 4); }
[data-direction="reverse"] .mot-stg-chip--2 { animation-delay: calc(100ms * 3); }
[data-direction="reverse"] .mot-stg-chip--3 { animation-delay: calc(100ms * 2); }
[data-direction="reverse"] .mot-stg-chip--4 { animation-delay: calc(100ms * 1); }
[data-direction="reverse"] .mot-stg-chip--5 { animation-delay: calc(100ms * 0); }
@keyframes mot-stg-in { 0%,20% { opacity: .25; transform: translateY(6px); } 40%,100% { opacity: 1; transform: translateY(0); } }
}
</style><div class="w-full max-w-[320px] p-4 bg-[#FAF7F2] border border-[#24143022] rounded-xl flex gap-2 flex-wrap font-sans text-xs text-[#241430]/70" data-direction="forward">
<span class="tw-stg-chip tw-stg-1 w-8 h-8 rounded-lg" style="background:#BFD9F2;"></span>
<span class="tw-stg-chip tw-stg-2 w-8 h-8 rounded-lg" style="background:#BFD9F2;"></span>
<span class="tw-stg-chip tw-stg-3 w-8 h-8 rounded-lg" style="background:#BFD9F2;"></span>
<span class="tw-stg-chip tw-stg-4 w-8 h-8 rounded-lg" style="background:#BFD9F2;"></span>
<span class="tw-stg-chip tw-stg-5 w-8 h-8 rounded-lg" style="background:#BFD9F2;"></span>
<p class="basis-full mt-2">100ms between each item · forward order</p>
</div>
<style>
@media (prefers-reduced-motion: no-preference) {
.tw-stg-chip { animation: mot-stg-tw-in 450ms ease-out infinite; }
[data-direction="forward"] .tw-stg-1 { animation-delay: calc(100ms * 0); }
[data-direction="forward"] .tw-stg-2 { animation-delay: calc(100ms * 1); }
[data-direction="forward"] .tw-stg-3 { animation-delay: calc(100ms * 2); }
[data-direction="forward"] .tw-stg-4 { animation-delay: calc(100ms * 3); }
[data-direction="forward"] .tw-stg-5 { animation-delay: calc(100ms * 4); }
[data-direction="reverse"] .tw-stg-1 { animation-delay: calc(100ms * 4); }
[data-direction="reverse"] .tw-stg-2 { animation-delay: calc(100ms * 3); }
[data-direction="reverse"] .tw-stg-3 { animation-delay: calc(100ms * 2); }
[data-direction="reverse"] .tw-stg-4 { animation-delay: calc(100ms * 1); }
[data-direction="reverse"] .tw-stg-5 { animation-delay: calc(100ms * 0); }
@keyframes mot-stg-tw-in { 0%,20% { opacity: .25; transform: translateY(6px); } 40%,100% { opacity: 1; transform: translateY(0); } }
}
</style>export function Stagger({
interval = 100,
duration = 450,
direction = "forward",
accent = "#BFD9F2",
}) {
const order = direction === "forward" ? [0, 1, 2, 3, 4] : [4, 3, 2, 1, 0];
return (
<div style={{ width: "100%", maxWidth: 320, padding: 16, background: "#FAF7F2", border: "1px solid #24143022", borderRadius: 12, display: "flex", gap: 8, flexWrap: "wrap", fontFamily: "system-ui, sans-serif", fontSize: 12, color: "#241430aa" }}>
{order.map((mult, i) => (
<span key={i} className="chip" style={{ width: 32, height: 32, borderRadius: 8, background: accent, "--stg-delay": `${mult * interval}ms` }} />
))}
<p style={{ flexBasis: "100%", margin: "8px 0 0" }}>{interval}ms between each item · {direction} order</p>
<style>{`
@media (prefers-reduced-motion: no-preference) {
.chip { animation: mot-stg-in ${duration}ms ease-out infinite; animation-delay: var(--stg-delay); }
@keyframes mot-stg-in { 0%,20% { opacity: .25; transform: translateY(6px); } 40%,100% { opacity: 1; transform: translateY(0); } }
}
`}</style>
</div>
);
}