## Ink Field (S—003)

A living flow-field background of ink strands that drift, fade and curl around the pointer.

- URL: https://sundaeui.dev/components/ink-field
- Category: Backgrounds & effects · Art direction: Organic
- Access: Free (no account needed)
- Stack: React 18+, TypeScript, plain CSS; dependencies: none
- Install: `npx shadcn@latest add https://sundaeui.dev/r/ink-field.json`
- Tags: interactive, canvas, generative, animated, background, react

Hundreds of short strokes follow a slowly shifting Perlin noise field across a paper-coloured canvas. Each frame fades the last one a little toward the paper, so the strands leave soft trails that read like ink spreading through water.
Move the pointer and the strands nearby bend into a gentle vortex. When the pointer leaves, they drift back into the field.
It is a single canvas with no dependencies. It is DPR-aware, sizes itself to its container, pauses when offscreen or when the tab is hidden, and renders a settled still frame for visitors who prefer reduced motion.

### Usage

```tsx
import { InkField } from '@/components/sundae/ink-field'

export function Hero() {
  return (
    <InkField className="min-h-[80vh]" inks={['#1f2a37', '#c2563a']} paper="#f4efe6">
      <div className="mx-auto max-w-3xl px-6 py-32">
        <h1>Slow water, carrying ink.</h1>
      </div>
    </InkField>
  )
}
```

### Props

- `inks` (`string[]`, default `['#1f2a37', '#3d4f63', '#c2563a']`): Stroke colours. The first is the main ink (about 70% of strands), and later colours are rarer accents.
- `paper` (`string`, default `'#f4efe6'`): Background colour that strokes fade into. 'transparent' draws without trails.
- `density` (`number`, default `1.4`): Strand density relative to canvas area (capped at 1,600).
- `speed` (`number`, default `1`): Global speed multiplier.
- `fade` (`number`, default `0.022`): Per-frame fade toward the paper, from 0 to 1. Lower values leave longer trails.
- `interactive` (`boolean`, default `true`): Strands swirl around the pointer.
- `children` (`ReactNode`): Content rendered above the canvas.

### Accessibility

- The canvas is aria-hidden. It is decoration only, and content lives in normal DOM above it.
- With prefers-reduced-motion, it renders a single settled frame and never starts the animation loop.
- Check text contrast against your chosen paper and ink. The defaults give dark text roughly 12:1 against the paper.
