Bunny/cross-origin downloads are fetched into a blob before saving, which
on large files or slow connections looked stuck (spinner only). Stream the
body through a counting transform and show real byte progress in a toast:
per-file percent for single downloads and file N/M + percent for bulk.
- Progress is measured from Content-Length + received bytes (not estimated).
- The blob is assembled by the browser from the stream (can be disk-backed),
so we don't accumulate chunks in the JS heap.
- Only the blob path shows a toast; same-origin (R2/S3/MinIO) and the >10 GB
fallback use the browser's native download UI.