<!-- source-hash: ec93c3a6544d7f572c8219bc65ceaf67 -->
Smooth-scroll utility that positions an element at the top of the viewport with support for sticky header offsets and pre-computed layout-shift adjustments.

## Key Components

### `ScrollElementIntoViewOptions`

| Option | Type | Default | Description |
|---|---|---|---|
| `headerOffset` | `number` | `0` | Pixels to subtract for sticky chrome (e.g., `96` for `scroll-mt-24`) |
| `behavior` | `ScrollBehavior` | `'smooth'` | `'smooth'` for animated scrolls, `'instant'` for deep-link jumps |
| `adjustTargetY` | `(raw: number) => number` | — | Callback to correct the pixel target before animation starts |

### `scrollElementIntoView(target, options?)`

Computes a fixed pixel target via `getBoundingClientRect().top + scrollY - headerOffset`, then calls `window.scrollTo()` directly. This avoids the jitter caused by `element.scrollIntoView()`, which re-targets continuously during layout shifts. Handles `null`/`undefined` refs as a no-op and short-circuits in SSR environments.

## Usage Example

```typescript
import { scrollElementIntoView } from './scroll-into-view'

// Basic — scroll a ref to top, accounting for a 96px sticky header
scrollElementIntoView(cardRef.current, { headerOffset: 96 })

// Instant jump on deep-link land
scrollElementIntoView(anchorRef.current, {
  headerOffset: 96,
  behavior: 'instant',
})

// Pre-computed layout-shift adjustment (e.g. HelpCenterCard accordion)
// Row A (above target) collapses simultaneously — shift target up by A's height
scrollElementIntoView(rowBRef.current, {
  headerOffset: 96,
  adjustTargetY: (raw) => raw - getAboveDrawerHeight(),
})
```

> **Why not `element.scrollIntoView()`?** That API re-targets continuously as the page reflows during the animation, causing visible jitter when sibling content is also moving. Pre-computing a fixed pixel value lets the browser commit to a clean, uninterrupted animation.