When the dragged profile came from an earlier index than the drop target,
`splice(sourceIndex, 1)` shifted every subsequent element left by one,
making the raw `targetIndex` point one slot past the original drop target.
The moved item landed AFTER the target card instead of AT it.
Fix: extract `reorderProfiles()` pure helper that uses
`targetIndex - 1` when `sourceIndex < targetIndex`, and delegate
the drop handler to it.
Adds 10 regression tests covering forward drags (the bug case),
backward drags (unchanged), adjacent-element edge cases, and
immutability of the input array.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>