# <motion-liquid>

Liquid-distorted text via SVG turbulence + displacement-map. Looped
fractal-noise warps the text into a flowing, organic shape.

The text is rendered as SVG `<text>` and the filter is applied to that SVG
content directly — not to an HTML element via CSS `filter: url(#…)`. On
WebKit (iOS Safari and every iOS browser) a `url()` filter applied to an
HTML element is cached as a composited layer that only re-rasterizes when a
repaint is forced (e.g. scrolling), so the distortion appears frozen except
while scrolling. SVG content re-renders its own filtered output on every
SMIL tick, which animates reliably across platforms.

Text can be set with the `text` attribute or as child text. Child text
doubles as a pre-upgrade fallback: the browser shows it before the
element is defined, so the page never paints an empty gap.

**Use it for:** one short word or title with a slow, flowing distortion,
such as an accent in a hero section.

**Avoid it for:** long text, and text that people need to read quickly. The
text is one line of SVG text and does not wrap. For letters that ride a
wave, use `motion-curve`.

**Accessibility:** the SVG has `role="img"` and an `aria-label` with the
text, so screen readers announce it as an image with that name. If it is a
heading, put it inside a heading element. The distortion never stops on
its own, and `pause-on-hover` works with a mouse only. Keep `intensity` low
enough that the text stays readable.

**Reduced motion:** the distortion filter is not applied. The text shows
plain and still.

**Common mistakes:** setting `duration="0"` to freeze the shape. This also
turns the filter off, so the text shows with no distortion. Changing the
child text after the element is on the page; the child text is read once,
so set the `text` property instead.

Docs: https://www.motion-components.dev/docs/text/motion-liquid/

## Install

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

Or without a build step:

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

## Example

```html
<motion-liquid intensity="14" duration="3.6">LIQUID</motion-liquid>
```

## Attributes

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `text` | `string \| undefined` |  | Text to distort. Falls back to the element's child text when unset. |
| `intensity` | `number` | `10` | Maximum displacement amount in pixels (peak of the noise pulse). |
| `duration` | `number` | `4.5` | Seconds per distortion cycle. Lower is faster, `0` holds the text still. |
| `pause-on-hover` | `boolean` | `false` | When `true`, pause the distortion loop while the cursor is over the element. |

## 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 |
| --- | --- |
| `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. |
