diff --git a/README.md b/README.md
index 4c95192..680998d 100644
--- a/README.md
+++ b/README.md
@@ -1,43 +1,51 @@
# Animated Background
-A browser-based animated desktop background: a WebGL flight scene over
-real terrain, driven by the real sun, moon, stars, and live weather.
+A browser-based animated desktop background: a WebGL flight scene over real
+terrain, driven by the real sun, moon, stars and live weather. Designed to be
+dropped into an iframe or kiosk browser and left running.
## Features
-- **WebGL flight scene** (`vendor/clouds3d.js`): raymarched cloud deck,
- 3D terrain mesh from real elevation data (Copernicus DEM), satellite
- or street basemap, figure-eight flight path around the configured
- location with a vertical bob between **15 and 35 km** flight altitude.
-- **Real day/night cycle** driven by the actual sun and moon position
- (SunCalc) for the configured latitude/longitude — or an accelerated
- 24 h simulation (`CONFIG.day`) for wall-decoration purposes.
-- **Realistic night sky**: ~8700 stars from the Yale Bright Star
- Catalogue (crisp GL points, size by magnitude, colour by temperature),
- rotated with the sidereal rate for the site's latitude, plus a Milky
- Way band and a phase-correct moon.
-- **Aircraft**: low-poly jets (CC0 model) cruising the region on curved
- routes between real airfields, rolling a random destination at every
- take-off - sun-lit silhouettes with contrails by day, strobing position
- lights by night (all parameters in `CONFIG.flights`).
-- **Night lights**: animated car lights along the real motorway/road
- network and pale-yellow settlement lights (OSM place nodes; bigger
- towns get more and brighter dots), optionally a NASA VIIRS night-lights
- satellite overlay. All faded in from dusk, density shaped by a
- rush-hour curve.
-- **Live weather** (Open-Meteo): current conditions + 4-day forecast
- widget; the weather code selects the scene's cloud density and colour
- mood (sunny / cloudy / stormy / night).
-- **Fully cached, offline-capable**: basemap tiles, elevation grid,
- Overpass road/place data, star catalogue and the last weather payload
- live permanently in IndexedDB. Once warm, the scene renders fully offline, and a 15-minute cycle transparently retries anything that previously failed. Merged road chains and the decoded settlement list are cached as well and only recomputed when an Overpass cell is actually re-fetched.tiles.expireDays`) can refresh
- basemap tiles periodically.
-- **Location-aware**: set `CONFIG.location.lat/lon`; everything
- (flight anchor, terrain tiles, sun/moon, weather, star rotation) is
- computed from it. If the location is omitted, browser geolocation is
- tried, falling back to the built-in default (London).
-- Units (°C/°F), six UI languages, CSS-swappable colour themes
- (Ash/Gruvbox/Nord), configurable clock format, optional debug panel.
+- **WebGL flight scene** (`vendor/clouds3d.js`): a 3D terrain mesh built from
+ real elevation data (Copernicus DEM), a raymarched volumetric cloud deck,
+ and a figure-eight flight path around the configured location with a
+ vertical bob inside the 15-35 km flight band.
+- **One physical light model** shared by sky, clouds, contrails, aircraft and
+ ground: direct beam through a Kasten-Young air mass with Rayleigh, ozone and
+ aerosol extinction, diffuse skylight, moonlight, a starlight floor and aerial
+ perspective. Sun and moon come from the real positions (SunCalc) for
+ `CONFIG.location`, or from an accelerated 24 h simulation (`CONFIG.day`).
+- **Theme-tinted lighting**: each theme may pull the physical colours toward
+ its own palette and set its own day/night exposure, without replacing the
+ physics (`window.THEMES[...].lighting`).
+- **Shadows**: moving cloud shadows sampled from the same cloud field the sky
+ renders, plus terrain self-shadowing over the DEM height field.
+- **Realistic night sky**: ~8700 stars from the Yale Bright Star Catalogue
+ (points sized by magnitude, coloured by temperature), rotated at the sidereal
+ rate for the site's latitude, a Milky Way band and a phase-correct moon.
+- **Aircraft**: low-poly jets (CC0 model) on curved routes between real
+ airfields, with a destination rolled at every take-off, sun-lit silhouettes
+ and contrails by day, strobing position lights by night.
+- **Night lights**: vehicle lights moving along the real road network (Overpass)
+ with correct driving side per country, and settlement lights from OSM place
+ nodes (bigger towns get more and brighter dots). Both fade in light by light
+ across twilight instead of switching as one block.
+- **Live weather** (Open-Meteo): current conditions plus a 4-day forecast
+ widget; the weather code selects the cloud coverage and the colour mood.
+- **Fully cached, offline-capable**: basemap tiles, the elevation grid, Overpass
+ road/place cells, the merged road chains and the decoded settlement list live
+ permanently in IndexedDB; the star catalogue is inlined. Once warm, the scene
+ renders fully offline (only weather is fetched live), and a 15-minute cycle
+ transparently retries anything that previously failed.
+- **Pixel-art rendering option**: `CONFIG.renderScale` renders the 3D scene at
+ a fraction of the display size and upscales it in exact integer blocks with
+ `image-rendering: pixelated`, while the DOM UI stays crisp.
+- **Location-aware**: set `CONFIG.location.lat/lon` and everything (flight
+ anchor, terrain tiles, sun/moon, weather, star rotation, traffic side) is
+ derived from it. Without a location, browser geolocation is tried, falling
+ back to the built-in default.
+- Six UI languages, CSS-swappable colour themes, configurable clock format,
+ optional debug panel.
## Run with Docker (recommended)
@@ -47,112 +55,122 @@ docker compose up --build
Then open .
-The bundled nginx config (`default.conf`) is more than a file server: it
-provides CORS proxies for the tile sources (`/esri/`, `/carto/`,
-`/terrarium/`) that the scene needs for basemap and elevation data.
-A plain static server without these proxies (e.g.
-`python3 -m http.server 58881`) will run the UI but terrain and map
-tiles will fail to load.
+The bundled nginx config (`default.conf`) is more than a file server:
+
+- CORS proxies for the basemap styles (`/esri/streets/`, `/esri/imagery/`) and
+ the elevation tiles (`/terrarium/`).
+- CORS proxies for the three Overpass mirrors (`/overpass/api/`,
+ `/overpass/coffee/`, `/overpass/mail/`) with a browser-like request, long
+ timeouts and a 30-day `proxy_cache` (`overpass-cache.conf`) that also serves
+ stale entries while a mirror is down. Public Overpass instances refuse or
+ mis-handle cross-origin POSTs, and they are flaky; the cache means a cell the
+ browser already paid for is never lost.
+- `Cache-Control: no-store` for HTML and JS, so a changed `CONFIG` takes effect
+ on reload.
+
+A plain static server without these proxies (e.g. `python3 -m http.server
+58881`) runs the UI, but terrain, basemap and road data will not load.
## Single-file build
-`build.py` bundles everything into one self-contained HTML file
-(`background-standalone.html`) — all scripts, the star catalogue and all
-theme CSS are inlined, and theme switching keeps working:
+`build.py` bundles everything into one self-contained HTML file: all scripts,
+the star catalogue and every theme stylesheet are inlined, and theme switching
+keeps working.
```sh
-python3 build.py # -> background-standalone.html (no sibling files needed)
+python3 build.py # -> background-standalone.html
+python3 build.py out.html # -> custom output path
+python3 build.py --check # build to a temp file and verify, write nothing
```
-Runtime *data* is still fetched at load (tiles, Overpass, weather): serve
-the file from the Docker image for the full experience; opened via
-`file://` or a proxy-less server it renders sky, clouds and UI with an
-"OFFLINE"-labelled ground grid instead of basemap tiles.
+`--check` fails if anything is left that would need a sibling file (an external
+`