# Motion · MIAN

A small motion system: three durations, three curves, the noodle’s own entrance for anything you add, staggered lists, press and lift feedback, drawn lines, counted numbers and cross-faded changes. All of it stops under reduced motion.

- Id: `motion` · Category: Layout & utilities · Needs mian.js: yes · License: MIAN License (free to use)
- Docs: https://mian.ro/components/motion
- Use for: animation, entrance animation, staggered list, hover lift, count up number, page transition, micro interactions.
- Avoid: Do not fade sections in on scroll and do not animate everything. Motion explains a change: something arrived, moved or was pressed.

Use only the classes below and copy the examples' structure and ARIA; change the words. Check your markup at https://mian.ro/api/v1/validate.

## Install

```html
<link rel="stylesheet" href="https://mian.ro/dist/mian.css">
<script src="https://mian.ro/dist/mian.js" defer></script>
```

## Classes

- `--mn-dur-fast · --mn-dur · --mn-dur-slow`: 120, 200 and 360 ms: feedback, state change, layout change.
- `--mn-ease-out · --mn-ease-in-out · --mn-ease-spring`: Arriving, moving across the screen, and a soft overshoot for playful noodles.
- `mn-enter`: Plays the current noodle’s entrance once, when the element is added.
- `mn-stagger`: On a container: its first eight children enter 45 ms apart (--mn-stagger-step).
- `mn-press`: Shrinks to 97% while pressed.
- `mn-lift`: Rises 2px with a shadow on hover, for whole-card links.
- `mn-draw`: On an SVG path with pathLength="1": draws the line in.
- `data-mn-count`: Counts up to the element’s own number once, when first seen.
- `Mian.transition(fn)`: Runs a DOM change inside a view transition, so it cross-fades. Mian.setNoodle and Mian.setMode use it.

## Accessibility

- Everything here is disabled by prefers-reduced-motion: reduce; nothing depends on an animation finishing.
- Animate to explain a change (something arrived, moved, was pressed), not to decorate. Do not fade sections in as the reader scrolls.
- Keep motion under 400 ms and never loop it near text.
- Counted numbers keep their final value in the DOM, so assistive technology never reads a partial count.

## Examples

### Entrance and stagger

Press the button: the list is re-inserted and enters in this noodle’s own style.

```html
<div class="mn-stack" style="width:min(100%,22rem)">
  <ul class="mn-list mn-stagger" id="motion-list"><li>Invoice sent</li><li>Reminder scheduled</li><li>Payment received</li><li>Receipt emailed</li></ul>
  <button class="mn-btn mn-btn-outline mn-press" type="button" onclick="const l=document.getElementById('motion-list');const c=l.cloneNode(true);l.replaceWith(c)">Play again</button>
</div>
```

### Press, lift and count

```html
<div class="mn-row" style="--mn-gap:1rem">
  <a class="mn-card mn-lift" href="#" style="display:block;padding:1rem 1.25rem;text-decoration:none;color:inherit"><span class="mn-muted" style="font-size:.8125rem">Orders today</span><br><strong style="font-size:1.5rem" data-mn-count>1,284</strong></a>
  <button class="mn-btn mn-press" type="button">Press me</button>
</div>
```

## Source

Already inside mian.css and mian.js; you do not need it to use the component. To vendor or customise: https://mian.ro/api/v1/components/motion/source
