Resolves the last of the parallel work. Two conflicts worth recording,
because both were semantic rather than textual:
`render_for_export` gained a colour space on master while the batch branch
was rewriting the single-image export path around it. Kept both: the batch
request supersedes the synchronous path, and the space still has to be chosen
at render time because the conversion happens in the shader before the clip to
0..1. `render_open_frame` takes it as an argument rather than reaching for a
controller it does not hold.
The map-wait moved into `readback::await_mapping` on one branch while another
was editing the constant it used, so `READBACK_POLL_LIMIT` survived the merge
with no callers. Removed rather than left for clippy to find later.
1164 tests pass, clippy clean, fmt clean. Traceability 53.0% -> 54.3%.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>