diff --git a/CHANGELOG.md b/CHANGELOG.md
index ea6227b..dea93c5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,56 @@ This project uses calendar versioning: `YY.N-stage` (e.g. `26.0-alpha` = 2026, r
## [Unreleased]
+## [26.16-alpha] - 2026-05-10
+
+### Added
+
+- **Failed-login rate limit on `/login`.** A new in-memory
+ `LoginAttempts` store in `furtka/auth.py` blocks brute-force attempts
+ after 10 failures in 15 minutes from the same (username, IP) pair,
+ with a 15-minute lockout. Successful logins clear the counter; a
+ `systemctl restart furtka` clears any stuck lockout — fine for an
+ alpha single-user box. Tuple-keying means a flood from one source IP
+ can't lock the admin out from elsewhere; an attacker can rotate IPs
+ to keep probing forever, but each attempt still eats the PBKDF2 cost.
+ Locked attempts get a `Retry-After` header so the UI can render the
+ cooldown.
+- **Live-ISO boot USB is filtered out of the install drive picker.** On
+ bare-metal installs, `lsblk` reports the USB stick the live ISO
+ booted from as `TYPE=disk`, so it showed up in the picker alongside
+ the real install target — a user could in theory pick the USB they
+ had just booted from. `webinstaller/drives.py` now resolves
+ `/run/archiso/bootmnt` via `findmnt`, walks it up to its parent disk
+ via `lsblk -no PKNAME`, and drops that disk before scoring. On a
+ normal (non-live) box `/run/archiso/bootmnt` does not exist and the
+ picker is unchanged.
+
+### Changed
+
+- **furtka.org homepage rebuild.** Adopted the visual feel of Pascal's
+ prototype while keeping Furtka's voice, brand palette, and bilingual
+ structure: Three.js wireframe torus-knot behind the hero (color +
+ opacity tied to the existing `--accent` CSS var so light and dark
+ modes share one scene), scroll-driven camera zoom + tilt, GSAP +
+ ScrollTrigger card reveals, Lenis smooth scroll, gradient wordmark,
+ drop-shadow glow in dark mode, and a pulsing CTA pointing at
+ `/releases`. "What works today" / "What's coming next" lists moved
+ from markdown bullets into front-matter arrays and now render as
+ scroll-reveal cards. All vendor JS (Three.js r128, GSAP 3.12.2 +
+ ScrollTrigger, Lenis 1.0.33) is vendored locally under
+ `website/assets/js/vendor/`, fingerprinted with SRI, gated to the
+ homepage only, deferred so first paint isn't blocked, and
+ early-returned on `prefers-reduced-motion`.
+- **Static-asset gzip on the furtka.org nginx (config only — needs a
+ deploy on forge-runner-01).** Default nginx only gzips `text/html`,
+ so the homepage HTML was the only asset coming back compressed. The
+ ~600 KB `three.min.js` bundle (and the hashed CSS) were being shipped
+ uncompressed across the public openresty proxy. `gzip_types` in
+ `ops/nginx/furtka.org.conf` now covers css/js/json/xml/svg/woff2.
+ Needs `sudo ops/nginx/setup-vm.sh` on forge-runner-01 to take effect
+ — the site-deploy workflow only rebuilds Hugo, it doesn't touch the
+ nginx config.
+
## [26.15-alpha] - 2026-04-21
### Fixed
@@ -354,7 +404,8 @@ First tagged snapshot. Pre-alpha — the installer does not yet boot, but the de
- **Containers:** Docker + Compose
- **License:** AGPL-3.0
-[Unreleased]: https://forgejo.sourcegate.online/daniel/furtka/compare/26.15-alpha...HEAD
+[Unreleased]: https://forgejo.sourcegate.online/daniel/furtka/compare/26.16-alpha...HEAD
+[26.16-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.16-alpha
[26.15-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.15-alpha
[26.14-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.14-alpha
[26.13-alpha]: https://forgejo.sourcegate.online/daniel/furtka/releases/tag/26.13-alpha
diff --git a/pyproject.toml b/pyproject.toml
index 2344472..5ddfb71 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "furtka"
-version = "26.15-alpha"
+version = "26.16-alpha"
description = "Open-source home server OS — simple enough for everyone."
requires-python = ">=3.11"
readme = "README.md"
diff --git a/website/content/_index.de.md b/website/content/_index.de.md
index f879976..09469d5 100644
--- a/website/content/_index.de.md
+++ b/website/content/_index.de.md
@@ -1,7 +1,7 @@
---
title: "Furtka"
description: "Offenes Heimserver-Betriebssystem — einfach genug für alle."
-status: "26.15-alpha — in Arbeit"
+status: "26.16-alpha — in Arbeit"
# features_today / features_next müssen index-parallel zu content/_index.md bleiben.
intro: |
**Furtka** ist ein offenes Heimserver-Betriebssystem.
diff --git a/website/content/_index.md b/website/content/_index.md
index 98041f0..decc35a 100644
--- a/website/content/_index.md
+++ b/website/content/_index.md
@@ -1,7 +1,7 @@
---
title: "Furtka"
description: "Open-source home server OS — simple enough for everyone."
-status: "26.15-alpha — work in progress"
+status: "26.16-alpha — work in progress"
# Keep features_today / features_next index-aligned with content/_index.de.md.
intro: |
**Furtka** is an open-source home server OS.
diff --git a/website/hugo.toml b/website/hugo.toml
index 7c91d66..612a880 100644
--- a/website/hugo.toml
+++ b/website/hugo.toml
@@ -6,7 +6,7 @@ enableRobotsTXT = true
[params]
description = "Open-source home server OS — simple enough for everyone."
- version = "26.15-alpha"
+ version = "26.16-alpha"
contactEmail = "hallo@furtka.org"
[markup.goldmark.renderer]