<!-- source-hash: 89208f0119005a51561aa80d8594f307 -->
Renders a multi-step onboarding walkthrough UI that syncs external completion status with local storage state, prevents race conditions via refs, and displays dismissible step cards.

## Key Components

- **`OnboardingWalkthrough`** — Main exported component that orchestrates step rendering, completion tracking, and dismissal
- **`OnboardingWalkthroughProps`** — Interface defining the component's props
- **`useOnboardingState`** — Hook managing persistent onboarding state (completed/skipped/dismissed) via `localStorage`
- **`OnboardingStepCard`** — Child component rendering individual step cards
- **Race condition guards** — Three refs (`hasAutoMarkedRef`, `autoMarkingInProgressRef`, `actionInProgressRef`) prevent duplicate or concurrent state mutations

## Usage Example

```typescript
import { OnboardingWalkthrough } from './onboarding-walkthrough'
import type { OnboardingStepConfig } from '../../../hooks/ui/use-onboarding-state'

const steps: OnboardingStepConfig[] = [
  {
    id: 'knowledge-base',
    title: 'Set up Knowledge Base',
    description: 'Upload your documentation.',
    onAction: async () => { /* open modal or navigate */ },
  },
  {
    id: 'connect-psa',
    title: 'Connect your PSA',
    description: 'Integrate your ticketing system.',
    onAction: async () => { /* trigger integration flow */ },
    checkComplete: async () => await checkPsaConnected(),
  },
]

<OnboardingWalkthrough
  steps={steps}
  storageKey="my-app-onboarding"
  completionStatus={{ 'connect-psa': true }}
  isLoadingCompletion={false}
  onDismiss={() => console.log('dismissed')}
/>
```

## Behavior Notes

- **Auto-sync**: When `completionStatus` prop changes, steps flagged `true` are automatically marked complete via `markMultipleComplete`, guarded by a JSON-stringified status key to avoid re-processing identical data.
- **Action deduplication**: `actionInProgressRef` tracks in-flight step actions per `step.id`, silently skipping duplicate triggers.
- **All hooks called unconditionally** — the `state.dismissed` early return happens *after* all hooks and refs are initialized, satisfying React's Rules of Hooks.