Plan the week
Lay every task on one shared board and see at a glance who is on what.
Slides that share one frame and change by slide, fade, scale, flip, stack or depth, with swipes, dots and an autoplay timer that waits while you read.
Background Studio: tune it below, then copy the code
Your system asks for reduced motion: the demo shows its final state and nothing moves.
Lay every task on one shared board and see at a glance who is on what.
Draw flows and screens right beside the notes that explain them.
Every change lands with its review, its tests and a note on why.
Release when it is ready, roll back in one step if it is not.
Plain numbers on what people use, with nothing tracked behind their backs.
Lay every task on one shared board and see at a glance who is on what.
Draw flows and screens right beside the notes that explain them.
Every change lands with its review, its tests and a note on why.
Release when it is ready, roll back in one step if it is not.
Plain numbers on what people use, with nothing tracked behind their backs.
It follows the controls above: change an option and the code changes with it.
<link rel="stylesheet" href="/axi0/motion/motion.css?v=6">
<script src="/axi0/motion/motion.js?v=10" defer></script>
<div data-motion="carousel" aria-label="Product tour">
<article><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="17" rx="3"/><path d="M8 2v4M16 2v4M3 10h18"/></svg><h3>Plan the week</h3><p>Lay every task on one shared board and see at a glance who is on what.</p></article>
<article><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20l4-1 11-11-3-3L5 16z"/><path d="M14 6l3 3"/></svg><h3>Sketch it out</h3><p>Draw flows and screens right beside the notes that explain them.</p></article>
<article><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 7l-5 5 5 5M16 7l5 5-5 5M13 4l-2 16"/></svg><h3>Build in the open</h3><p>Every change lands with its review, its tests and a note on why.</p></article>
<article><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 15c-1.5 1.5-2 5-2 5s3.5-.5 5-2M9 15l-3-3c1-4 5-9 13-9 0 8-5 12-9 13z"/><circle cx="15" cy="9" r="1.6"/></svg><h3>Ship with care</h3><p>Release when it is ready, roll back in one step if it is not.</p></article>
<article><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 20h18M6 16l4-5 3 3 5-7"/><path d="M15 7h3v3"/></svg><h3>Watch it grow</h3><p>Plain numbers on what people use, with nothing tracked behind their backs.</p></article>
</div>
import { Carousel } from "./motion/react/Carousel";
<Carousel>Your content</Carousel>
<script setup lang="ts">
import Carousel from "./motion/vue/Carousel.vue";
</script>
<template>
<Carousel>Your content</Carousel>
</template>
const el = document.querySelector("#title");
el.dataset.motion = "carousel";
The wrappers: Carousel.tsx (React, TypeScript) and Carousel.vue (Vue). Both render the same attributes as the HTML; the loader does the rest.
| Attribute | Default | What it does |
|---|---|---|
data-motion-transition | slide | how one slide gives way to the next |
data-motion-autoplay | 5000 | time on each slide; 0 turns the timer off |
data-motion-loop | true | go round from the last slide to the first |
data-motion-label | Carousel | the name read out when the element has no aria-label |
- The element becomes a region with aria-roledescription="carousel" and a label; each slide is a tab panel announced as "slide", "2 of 5". - The dots are a tab list: Tab reaches the chosen dot, Left and Right arrows (Home and End) pick a slide. Previous and Next are plain buttons. - With a timer, a Stop/Start button comes first in the tab order. The timer pauses while the pointer rests on the carousel and stops for good when focus moves inside, until the Start button is pressed. Slides out of view are inert, so focus never lands on a hidden link. - The slide area is a polite live region while the timer is off, so a screen reader reads each new slide; while it runs, it stays quiet. - Reduced motion turns the timer off and changes slides with no movement. Reduced motion shows every state at once, with no movement, and stops anything that would move on its own. Frame loops and CSS animations pause off screen and in hidden tabs. Only transform, opacity and paint animate, so nothing around it moves.
carousel.js is 3.0 KB gzip, with components-kit.js 3.9 KB it needs. A page loads the loader (2.7 KB) and core.js (1.4 KB) once, whatever it uses.