Round to the nearest increment when snap is on, otherwise pass the angle through.
Callers rotating a SINGLE thing pass its absolute angle, so the result is always a clean multiple however the drag started. Callers rotating a GROUP pass the delta instead: the members start at different angles, so there is no shared absolute to snap, and snapping the delta is what keeps them rotating and orbiting as one.
Shared rotation behaviour for the drag handlers.
Holding shift while rotating snaps to whole increments. Kept in one place because three handlers need it — element, multi-element and image content — and they would otherwise drift apart.
Mirrors kRotationSnapDegrees in typograph-canvas (mousemanagers.ts), which does the same for the viewer's image-content rotation. Duplicated rather than imported: canvas does not export it, and a cross-repo pin for one number is not worth the coupling. Change both together.