diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7b68daf
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 zink
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..12694e3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,139 @@
+# Animated Background
+
+An animated desktop background that runs in a browser. Features:
+
+- Time-of-day simulation with realistic color gradients driven by the
+ actual sun position (computed from latitude/longitude via SunCalc).
+- Night brightness coupled to the moon phase (new moon = minimum, full
+ moon = maximum), with a configurable minimum so the night is never
+ pitch-black.
+- Live weather widget (Open-Meteo) showing current conditions and a
+ 4-day forecast (morning, evening, full) at every timestamp.
+- Configurable units (metric °C+km/h or imperial °F+mph).
+- Configurable language (with English as the base; translations for
+ German, Italian, Spanish, French, and Russian).
+- Configurable color theme (Ash, Gruvbox, Nord) - drop a new
+ `*.css` file in the same directory and add an entry to `window.THEMES`
+ to add a new theme.
+- Customisable location: set `CONFIG.location.lat/lon`, or let the
+ browser's geolocation API pick one up automatically (falls back to
+ London).
+- Optional custom location label (`CONFIG.location.label`) that
+ overrides the OpenStreetMap reverse-geocoding lookup.
+- Configurable digital clock format string using ISO-8601-ish tokens
+ (YYYY, MM, DD, HH, mm, ss, DDD, DDDD, MMM, MMMM, a, A, sss, T, escape
+ sequences \n \t \\, and full weekday/month names via the i18n dict).
+- Configurable debug panel (toggle collapse/expand with theme, units,
+ and language dropdowns that apply at runtime).
+
+## Run with Docker
+
+```sh
+docker compose up --build
+```
+
+Then open .
+
+## Run locally
+
+The app is a single HTML page. With any static file server:
+
+```sh
+python3 -m http.server 58881
+```
+
+Open .
+
+## Configuration
+
+Edit `config.js` and reload the page:
+
+```javascript
+window.CONFIG = {
+ debug: 0, // 0 = hide debug panel, 1 = show
+ theme: 'ash', // 'ash' | 'gruvbox' | 'nord'
+ units: 'metric', // 'metric' | 'imperial'
+ language: 'de', // 'en' | 'de' | 'it' | 'es' | 'fr' | 'ru'
+ timeFormat: 'DD. MMMM, YYYY \u2012 HH:mm:SS',
+ location: {
+ lat: 48.5667, // latitude, -90 to +90, north positive
+ lon: 13.4319, // longitude, -180 to +180, east positive
+ label: '' // optional custom place name;
+ // if set, skips reverse-geocoding
+ }
+};
+```
+
+## Adding a new language
+
+Edit `i18n.js` and add entries for each existing key under your new
+language code, e.g.:
+
+```javascript
+window.TRANSLATIONS['Sunrise']['xx'] = 'MyTranslation';
+```
+
+## Adding a new theme
+
+Drop a new `*.css` file next to the others and add an entry to
+`window.THEMES`:
+
+```javascript
+window.THEMES['mytheme'] = 'mytheme.css';
+```
+
+## Time format tokens
+
+```
+YYYY 4-digit year (2026)
+MM month 01-12 (10)
+DD day 01-31 (07)
+HH hour 00-23 (24h) (14)
+mm minute 00-59 (35) lowercase!
+ss second 00-59 (22) lowercase!
+sss millisecond 000-999 (456)
+a am/pm (lowercase) (pm)
+A AM/PM (uppercase) (PM)
+T literal 'T'
+
+MMM month short name (Oct, Okt, Ott, ...)
+MMMM month full name (October, Oktober, ...)
+DDD weekday short name (Mon, Mo, Lu, ...)
+DDDD weekday full name (Monday, Montag, ...)
+
+\n newline
+\t tab
+\\ literal backslash
+```
+
+## Files
+
+```
+.
+├── background.html the page (formerly index.html)
+├── config.js user-facing configuration
+├── i18n.js translation strings (en/de/it/es/fr/ru)
+├── ash.css default color theme
+├── gruvbox.css alternative color theme
+├── nord.css alternative color theme
+├── noise.png background noise texture for Vanta
+├── vendor/ vendored third-party JS (no network needed)
+│ ├── three.min.js MIT (three.js)
+│ ├── suncalc.js ISC (SunCalc by mourner)
+│ ├── vanta.clouds.min.js MIT (Vanta.js Clouds)
+│ ├── vanta.clouds2.min.js MIT (Vanta.js Clouds2)
+│ └── LICENSE per-library license attributions
+├── default.conf nginx server config (port 58881)
+├── Dockerfile builds nginx:alpine image
+└── docker-compose.yml one-service Compose file
+```
+
+## Licenses
+
+- **Background application code**: MIT
+- **three.js** (vendored): MIT -
+- **SunCalc** (vendored): ISC -
+- **Vanta.js** (vendored): MIT -
+- **Open-Meteo** (weather API): CC BY 4.0 -
+- **OpenStreetMap Nominatim** (reverse geocoding): ODbL -
+
\ No newline at end of file