# <motion-blur>

Scroll-driven blur reveal. Maps the element's scroll progress through the
viewport to opacity, blur, and Y-translation. Direction controls whether the
blur happens on entry, exit, or both.

**Use it for:** hero images, quotes and section headings that should come
into focus, or fade away, as the page scrolls.

**Avoid it for:** an entrance that should play on its own once the content
is in view; use `motion-blur-in`, which plays over a fixed time. Avoid
`direction="both"` for text people need to read, because the text is fully
clear only when it is in the middle of the screen.

**Accessibility:** the content stays in the page while it is faded or
blurred, so screen readers can read it at any scroll position. Only
opacity, filter and transform change, so the layout does not shift.

**Reduced motion:** the content shows fully visible, sharp and in place at
once, for every `direction`, and it does not change as the page scrolls.
`motion-start` and `motion-finish` still fire, and `cancel()` keeps the
content visible.

**Common mistakes:** placing it near the end of the page, or on a page too
short to scroll. With `direction="in"`, the content is fully clear only
when its center reaches the middle of the screen, so it can stay faded and
blurred. Use `motion-blur-in` there.

Docs: https://www.motion-components.dev/docs/reveal/motion-blur/

## Install

```js
import 'motion-components/motion-blur'
```

Or without a build step:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/motion-components@1/dist/motion-blur.js/+esm"></script>
```

## Example

```html
<motion-blur intensity="14" y="20" direction="in">
  <img src="hero.jpg" alt="" />
</motion-blur>
```

## Attributes

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `intensity` | `number` | `10` | Maximum blur amount in pixels at the unfocused extreme. |
| `y` | `number` | `12` | Vertical translation in pixels at the unfocused extreme. |
| `once` | `boolean` | `true` | When `true` (and `direction="in"`), latch focused state on first reveal. Set `once="false"` to turn it off. |
| `direction` | `'in' \| 'out' \| 'both'` | `'in'` | `'in'` blurs on entry, `'out'` blurs on exit, `'both'` blur-focus-blur. |

## Properties

| Property | Type | Description |
| --- | --- | --- |
| `playState` | `'idle' \| 'running' \| 'paused' \| 'finished'` | Current state: `'idle'`, `'running'`, `'paused'` or `'finished'`. |
| `finished` | `Promise<void>` | Resolves when the current run settles. A new run replaces the promise. |

## Methods

| Method | Description |
| --- | --- |
| `replay()` | Resets the latch and re-binds the scroll handler. |
| `play()` | Starts the animation, or resumes it when paused. Resolves once the run settles. Under `prefers-reduced-motion: reduce` the final state is applied immediately without animating. |
| `pause()` | Holds the animation at its current position. No-op unless running. |
| `finish()` | Jumps to the final state and settles. Fires `motion-finish`. |
| `cancel()` | Reverts to the initial state and returns to idle. Fires `motion-cancel`. |

## Events

The `motion-*` events bubble and are composed.

| Event | Description |
| --- | --- |
| `motion-start` | When a run starts. |
| `motion-finish` | When a run finishes, or `finish()` jumps to the end. |
| `motion-cancel` | When `cancel()` stops a run and resets it. |

## Slots

| Slot | Description |
| --- | --- |
| (default) | The content to blur on scroll. |
