Direct fetching from a.basemaps.cartocdn.com was returning
stripped/missing CORS headers in the user's browser, blocking
the img.src load. Even with cache-busters the failure persisted.
Solution: local nginx proxy at /carto/ that forwards to the
upstream and always adds Access-Control-Allow-Origin: *.
Key detail: the 'resolver' directive is required inside the
proxy_pass location block so nginx can resolve the upstream
hostname. Without it, the location block silently fails (the
'/' location falls through to try_files ... =404, and the
~*\.(png|jpg)$ regex also matches and silently fails for GETs).
Also added 'location ^~ /carto/' to give prefix matching strict
priority over the .png regex match that was stealing the request.
JS now uses /carto/voyager/ (relative URL through the same
origin) so CORS preflight is not even needed.