Step 3 of the gui/app.py + gui/preview.py structural refactor. Pure move: the zoom/pan image viewer class is now in its own module under media/. preview.py grows another re-export shim line so ImagePreview and FullscreenPreview (both still in preview.py) can keep constructing ImageViewer instances unchanged. Shim removed in commit 14.