From 466df3bd04c78c3a3298cf1f8f2932f3ad42808c Mon Sep 17 00:00:00 2001
From: Stefan Koelle
Date: Fri, 11 Sep 2026 10:53:22 +0200
Subject: [PATCH] Consolidate all moonweb.org sites under www.moonweb.org
- Migrate timecapsule (old www.moonweb.org) into monorepo as Eleventy 2.x site
- Change all site URLs from subdomains to subdirectories under www.moonweb.org
- Replace Cloudflare Pages deployment with IONOS SFTP
- Update site-switcher, footer, and all internal links
- Add merge script for combining all sites into single deployment
- Update CI/CD workflow for IONOS SFTP deployment
- Update stefankoelle.de references to use new URLs
- Update AGENTS.md and README.md documentation
---
.github/workflows/build-deploy-moonweb.yml | 195 ++
.github/workflows/build-deploy.yml | 139 -
AGENTS.md | 114 +-
README.md | 257 +-
TODO.md | 128 +-
code/eleventy.config.js | 2 +-
hub/eleventy.config.js | 2 +-
hub/impressum.njk | 18 +-
hub/index.njk | 12 +-
infra/eleventy.config.js | 2 +-
package.json | 12 +-
retro/eleventy.config.js | 2 +-
scripts/merge-moonweb.sh | 49 +
shared/_includes/base.njk | 19 +-
smarthome/eleventy.config.js | 2 +-
stefankoelle/_includes/base.njk | 14 +-
stefankoelle/_includes/stefankoelle.njk | 2 +-
stefankoelle/index.njk | 36 +-
stefankoelle/ledmatrix/index.njk | 6 +-
timecapsule/_site/404/index.html | 69 +
timecapsule/_site/acoustics/index.html | 254 ++
timecapsule/_site/background/index.html | 270 ++
timecapsule/_site/beginning/index.html | 12 +
timecapsule/_site/beginning/news.html | 247 ++
timecapsule/_site/beginning/report.html | 242 ++
timecapsule/_site/beginning/sitemap.html | 354 +++
timecapsule/_site/contact/index.html | 233 ++
timecapsule/_site/hardware.html | 12 +
timecapsule/_site/index.html | 235 ++
timecapsule/_site/index2.html | 12 +
timecapsule/_site/index3.html | 12 +
timecapsule/_site/infos.html | 12 +
timecapsule/_site/legal-notice/index.html | 224 ++
timecapsule/_site/links.html | 12 +
timecapsule/_site/location/index.html | 241 ++
timecapsule/_site/network/index.html | 219 ++
timecapsule/_site/new.html | 12 +
timecapsule/_site/partners/index.html | 241 ++
timecapsule/_site/products/index.html | 301 ++
timecapsule/_site/projects.html | 12 +
timecapsule/_site/projects/index.html | 341 +++
timecapsule/_site/start.html | 12 +
timecapsule/_site/stefan/index.html | 228 ++
timecapsule/_site/timecapsule/.htaccess | 3 +
.../_site/timecapsule/acoustics/index.html | 254 ++
.../assets/archive/banner/moonback_finish.gif | Bin 0 -> 15676 bytes
.../archive/banner/moonweb_banner_ani.gif | Bin 0 -> 13669 bytes
.../archive/banner/moonweb_banner_static.gif | Bin 0 -> 11518 bytes
.../archive/banner/moonweb_newdesign5.gif | Bin 0 -> 35689 bytes
.../timecapsule/assets/archive/fuckoff.jpg | Bin 0 -> 4422 bytes
.../timecapsule/assets/archive/splash-pre.gif | Bin 0 -> 12946 bytes
.../timecapsule/assets/archive/splash.gif | Bin 0 -> 7616 bytes
.../timecapsule/assets/content/network.jpg | Bin 0 -> 37678 bytes
.../assets/content/stefan-koelle.jpg | Bin 0 -> 10569 bytes
.../_site/timecapsule/assets/css/moonweb.css | 315 +++
.../assets/css/nav-replacement.css | 104 +
.../timecapsule/assets/images/background.gif | Bin 0 -> 918 bytes
.../timecapsule/assets/images/favicon.ico | Bin 0 -> 1150 bytes
.../_site/timecapsule/assets/images/item.gif | Bin 0 -> 91 bytes
.../_site/timecapsule/assets/images/logo.gif | Bin 0 -> 7516 bytes
.../timecapsule/assets/images/logomobile.gif | Bin 0 -> 11518 bytes
.../timecapsule/assets/images/pixel-white.gif | Bin 0 -> 85 bytes
.../assets/images/quicknav-back.gif | Bin 0 -> 818 bytes
.../assets/images/quicknav-end.gif | Bin 0 -> 1289 bytes
.../assets/images/quicknav-top.gif | Bin 0 -> 1497 bytes
.../timecapsule/assets/images/redbottom.gif | Bin 0 -> 179 bytes
.../timecapsule/assets/images/redline.gif | Bin 0 -> 141 bytes
.../timecapsule/assets/menu/acoustics.gif | Bin 0 -> 1146 bytes
.../timecapsule/assets/menu/acoustics_a.gif | Bin 0 -> 1147 bytes
.../timecapsule/assets/menu/acoustics_h.gif | Bin 0 -> 1237 bytes
.../timecapsule/assets/menu/background.gif | Bin 0 -> 1166 bytes
.../timecapsule/assets/menu/background_a.gif | Bin 0 -> 1159 bytes
.../timecapsule/assets/menu/background_h.gif | Bin 0 -> 1234 bytes
.../timecapsule/assets/menu/beginning.gif | Bin 0 -> 1144 bytes
.../timecapsule/assets/menu/beginning_a.gif | Bin 0 -> 1137 bytes
.../timecapsule/assets/menu/beginning_h.gif | Bin 0 -> 1220 bytes
.../_site/timecapsule/assets/menu/contact.gif | Bin 0 -> 1105 bytes
.../timecapsule/assets/menu/contact_a.gif | Bin 0 -> 1100 bytes
.../timecapsule/assets/menu/contact_h.gif | Bin 0 -> 1194 bytes
.../timecapsule/assets/menu/location.gif | Bin 0 -> 1130 bytes
.../timecapsule/assets/menu/location_a.gif | Bin 0 -> 1120 bytes
.../timecapsule/assets/menu/location_h.gif | Bin 0 -> 1205 bytes
.../timecapsule/assets/menu/partners.gif | Bin 0 -> 1107 bytes
.../timecapsule/assets/menu/partners_a.gif | Bin 0 -> 1110 bytes
.../timecapsule/assets/menu/partners_h.gif | Bin 0 -> 1194 bytes
.../timecapsule/assets/menu/products.gif | Bin 0 -> 1130 bytes
.../timecapsule/assets/menu/products_a.gif | Bin 0 -> 1126 bytes
.../timecapsule/assets/menu/products_h.gif | Bin 0 -> 1202 bytes
.../timecapsule/assets/menu/projects.gif | Bin 0 -> 1152 bytes
.../timecapsule/assets/menu/projects_a.gif | Bin 0 -> 1139 bytes
.../timecapsule/assets/menu/projects_h.gif | Bin 0 -> 1235 bytes
.../assets/pageImage/acoustics.jpg | Bin 0 -> 4758 bytes
.../assets/pageImage/background.jpg | Bin 0 -> 4817 bytes
.../assets/pageImage/beginning.jpg | Bin 0 -> 7779 bytes
.../timecapsule/assets/pageImage/contact.jpg | Bin 0 -> 3739 bytes
.../timecapsule/assets/pageImage/location.jpg | Bin 0 -> 7194 bytes
.../timecapsule/assets/pageImage/network.jpg | Bin 0 -> 3999 bytes
.../timecapsule/assets/pageImage/partners.jpg | Bin 0 -> 3794 bytes
.../timecapsule/assets/pageImage/products.jpg | Bin 0 -> 4746 bytes
.../timecapsule/assets/pageImage/projects.jpg | Bin 0 -> 3999 bytes
.../timecapsule/assets/pageImage/stefan.jpg | Bin 0 -> 3739 bytes
.../_site/timecapsule/background/index.html | 270 ++
.../_site/timecapsule/beginning/index.html | 12 +
.../_site/timecapsule/beginning/news.html | 247 ++
.../_site/timecapsule/beginning/report.html | 242 ++
.../_site/timecapsule/beginning/sitemap.html | 354 +++
.../_site/timecapsule/contact/index.html | 233 ++
timecapsule/_site/timecapsule/hardware.html | 12 +
timecapsule/_site/timecapsule/index.html | 235 ++
timecapsule/_site/timecapsule/index2.html | 12 +
timecapsule/_site/timecapsule/index3.html | 12 +
timecapsule/_site/timecapsule/infos.html | 12 +
.../_site/timecapsule/legal-notice/index.html | 224 ++
timecapsule/_site/timecapsule/links.html | 12 +
.../_site/timecapsule/location/index.html | 241 ++
.../_site/timecapsule/network/index.html | 219 ++
timecapsule/_site/timecapsule/new.html | 12 +
.../_site/timecapsule/partners/index.html | 241 ++
.../_site/timecapsule/products/index.html | 301 ++
timecapsule/_site/timecapsule/projects.html | 12 +
.../_site/timecapsule/projects/index.html | 341 +++
timecapsule/_site/timecapsule/robots.txt | 4 +
timecapsule/_site/timecapsule/sitemap.xml | 59 +
timecapsule/_site/timecapsule/start.html | 12 +
.../_site/timecapsule/stefan/index.html | 228 ++
timecapsule/_site/timecapsule/users.html | 12 +
timecapsule/_site/users.html | 12 +
timecapsule/eleventy.config.js | 38 +
timecapsule/package-lock.json | 2505 +++++++++++++++++
timecapsule/package.json | 14 +
timecapsule/src/.htaccess | 3 +
timecapsule/src/404/index.html | 69 +
timecapsule/src/_data/nav.json | 18 +
timecapsule/src/_data/site.json | 4 +
timecapsule/src/_includes/layout.njk | 92 +
timecapsule/src/_includes/nav.njk | 17 +
timecapsule/src/_includes/quicknav.njk | 2 +
timecapsule/src/_includes/redirect.njk | 12 +
timecapsule/src/acoustics/index.md | 52 +
.../assets/archive/banner/moonback_finish.gif | Bin 0 -> 15676 bytes
.../archive/banner/moonweb_banner_ani.gif | Bin 0 -> 13669 bytes
.../archive/banner/moonweb_banner_static.gif | Bin 0 -> 11518 bytes
.../archive/banner/moonweb_newdesign5.gif | Bin 0 -> 35689 bytes
timecapsule/src/assets/archive/fuckoff.jpg | Bin 0 -> 4422 bytes
timecapsule/src/assets/archive/splash-pre.gif | Bin 0 -> 12946 bytes
timecapsule/src/assets/archive/splash.gif | Bin 0 -> 7616 bytes
timecapsule/src/assets/content/network.jpg | Bin 0 -> 37678 bytes
.../src/assets/content/stefan-koelle.jpg | Bin 0 -> 10569 bytes
timecapsule/src/assets/css/moonweb.css | 315 +++
timecapsule/src/assets/images/background.gif | Bin 0 -> 918 bytes
timecapsule/src/assets/images/favicon.ico | Bin 0 -> 1150 bytes
timecapsule/src/assets/images/item.gif | Bin 0 -> 91 bytes
timecapsule/src/assets/images/logo.gif | Bin 0 -> 7516 bytes
timecapsule/src/assets/images/logomobile.gif | Bin 0 -> 11518 bytes
timecapsule/src/assets/images/pixel-white.gif | Bin 0 -> 85 bytes
.../src/assets/images/quicknav-back.gif | Bin 0 -> 818 bytes
.../src/assets/images/quicknav-end.gif | Bin 0 -> 1289 bytes
.../src/assets/images/quicknav-top.gif | Bin 0 -> 1497 bytes
timecapsule/src/assets/images/redbottom.gif | Bin 0 -> 179 bytes
timecapsule/src/assets/images/redline.gif | Bin 0 -> 141 bytes
timecapsule/src/assets/menu/acoustics.gif | Bin 0 -> 1146 bytes
timecapsule/src/assets/menu/acoustics_a.gif | Bin 0 -> 1147 bytes
timecapsule/src/assets/menu/acoustics_h.gif | Bin 0 -> 1237 bytes
timecapsule/src/assets/menu/background.gif | Bin 0 -> 1166 bytes
timecapsule/src/assets/menu/background_a.gif | Bin 0 -> 1159 bytes
timecapsule/src/assets/menu/background_h.gif | Bin 0 -> 1234 bytes
timecapsule/src/assets/menu/beginning.gif | Bin 0 -> 1144 bytes
timecapsule/src/assets/menu/beginning_a.gif | Bin 0 -> 1137 bytes
timecapsule/src/assets/menu/beginning_h.gif | Bin 0 -> 1220 bytes
timecapsule/src/assets/menu/contact.gif | Bin 0 -> 1105 bytes
timecapsule/src/assets/menu/contact_a.gif | Bin 0 -> 1100 bytes
timecapsule/src/assets/menu/contact_h.gif | Bin 0 -> 1194 bytes
timecapsule/src/assets/menu/location.gif | Bin 0 -> 1130 bytes
timecapsule/src/assets/menu/location_a.gif | Bin 0 -> 1120 bytes
timecapsule/src/assets/menu/location_h.gif | Bin 0 -> 1205 bytes
timecapsule/src/assets/menu/partners.gif | Bin 0 -> 1107 bytes
timecapsule/src/assets/menu/partners_a.gif | Bin 0 -> 1110 bytes
timecapsule/src/assets/menu/partners_h.gif | Bin 0 -> 1194 bytes
timecapsule/src/assets/menu/products.gif | Bin 0 -> 1130 bytes
timecapsule/src/assets/menu/products_a.gif | Bin 0 -> 1126 bytes
timecapsule/src/assets/menu/products_h.gif | Bin 0 -> 1202 bytes
timecapsule/src/assets/menu/projects.gif | Bin 0 -> 1152 bytes
timecapsule/src/assets/menu/projects_a.gif | Bin 0 -> 1139 bytes
timecapsule/src/assets/menu/projects_h.gif | Bin 0 -> 1235 bytes
.../src/assets/pageImage/acoustics.jpg | Bin 0 -> 4758 bytes
.../src/assets/pageImage/background.jpg | Bin 0 -> 4817 bytes
.../src/assets/pageImage/beginning.jpg | Bin 0 -> 7779 bytes
timecapsule/src/assets/pageImage/contact.jpg | Bin 0 -> 3739 bytes
timecapsule/src/assets/pageImage/location.jpg | Bin 0 -> 7194 bytes
timecapsule/src/assets/pageImage/network.jpg | Bin 0 -> 3999 bytes
timecapsule/src/assets/pageImage/partners.jpg | Bin 0 -> 3794 bytes
timecapsule/src/assets/pageImage/products.jpg | Bin 0 -> 4746 bytes
timecapsule/src/assets/pageImage/projects.jpg | Bin 0 -> 3999 bytes
timecapsule/src/assets/pageImage/stefan.jpg | Bin 0 -> 3739 bytes
timecapsule/src/background/index.md | 67 +
timecapsule/src/beginning/index.md | 8 +
timecapsule/src/beginning/news.md | 43 +
timecapsule/src/beginning/report.md | 39 +
timecapsule/src/beginning/sitemap.md | 160 ++
timecapsule/src/contact/index.md | 25 +
timecapsule/src/css/nav-replacement.njk | 38 +
timecapsule/src/hardware.md | 5 +
timecapsule/src/index.md | 35 +
timecapsule/src/index2.md | 5 +
timecapsule/src/index3.md | 5 +
timecapsule/src/infos.md | 5 +
timecapsule/src/legal-notice/index.md | 20 +
timecapsule/src/links.md | 5 +
timecapsule/src/location/index.md | 43 +
timecapsule/src/network/index.md | 15 +
timecapsule/src/new.md | 5 +
timecapsule/src/partners/index.md | 46 +
timecapsule/src/products/index.md | 84 +
timecapsule/src/projects.md | 5 +
timecapsule/src/projects/index.md | 103 +
timecapsule/src/robots.njk | 8 +
timecapsule/src/sitemap.xml.njk | 12 +
timecapsule/src/start.md | 5 +
timecapsule/src/stefan/index.md | 26 +
timecapsule/src/users.md | 5 +
220 files changed, 12598 insertions(+), 425 deletions(-)
create mode 100644 .github/workflows/build-deploy-moonweb.yml
delete mode 100644 .github/workflows/build-deploy.yml
create mode 100755 scripts/merge-moonweb.sh
create mode 100644 timecapsule/_site/404/index.html
create mode 100644 timecapsule/_site/acoustics/index.html
create mode 100644 timecapsule/_site/background/index.html
create mode 100644 timecapsule/_site/beginning/index.html
create mode 100644 timecapsule/_site/beginning/news.html
create mode 100644 timecapsule/_site/beginning/report.html
create mode 100644 timecapsule/_site/beginning/sitemap.html
create mode 100644 timecapsule/_site/contact/index.html
create mode 100644 timecapsule/_site/hardware.html
create mode 100644 timecapsule/_site/index.html
create mode 100644 timecapsule/_site/index2.html
create mode 100644 timecapsule/_site/index3.html
create mode 100644 timecapsule/_site/infos.html
create mode 100644 timecapsule/_site/legal-notice/index.html
create mode 100644 timecapsule/_site/links.html
create mode 100644 timecapsule/_site/location/index.html
create mode 100644 timecapsule/_site/network/index.html
create mode 100644 timecapsule/_site/new.html
create mode 100644 timecapsule/_site/partners/index.html
create mode 100644 timecapsule/_site/products/index.html
create mode 100644 timecapsule/_site/projects.html
create mode 100644 timecapsule/_site/projects/index.html
create mode 100644 timecapsule/_site/start.html
create mode 100644 timecapsule/_site/stefan/index.html
create mode 100644 timecapsule/_site/timecapsule/.htaccess
create mode 100644 timecapsule/_site/timecapsule/acoustics/index.html
create mode 100755 timecapsule/_site/timecapsule/assets/archive/banner/moonback_finish.gif
create mode 100755 timecapsule/_site/timecapsule/assets/archive/banner/moonweb_banner_ani.gif
create mode 100755 timecapsule/_site/timecapsule/assets/archive/banner/moonweb_banner_static.gif
create mode 100755 timecapsule/_site/timecapsule/assets/archive/banner/moonweb_newdesign5.gif
create mode 100755 timecapsule/_site/timecapsule/assets/archive/fuckoff.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/archive/splash-pre.gif
create mode 100755 timecapsule/_site/timecapsule/assets/archive/splash.gif
create mode 100755 timecapsule/_site/timecapsule/assets/content/network.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/content/stefan-koelle.jpg
create mode 100644 timecapsule/_site/timecapsule/assets/css/moonweb.css
create mode 100644 timecapsule/_site/timecapsule/assets/css/nav-replacement.css
create mode 100755 timecapsule/_site/timecapsule/assets/images/background.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/favicon.ico
create mode 100755 timecapsule/_site/timecapsule/assets/images/item.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/logo.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/logomobile.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/pixel-white.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/quicknav-back.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/quicknav-end.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/quicknav-top.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/redbottom.gif
create mode 100755 timecapsule/_site/timecapsule/assets/images/redline.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/acoustics.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/acoustics_a.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/acoustics_h.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/background.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/background_a.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/background_h.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/beginning.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/beginning_a.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/beginning_h.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/contact.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/contact_a.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/contact_h.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/location.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/location_a.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/location_h.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/partners.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/partners_a.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/partners_h.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/products.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/products_a.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/products_h.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/projects.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/projects_a.gif
create mode 100755 timecapsule/_site/timecapsule/assets/menu/projects_h.gif
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/acoustics.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/background.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/beginning.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/contact.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/location.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/network.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/partners.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/products.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/projects.jpg
create mode 100755 timecapsule/_site/timecapsule/assets/pageImage/stefan.jpg
create mode 100644 timecapsule/_site/timecapsule/background/index.html
create mode 100644 timecapsule/_site/timecapsule/beginning/index.html
create mode 100644 timecapsule/_site/timecapsule/beginning/news.html
create mode 100644 timecapsule/_site/timecapsule/beginning/report.html
create mode 100644 timecapsule/_site/timecapsule/beginning/sitemap.html
create mode 100644 timecapsule/_site/timecapsule/contact/index.html
create mode 100644 timecapsule/_site/timecapsule/hardware.html
create mode 100644 timecapsule/_site/timecapsule/index.html
create mode 100644 timecapsule/_site/timecapsule/index2.html
create mode 100644 timecapsule/_site/timecapsule/index3.html
create mode 100644 timecapsule/_site/timecapsule/infos.html
create mode 100644 timecapsule/_site/timecapsule/legal-notice/index.html
create mode 100644 timecapsule/_site/timecapsule/links.html
create mode 100644 timecapsule/_site/timecapsule/location/index.html
create mode 100644 timecapsule/_site/timecapsule/network/index.html
create mode 100644 timecapsule/_site/timecapsule/new.html
create mode 100644 timecapsule/_site/timecapsule/partners/index.html
create mode 100644 timecapsule/_site/timecapsule/products/index.html
create mode 100644 timecapsule/_site/timecapsule/projects.html
create mode 100644 timecapsule/_site/timecapsule/projects/index.html
create mode 100644 timecapsule/_site/timecapsule/robots.txt
create mode 100644 timecapsule/_site/timecapsule/sitemap.xml
create mode 100644 timecapsule/_site/timecapsule/start.html
create mode 100644 timecapsule/_site/timecapsule/stefan/index.html
create mode 100644 timecapsule/_site/timecapsule/users.html
create mode 100644 timecapsule/_site/users.html
create mode 100644 timecapsule/eleventy.config.js
create mode 100644 timecapsule/package-lock.json
create mode 100644 timecapsule/package.json
create mode 100644 timecapsule/src/.htaccess
create mode 100644 timecapsule/src/404/index.html
create mode 100644 timecapsule/src/_data/nav.json
create mode 100644 timecapsule/src/_data/site.json
create mode 100644 timecapsule/src/_includes/layout.njk
create mode 100644 timecapsule/src/_includes/nav.njk
create mode 100644 timecapsule/src/_includes/quicknav.njk
create mode 100644 timecapsule/src/_includes/redirect.njk
create mode 100644 timecapsule/src/acoustics/index.md
create mode 100755 timecapsule/src/assets/archive/banner/moonback_finish.gif
create mode 100755 timecapsule/src/assets/archive/banner/moonweb_banner_ani.gif
create mode 100755 timecapsule/src/assets/archive/banner/moonweb_banner_static.gif
create mode 100755 timecapsule/src/assets/archive/banner/moonweb_newdesign5.gif
create mode 100755 timecapsule/src/assets/archive/fuckoff.jpg
create mode 100755 timecapsule/src/assets/archive/splash-pre.gif
create mode 100755 timecapsule/src/assets/archive/splash.gif
create mode 100755 timecapsule/src/assets/content/network.jpg
create mode 100755 timecapsule/src/assets/content/stefan-koelle.jpg
create mode 100644 timecapsule/src/assets/css/moonweb.css
create mode 100755 timecapsule/src/assets/images/background.gif
create mode 100755 timecapsule/src/assets/images/favicon.ico
create mode 100755 timecapsule/src/assets/images/item.gif
create mode 100755 timecapsule/src/assets/images/logo.gif
create mode 100755 timecapsule/src/assets/images/logomobile.gif
create mode 100755 timecapsule/src/assets/images/pixel-white.gif
create mode 100755 timecapsule/src/assets/images/quicknav-back.gif
create mode 100755 timecapsule/src/assets/images/quicknav-end.gif
create mode 100755 timecapsule/src/assets/images/quicknav-top.gif
create mode 100755 timecapsule/src/assets/images/redbottom.gif
create mode 100755 timecapsule/src/assets/images/redline.gif
create mode 100755 timecapsule/src/assets/menu/acoustics.gif
create mode 100755 timecapsule/src/assets/menu/acoustics_a.gif
create mode 100755 timecapsule/src/assets/menu/acoustics_h.gif
create mode 100755 timecapsule/src/assets/menu/background.gif
create mode 100755 timecapsule/src/assets/menu/background_a.gif
create mode 100755 timecapsule/src/assets/menu/background_h.gif
create mode 100755 timecapsule/src/assets/menu/beginning.gif
create mode 100755 timecapsule/src/assets/menu/beginning_a.gif
create mode 100755 timecapsule/src/assets/menu/beginning_h.gif
create mode 100755 timecapsule/src/assets/menu/contact.gif
create mode 100755 timecapsule/src/assets/menu/contact_a.gif
create mode 100755 timecapsule/src/assets/menu/contact_h.gif
create mode 100755 timecapsule/src/assets/menu/location.gif
create mode 100755 timecapsule/src/assets/menu/location_a.gif
create mode 100755 timecapsule/src/assets/menu/location_h.gif
create mode 100755 timecapsule/src/assets/menu/partners.gif
create mode 100755 timecapsule/src/assets/menu/partners_a.gif
create mode 100755 timecapsule/src/assets/menu/partners_h.gif
create mode 100755 timecapsule/src/assets/menu/products.gif
create mode 100755 timecapsule/src/assets/menu/products_a.gif
create mode 100755 timecapsule/src/assets/menu/products_h.gif
create mode 100755 timecapsule/src/assets/menu/projects.gif
create mode 100755 timecapsule/src/assets/menu/projects_a.gif
create mode 100755 timecapsule/src/assets/menu/projects_h.gif
create mode 100755 timecapsule/src/assets/pageImage/acoustics.jpg
create mode 100755 timecapsule/src/assets/pageImage/background.jpg
create mode 100755 timecapsule/src/assets/pageImage/beginning.jpg
create mode 100755 timecapsule/src/assets/pageImage/contact.jpg
create mode 100755 timecapsule/src/assets/pageImage/location.jpg
create mode 100755 timecapsule/src/assets/pageImage/network.jpg
create mode 100755 timecapsule/src/assets/pageImage/partners.jpg
create mode 100755 timecapsule/src/assets/pageImage/products.jpg
create mode 100755 timecapsule/src/assets/pageImage/projects.jpg
create mode 100755 timecapsule/src/assets/pageImage/stefan.jpg
create mode 100644 timecapsule/src/background/index.md
create mode 100644 timecapsule/src/beginning/index.md
create mode 100644 timecapsule/src/beginning/news.md
create mode 100644 timecapsule/src/beginning/report.md
create mode 100644 timecapsule/src/beginning/sitemap.md
create mode 100644 timecapsule/src/contact/index.md
create mode 100644 timecapsule/src/css/nav-replacement.njk
create mode 100644 timecapsule/src/hardware.md
create mode 100644 timecapsule/src/index.md
create mode 100644 timecapsule/src/index2.md
create mode 100644 timecapsule/src/index3.md
create mode 100644 timecapsule/src/infos.md
create mode 100644 timecapsule/src/legal-notice/index.md
create mode 100644 timecapsule/src/links.md
create mode 100644 timecapsule/src/location/index.md
create mode 100644 timecapsule/src/network/index.md
create mode 100644 timecapsule/src/new.md
create mode 100644 timecapsule/src/partners/index.md
create mode 100644 timecapsule/src/products/index.md
create mode 100644 timecapsule/src/projects.md
create mode 100644 timecapsule/src/projects/index.md
create mode 100644 timecapsule/src/robots.njk
create mode 100644 timecapsule/src/sitemap.xml.njk
create mode 100644 timecapsule/src/start.md
create mode 100644 timecapsule/src/stefan/index.md
create mode 100644 timecapsule/src/users.md
diff --git a/.github/workflows/build-deploy-moonweb.yml b/.github/workflows/build-deploy-moonweb.yml
new file mode 100644
index 0000000..043b0b3
--- /dev/null
+++ b/.github/workflows/build-deploy-moonweb.yml
@@ -0,0 +1,195 @@
+name: Build & Deploy moonweb.org
+
+on:
+ push:
+ branches: [main]
+ paths-ignore:
+ - 'stefankoelle/**'
+ - '.github/workflows/deploy-stefankoelle.yml'
+ pull_request:
+ branches: [main]
+ paths-ignore:
+ - 'stefankoelle/**'
+ - '.github/workflows/deploy-stefankoelle.yml'
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+env:
+ NODE_VERSION: "22"
+
+jobs:
+ build:
+ name: Build ${{ matrix.site }}
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ site: [hub, infra, smarthome, code, retro]
+ steps:
+ - uses: actions/checkout@v7
+
+ - uses: actions/setup-node@v7
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+ cache: "npm"
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Build ${{ matrix.site }}
+ run: npm run build:${{ matrix.site }}
+
+ - name: Validate build output
+ run: |
+ if [ ! -d "dist/${{ matrix.site }}" ]; then
+ echo "Error: dist/${{ matrix.site }} not found"
+ exit 1
+ fi
+ if [ -z "$(ls -A dist/${{ matrix.site }} 2>/dev/null)" ]; then
+ echo "Error: dist/${{ matrix.site }} is empty"
+ exit 1
+ fi
+ echo "Build output:"
+ find dist/${{ matrix.site }} -type f | head -20
+
+ - name: Upload build artifact
+ uses: actions/upload-artifact@v7
+ with:
+ name: dist-${{ matrix.site }}
+ path: dist/${{ matrix.site }}
+ retention-days: 7
+
+ build-timecapsule:
+ name: Build timecapsule
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+
+ - uses: actions/setup-node@v7
+ with:
+ node-version: ${{ env.NODE_VERSION }}
+
+ - name: Install timecapsule dependencies
+ run: cd timecapsule && npm ci
+
+ - name: Build timecapsule
+ run: npm run build:timecapsule
+
+ - name: Validate build output
+ run: |
+ if [ ! -d "dist/timecapsule" ]; then
+ echo "Error: dist/timecapsule not found"
+ exit 1
+ fi
+ if [ -z "$(ls -A dist/timecapsule 2>/dev/null)" ]; then
+ echo "Error: dist/timecapsule is empty"
+ exit 1
+ fi
+ echo "Build output:"
+ find dist/timecapsule -type f | head -20
+
+ - name: Upload build artifact
+ uses: actions/upload-artifact@v7
+ with:
+ name: dist-timecapsule
+ path: dist/timecapsule
+ retention-days: 7
+
+ merge:
+ name: Merge all sites
+ needs: [build, build-timecapsule]
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v7
+
+ - name: Download all artifacts
+ uses: actions/download-artifact@v8
+ with:
+ path: artifacts/
+
+ - name: Merge into dist/
+ run: |
+ mkdir -p dist
+
+ # Hub becomes root
+ cp -r artifacts/dist-hub/* dist/
+
+ # Subdirectories
+ for site in infra smarthome code retro timecapsule; do
+ if [ -d "artifacts/dist-$site" ]; then
+ cp -r "artifacts/dist-$site" "dist/$site"
+ fi
+ done
+
+ # Copy shared CSS to root (accessible from all subdirectories)
+ cp shared/base.css dist/shared-base.css
+ cp shared/favicon/hub.svg dist/favicon.svg
+
+ echo "Final structure:"
+ find dist -maxdepth 2 -type f | sort | head -40
+ echo "..."
+ echo "Total files:"
+ find dist -type f | wc -l
+
+ - name: Upload merged artifact
+ uses: actions/upload-artifact@v7
+ with:
+ name: dist-moonweb-merged
+ path: dist/
+ retention-days: 7
+
+ deploy:
+ name: Deploy to IONOS
+ needs: merge
+ runs-on: ubuntu-latest
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+ steps:
+ - name: Download merged artifact
+ uses: actions/download-artifact@v8
+ with:
+ name: dist-moonweb-merged
+ path: dist/
+
+ - name: Deploy via SFTP
+ uses: wlixcc/SFTP-Deploy-Action@v1.2.6
+ with:
+ local_path: './dist/*'
+ server: ${{ secrets.IONOS_SFTP_HOST }}
+ username: ${{ secrets.IONOS_SFTP_USER }}
+ password: ${{ secrets.IONOS_SFTP_PASSWORD }}
+ remote_path: '/websites/moonweb/'
+ port: 22
+ sftp_only: true
+
+ summary:
+ name: Deploy Summary
+ needs: deploy
+ runs-on: ubuntu-latest
+ if: always()
+ steps:
+ - name: Print deployment summary
+ run: |
+ echo "## Deployment Summary" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ if [ "${{ needs.deploy.result }}" = "success" ]; then
+ echo "moonweb.org deployed successfully!" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "Deployment failed. Check the deploy jobs for details." >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Sites" >> $GITHUB_STEP_SUMMARY
+ echo "| Site | URL |" >> $GITHUB_STEP_SUMMARY
+ echo "|------|-----|" >> $GITHUB_STEP_SUMMARY
+ echo "| hub | https://www.moonweb.org/ |" >> $GITHUB_STEP_SUMMARY
+ echo "| infra | https://www.moonweb.org/infra/ |" >> $GITHUB_STEP_SUMMARY
+ echo "| smarthome | https://www.moonweb.org/smarthome/ |" >> $GITHUB_STEP_SUMMARY
+ echo "| code | https://www.moonweb.org/code/ |" >> $GITHUB_STEP_SUMMARY
+ echo "| retro | https://www.moonweb.org/retro/ |" >> $GITHUB_STEP_SUMMARY
+ echo "| timecapsule | https://www.moonweb.org/timecapsule/ |" >> $GITHUB_STEP_SUMMARY
+
+# Required repo secrets:
+# IONOS_SFTP_HOST — IONOS SFTP server hostname
+# IONOS_SFTP_USER — IONOS SFTP username
+# IONOS_SFTP_PASSWORD — IONOS SFTP password
diff --git a/.github/workflows/build-deploy.yml b/.github/workflows/build-deploy.yml
deleted file mode 100644
index 59232bd..0000000
--- a/.github/workflows/build-deploy.yml
+++ /dev/null
@@ -1,139 +0,0 @@
-name: Build & Deploy moonweb-site
-
-on:
- push:
- branches: [main]
- paths-ignore:
- - 'stefankoelle/**'
- - '.github/workflows/deploy-stefankoelle.yml'
- pull_request:
- branches: [main]
- paths-ignore:
- - 'stefankoelle/**'
- - '.github/workflows/deploy-stefankoelle.yml'
-
-# Cancel in-progress runs for the same branch
-concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
-
-env:
- NODE_VERSION: "22"
-
-jobs:
- build:
- name: Build ${{ matrix.site }}
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- site: [hub, infra, smarthome, code, retro]
- steps:
- - uses: actions/checkout@v7
-
- - uses: actions/setup-node@v7
- with:
- node-version: ${{ env.NODE_VERSION }}
- cache: "npm"
-
- - name: Install dependencies
- run: npm ci
-
- - name: Build ${{ matrix.site }}
- run: npm run build:${{ matrix.site }}
-
- - name: Validate build output
- run: |
- if [ ! -d "dist/${{ matrix.site }}" ]; then
- echo "Error: dist/${{ matrix.site }} not found"
- exit 1
- fi
- if [ -z "$(ls -A dist/${{ matrix.site }} 2>/dev/null)" ]; then
- echo "Error: dist/${{ matrix.site }} is empty"
- exit 1
- fi
- echo "Build output:"
- find dist/${{ matrix.site }} -type f | head -20
-
- - name: Upload build artifact
- uses: actions/upload-artifact@v7
- with:
- name: dist-${{ matrix.site }}
- path: dist/${{ matrix.site }}
- retention-days: 7
-
- deploy:
- name: Deploy ${{ matrix.site }}
- needs: build
- runs-on: ubuntu-latest
- if: github.ref == 'refs/heads/main' && github.event_name == 'push'
- strategy:
- fail-fast: false
- matrix:
- include:
- - site: hub
- cf_project: moonweb-hub
- - site: infra
- cf_project: moonweb-infra
- - site: smarthome
- cf_project: moonweb-smarthome
- - site: code
- cf_project: moonweb-code
- - site: retro
- cf_project: moonweb-retro
- steps:
- - name: Download build artifact
- uses: actions/download-artifact@v8
- with:
- name: dist-${{ matrix.site }}
- path: dist/${{ matrix.site }}
-
- - name: Create wrangler.toml for Worker
- run: |
- echo 'name = "${{ matrix.cf_project }}"' > wrangler.toml
- echo 'compatibility_date = "2024-01-01"' >> wrangler.toml
- echo '' >> wrangler.toml
- echo '[assets]' >> wrangler.toml
- echo 'directory = "./dist/${{ matrix.site }}"' >> wrangler.toml
- echo 'not_found_handling = "404-page"' >> wrangler.toml
-
- - name: Deploy to Cloudflare Workers
- uses: cloudflare/wrangler-action@v4
- with:
- apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- command: deploy
-
- summary:
- name: Deploy Summary
- needs: deploy
- runs-on: ubuntu-latest
- if: always()
- steps:
- - name: Print deployment summary
- run: |
- echo "## Deployment Summary" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- if [ "${{ needs.deploy.result }}" = "success" ]; then
- echo "✅ All sites deployed successfully!" >> $GITHUB_STEP_SUMMARY
- else
- echo "❌ Deployment failed. Check the deploy jobs for details." >> $GITHUB_STEP_SUMMARY
- fi
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### Sites" >> $GITHUB_STEP_SUMMARY
- echo "| Site | URL |" >> $GITHUB_STEP_SUMMARY
- echo "|------|-----|" >> $GITHUB_STEP_SUMMARY
- echo "| hub | https://hub.moonweb.org |" >> $GITHUB_STEP_SUMMARY
- echo "| infra | https://infra.moonweb.org |" >> $GITHUB_STEP_SUMMARY
- echo "| smarthome | https://smarthome.moonweb.org |" >> $GITHUB_STEP_SUMMARY
- echo "| code | https://code.moonweb.org |" >> $GITHUB_STEP_SUMMARY
- echo "| retro | https://retro.moonweb.org |" >> $GITHUB_STEP_SUMMARY
-
-# Required repo secrets:
-# CLOUDFLARE_API_TOKEN — Cloudflare API token with Workers:Edit permission
-# CLOUDFLARE_ACCOUNT_ID — Cloudflare account ID
-#
-# Required one-time setup (see PLAN.md Phase 2):
-# Create Cloudflare Workers and bind custom domains.
-# DNS is already on Cloudflare (SPEC.md §4.6).
-#
diff --git a/AGENTS.md b/AGENTS.md
index f0ddc14..ec71fc6 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -1,18 +1,19 @@
# AGENTS.md — moonweb-site
-## Projektübersicht
+## Projektuebersicht
-Monorepo für 5 statische Websites unter moonweb.org + stefankoelle.de, basierend auf Eleventy (11ty).
+Monorepo fuer 6 statische Websites unter www.moonweb.org + stefankoelle.de, basierend auf Eleventy (11ty).
-### Websites (Cloudflare Pages)
+### Websites (IONOS SFTP)
-| Site | Domain | Zweck | Status |
-|------|--------|-------|--------|
-| hub | hub.moonweb.org | Zentrale Indexseite, verlinkt alles | Fertig |
-| infra | infra.moonweb.org | Infrastruktur-Übersicht (Proxmox, Synology, Netzwerk) | Übersicht + 3 Detailseiten |
-| smarthome | smarthome.moonweb.org | Smart Home Projekte und Dashboards | Übersicht + 6 Detailseiten |
-| code | code.moonweb.org | GitHub-Projekte (aggregiert via .moonweb.yml) | Fertig (14 Repos) |
-| retro | retro.moonweb.org | Physische Retro-Hardware | Nur Übersicht (WIP) |
+| Site | URL | Zweck | Status |
+|------|-----|-------|--------|
+| hub | www.moonweb.org/ | Zentrale Indexseite, verlinkt alles | Fertig |
+| infra | www.moonweb.org/infra/ | Infrastruktur-Uebersicht (Proxmox, Synology, Netzwerk) | Uebersicht + 8 Detailseiten |
+| smarthome | www.moonweb.org/smarthome/ | Smart Home Projekte und Dashboards | Uebersicht + 9 Detailseiten |
+| code | www.moonweb.org/code/ | GitHub-Projekte (aggregiert via .moonweb.yml) | Fertig |
+| retro | www.moonweb.org/retro/ | Physische Retro-Hardware | Uebersicht + 13 Detailseiten |
+| timecapsule | www.moonweb.org/timecapsule/ | 2000er Internet-Zeitkapsel (altes Design) | Fertig |
### Externe Sites (SFTP-Deployment)
@@ -22,19 +23,23 @@ Monorepo für 5 statische Websites unter moonweb.org + stefankoelle.de, basieren
### Andere Sites (nicht im Monorepo)
-- www.moonweb.org — 2000er Internet-Zeitkapsel
- 28k8.moonweb.org — 90er BBS/Scene-Archiv
+- buildbroken.moonweb.org — .NET Open Space Blog Archiv
## Dateistruktur
```
moonweb-site/
├── hub/ # Eleventy-Config + index.njk
-├── infra/ # Eleventy-Config + index.njk + 3 Subseiten
-├── smarthome/ # Eleventy-Config + index.njk + 6 Subseiten
+├── infra/ # Eleventy-Config + index.njk + 8 Subseiten
+├── smarthome/ # Eleventy-Config + index.njk + 9 Subseiten
├── code/ # Eleventy-Config + index.njk
│ └── _data/repos.json
-├── retro/ # Eleventy-Config + index.njk
+├── retro/ # Eleventy-Config + index.njk + 13 Subseiten
+├── timecapsule/ # Eleventy 2.x (eigene Config)
+│ ├── eleventy.config.js
+│ ├── package.json
+│ └── src/ # 2001er Retro-Content
├── stefankoelle/ # Eleventy-Config + Onepager
│ ├── eleventy.config.js
│ ├── _includes/
@@ -52,10 +57,11 @@ moonweb-site/
│ ├── base.css
│ └── theme-*.css
├── scripts/
-│ └── github-aggregator/
+│ ├── github-aggregator/
+│ └── merge-moonweb.sh # Merge-Skript fuer Deployment
├── .github/workflows/
-│ ├── build-deploy.yml # CI/CD: Cloudflare Pages (5 Sites)
-│ └── deploy-stefankoelle.yml # CI/CD: IONOS SFTP (stefankoelle.de)
+│ ├── build-deploy-moonweb.yml # CI/CD: IONOS SFTP (www.moonweb.org)
+│ └── deploy-stefankoelle.yml # CI/CD: IONOS SFTP (stefankoelle.de)
├── DESIGN.md
├── SPEC.md
├── PLAN.md
@@ -66,10 +72,11 @@ moonweb-site/
## Technischer Stack
-- **SSG:** Eleventy (11ty) v3.1.6
+- **SSG:** Eleventy (11ty) v3.1.6 (hub, infra, smarthome, code, retro)
+- **SSG:** Eleventy v2.0.1 (timecapsule - retro 2001 Design)
- **Templates:** Nunjucks (.njk)
- **CSS:** Variables-basiert mit Accent-Farben pro Site
-- **Deploy (moonweb):** Cloudflare Pages (5 separate Projects)
+- **Deploy (moonweb):** IONOS SFTP
- **Deploy (stefankoelle):** IONOS SFTP
- **CI/CD:** GitHub Actions (2 Workflows)
@@ -77,32 +84,54 @@ moonweb-site/
```bash
npm install
-npm run prebuild # Pre-Build Tasks (CV PDF generieren)
-npm run dev:hub # localhost:8081
-npm run dev:infra # localhost:8082
-npm run dev:smarthome # localhost:8083
-npm run dev:code # localhost:8084
-npm run dev:retro # localhost:8085
-npm run dev:stefankoelle # localhost:8086
-npm run build # Alle Sites bauen
+cd timecapsule && npm install # Timecapsule Dependencies
+npm run prebuild # Pre-Build Tasks (CV PDF generieren)
+npm run dev:hub # localhost:8081
+npm run dev:infra # localhost:8082
+npm run dev:smarthome # localhost:8083
+npm run dev:code # localhost:8084
+npm run dev:retro # localhost:8085
+npm run dev:stefankoelle # localhost:8086
+npm run dev:timecapsule # localhost:8087
+npm run build # Alle Sites bauen
+npm run build:moonweb # Nur moonweb Sites (ohne stefankoelle)
+npm run merge:moonweb # Sites mergen fuer Deployment
```
## Design-Prinzipien
1. **Header konsistent** — Identischer Site-Switcher auf allen Home-Sites
-2. **Content flexibel** — Detailseiten dürfen eigenes Layout haben
+2. **Content flexibel** — Detailseiten duerfen eigenes Layout haben
3. **Accent-Farben:** hub=#3b6ea5, infra=#99333A, smarthome=#1f8a8a, code=#3E5098, retro=#8a6d3b
4. **Englisch** — Alle Sites komplett auf Englisch
5. **Keine Analytics** — Keine Tracking-Tools
-6. **Sensible Daten** — Infra-Content wird manuell redigiert (keine IPs, Keys, Passwörter)
+6. **Sensible Daten** — Infra-Content wird manuell redigiert (keine IPs, Keys, Passwoerter)
+
+## URL-Struktur
+
+Alle Sites sind unter `www.moonweb.org` als Subverzeichnisse erreichbar:
+- `www.moonweb.org/` — Hub (Root)
+- `www.moonweb.org/infra/` — Infra
+- `www.moonweb.org/smarthome/` — Smarthome
+- `www.moonweb.org/code/` — Code
+- `www.moonweb.org/retro/` — Retro
+- `www.moonweb.org/timecapsule/` — Timecapsule (2001 Design)
+- `www.moonweb.org/impressum/` — Impressum
+
+Cloudflare Redirects leiten alte Subdomains weiter:
+- `hub.moonweb.org/*` → `www.moonweb.org/*`
+- `infra.moonweb.org/*` → `www.moonweb.org/infra/*`
+- `smarthome.moonweb.org/*` → `www.moonweb.org/smarthome/*`
+- `code.moonweb.org/*` → `www.moonweb.org/code/*`
+- `retro.moonweb.org/*` → `www.moonweb.org/retro/*`
## stefankoelle.de
- Eigene Eleventy-Config (nicht shared base.njk)
- Eigenes CSS-Design (nicht moonweb design system)
- Onepager mit Anchor-Links (bleibt so)
-- Deploy via SFTP auf IONOS `/deploy/stefankoelle/`
-- CV-Partial zentral pflegbar (einmal aendern → Web + PDF aktualisieren)
+- Deploy via SFTP auf IONOS `/websites/stefankoelle/`
+- CV-Partial zentral pflegbar (einmal aendern -> Web + PDF aktualisieren)
- LED Matrix als eigene Seite unter stefankoelle.de/ledmatrix/
### CV PDF Generierung
@@ -116,7 +145,7 @@ npm run prebuild # Alle Pre-Build Tasks (inkl. CV PDF)
Dateien:
- `stefankoelle/pdf/cv-style.css` — WeasyPrint-Stylesheet (A4, Typografie)
-- `stefankoelle/pdf/build-pdf.sh` — Shell-Skript für PDF-Generierung
+- `stefankoelle/pdf/build-pdf.sh` — Shell-Skript fuer PDF-Generierung
- `stefankoelle/cv-print.njk` — Standalone HTML-Template (nur CV-Content)
- `stefankoelle/pdf/cv.pdf` — Generiertes PDF (Output)
@@ -124,21 +153,22 @@ Wichtig: Das PDF wird via Eleventy-Passthrough ins Build-Output kopiert (`dist/s
### CSS Cache-Busting
-CSS-Dateien werden als Passthrough kopiert (kein Hash im Dateinamen). Bei CSS-Änderungen muss der Query-String in der `?v=N` Inkludierung erhöht werden:
+CSS-Dateien werden als Passthrough kopiert (kein Hash im Dateinamen). Bei CSS-Aenderungen muss der Query-String in der `?v=N` Inkludierung erhoeht werden:
- `stefankoelle/index.njk`: ``
- `stefankoelle/ledmatrix/index.njk`: ``
-Bei jeder CSS-Anpassung `?v=N` um 1 erhöhen, sonst cached der Browser die alte Datei.
+Bei jeder CSS-Anpassung `?v=N` um 1 erhoehen, sonst cached der Browser die alte Datei.
## CI/CD
-### Cloudflare Pages (moonweb)
-`.github/workflows/build-deploy.yml` baut hub, infra, smarthome, code, retro.
+### IONOS SFTP (www.moonweb.org)
+`.github/workflows/build-deploy-moonweb.yml` baut alle moonweb Sites (hub, infra, smarthome, code, retro, timecapsule) und deployed per SFTP.
Benötigte Secrets:
-- `CLOUDFLARE_API_TOKEN`
-- `CLOUDFLARE_ACCOUNT_ID`
+- `IONOS_SFTP_HOST`
+- `IONOS_SFTP_USER`
+- `IONOS_SFTP_PASSWORD`
### IONOS SFTP (stefankoelle.de)
`.github/workflows/deploy-stefankoelle.yml` baut stefankoelle.de und deployed per SFTP.
@@ -150,9 +180,11 @@ Benötigte Secrets:
## Offene Punkte
-- retro/ ist bewusst rudimentär gehalten
+- retro/ ist bewusst rudimentaer gehalten
- Querverlinkungen stefankoelle.de <-> smarthome (zukuenftig)
- Ledmatrix ggf. nach smarthome verschieben (when ready)
+- Cloudflare Redirects einrichten (nach Deploy)
+- Google Search Console: Neue Property www.moonweb.org
## GitHub Aggregator
@@ -191,10 +223,10 @@ python3 -m venv .venv
## Text / Stil
-- Keine Em-Dashes (—) verwenden, stattdessen umformulieren (Komma, Satzzeichen, neu formulieren)
+- Keine Em-Dashes verwenden, stattdessen umformulieren (Komma, Satzzeichen, neu formulieren)
## Python / pip
-- Niemals `pip install` direkt ausführen
+- Niemals `pip install` direkt ausfuehren
- Immer ein virtuelles Umfeld (`.venv`) anlegen und darin arbeiten
- `python3 -m venv .venv` im Projektverzeichnis
diff --git a/README.md b/README.md
index d513416..16260cb 100755
--- a/README.md
+++ b/README.md
@@ -1,88 +1,67 @@
-# 🌙 moonweb-site
+# moonweb-site
-Monorepo for the **moonweb.org** homelab — five static sites built with [Eleventy](https://www.11ty.dev/), deployed to [Cloudflare Pages](https://pages.cloudflare.com/).
+Monorepo for the **moonweb.org** homelab — six static sites built with [Eleventy](https://www.11ty.dev/), deployed to [IONOS SFTP](https://www.ionos.de/).
```
-hub.moonweb.org → 🏠 Central index & gateway
-infra.moonweb.org → 🏗️ Infrastructure overview (Proxmox, Synology, Docker)
-smarthome.moonweb.org → 🏡 Smart home projects & dashboards
-code.moonweb.org → 💻 Curated GitHub project catalog
-retro.moonweb.org → 🕹️ Physical retro hardware collection
-stefankoelle.de → 👤 CV, career, personal site (LED Matrix docs)
+www.moonweb.org/ -> Central index & gateway
+www.moonweb.org/infra/ -> Infrastructure overview (Proxmox, Synology, Docker)
+www.moonweb.org/smarthome/ -> Smart home projects & dashboards
+www.moonweb.org/code/ -> Curated GitHub project catalog
+www.moonweb.org/retro/ -> Physical retro hardware collection
+www.moonweb.org/timecapsule/ -> 2000s internet time capsule (retro design)
+stefankoelle.de -> CV, career, personal site (LED Matrix docs)
```
-> **Other sites** (not in this monorepo): [www.moonweb.org](https://www.moonweb.org) (2000s time capsule), [28k8.moonweb.org](https://28k8.moonweb.org) (90s BBS archive).
+> **Other sites** (not in this monorepo): [28k8.moonweb.org](https://28k8.moonweb.org) (90s BBS archive), [buildbroken.moonweb.org](https://buildbroken.moonweb.org) (.NET Open Space blog).
---
-## 📐 Architecture
+## Architecture
```
-┌─────────────────────────────────────────────────────────────┐
-│ GitHub Actions CI │
-│ ┌───────────┐ ┌────────────┐ ┌─────────────┐ ┌─────────┐ │
-│ │ build:hub │ │build:infra │ │ build:smart │ │ build:… │ │
-│ └─────┬─────┘ └─────┬──────┘ └──────┬──────┘ └────┬────┘ │
-│ │ │ │ │ │
-│ ▼ ▼ ▼ ▼ │
-│ dist/hub/ dist/infra/ dist/smarthome/ dist/…/ │
-└────────┬───────────────────────────────────────────┬────────┘
- │ │
- ▼ ▼
-┌──────────────────┐ ┌─────────────────┐
-│ Cloudflare Pages │ │ IONOS SFTP │
-│ (5 sites) │ │ (stefankoelle) │
-└────────┬─────────┘ └────────┬────────┘
- ▼ ▼
- hub / infra / ... stefankoelle.de
++-------------------------------------------------------------------+
+| GitHub Actions CI |
+| +-----------+ +------------+ +-------------+ +---------+ +------+ |
+| | build:hub | |build:infra | | build:smart | | build:... | | build:timecapsule | |
+| +-----+-----+ +-----+------+ +------+------+ +----+----+ +----+----+ +--------+ |
+| | | | | | | |
+| v v v v v v |
+| dist/hub/ dist/infra/ dist/smarthome/ dist/.../ dist/timecapsule/ |
++--------+---------------------------------------------------+--------------------+
+ | |
+ v v
++------------------+ +------------------+
+| IONOS SFTP | | IONOS SFTP |
+| (www.moonweb.org)| | (stefankoelle.de)|
++--------+---------+ +--------+---------+
+ v v
+ www.moonweb.org/* stefankoelle.de
```
---
-## 🛠️ Tech Stack
+## Tech Stack
| Layer | Technology | Why |
|-------|-----------|-----|
-| **SSG** | [Eleventy 3.1.6](https://www.11ty.dev/) | Markdown/YAML-first, minimal JS, `_data` folders map directly to aggregator output, low maintenance for 5 sites |
+| **SSG** | [Eleventy 3.1.6](https://www.11ty.dev/) | Markdown/YAML-first, minimal JS, `_data` folders map directly to aggregator output |
+| **SSG (timecapsule)** | [Eleventy 2.0.1](https://www.11ty.dev/) | Legacy 2001 design, CommonJS config |
| **Templates** | [Nunjucks](https://mozilla.github.io/nunjucks/) | Shared `base.njk` layout with site-switcher header, `card-grid.njk` for index pages |
-| **Styling** | Custom CSS (variables-based) | `base.css` for shared layout, `theme-*.css` per domain accent color, no build step needed |
+| **Styling** | Custom CSS (variables-based) | `base.css` for shared layout, `theme-*.css` per domain accent color |
| **Fonts** | [Lobster](https://fonts.google.com/specimen/Lobster) (Google Fonts) | Distinctive heading font across all sites |
-| **CI/CD** | [GitHub Actions](https://github.com/features/actions) | Matrix build for all 5 sites, artifact upload, parallel deploy |
-| **Deploy** | [Cloudflare Workers](https://workers.cloudflare.com/) | Static asset hosting via `wrangler pages deploy`, one worker per site |
-| **DNS** | Cloudflare | Already managing DNS — zero additional setup for Pages custom domains |
+| **CI/CD** | [GitHub Actions](https://github.com/features/actions) | Matrix build for all sites, artifact upload, merge step, parallel deploy |
+| **Deploy** | IONOS SFTP | Static hosting via SFTP upload |
+| **DNS** | Cloudflare | DNS management + redirects from old subdomains |
| **GitHub Catalog** | Python aggregator | Reads `.moonweb.yml` from each repo, outputs `repos.json` |
-| **Runtime** | Fully static | No server-side code, no containers, no database — pure HTML/CSS/JS |
+| **Runtime** | Fully static | No server-side code, no containers, no database |
---
-## 🎨 Design System
-
-### Header-consistent, content-flexible
-
-- **Header is identical** across all home-section sites: site-switcher (hub · infra · smarthome · code · retro · cv), domain accent color, Lobster title font.
-- **Index pages** use a shared card-grid layout with grouped sections.
-- **Detail pages** keep the same header but use a freer layout below it (e.g., pin tables, API docs, photos in free arrangement).
-
-### Accent colors
-
-| Domain | Color | Hex |
-|--------|-------|-----|
-| hub | Neutral blue | `#3b6ea5` |
-| infra | Grey-blue | `#99333A` |
-| smarthome | Teal | `#1f8a8a` |
-| code | Violet | `#3E5098` |
-| retro | Warm brown | `#8a6d3b` |
-
-### Emojis
-
-Each card on index pages has an emoji for visual navigation — consistent across hub, infra, smarthome, code, and retro.
-
----
-
-## 🚀 Local Development
+## Local Development
```bash
npm install # install Eleventy + deps
+cd timecapsule && npm install # timecapsule has own deps (Eleventy 2.x)
npm run dev:hub # http://localhost:8081
npm run dev:infra # http://localhost:8082
@@ -90,8 +69,9 @@ npm run dev:smarthome # http://localhost:8083
npm run dev:code # http://localhost:8084
npm run dev:retro # http://localhost:8085
npm run dev:stefankoelle # http://localhost:8086
+npm run dev:timecapsule # http://localhost:8087
-npm run dev # all 6 in parallel
+npm run dev # all 7 in parallel
```
Each site has its own minimal Eleventy config (`/eleventy.config.js`). Live reload is built in.
@@ -100,83 +80,96 @@ Each site has its own minimal Eleventy config (`/eleventy.config.js`). Liv
```bash
npm run prebuild # pre-build tasks (CV PDF)
-npm run build # builds all 5 → dist//
+npm run build # builds all sites
+npm run build:moonweb # builds moonweb sites only (excludes stefankoelle)
npm run build:hub # build single site
+npm run merge:moonweb # merge all moonweb sites into dist/ for deployment
```
---
-## 📦 Project Structure
+## Project Structure
```
moonweb-site/
-├── hub/ # 🏠 Central index & gateway
-├── infra/ # 🏗️ Infra overview + 3 detail pages
+├── hub/ # Central index & gateway
+├── infra/ # Infra overview + 8 detail pages
│ ├── backup-strategy/
│ ├── monitoring/
-│ └── dev-environment/
-├── smarthome/ # 🏡 Smart home overview + 6 detail pages
+│ ├── dev-environment/
+│ └── ...
+├── smarthome/ # Smart home overview + 9 detail pages
│ ├── homematic-mqtt/
│ ├── tasmota-energy/
-│ ├── balkonpi/
-│ ├── airplay-audio/
-│ ├── octoprint/
-│ └── tubearchivist/
-├── code/ # 💻 GitHub catalog
+│ └── ...
+├── code/ # GitHub catalog
│ └── _data/repos.json # populated by the aggregator
-├── retro/ # 🕹️ Retro hardware (WIP)
-├── stefankoelle/ # 👤 CV, career, personal site
+├── retro/ # Retro hardware + 13 detail pages
+├── timecapsule/ # 2000s retro design (Eleventy 2.x)
+│ ├── eleventy.config.js
+│ ├── package.json
+│ └── src/
+├── stefankoelle/ # CV, career, personal site
│ ├── eleventy.config.js
│ ├── index.njk # Onepager (CV, Projects, Languages)
│ ├── cv-print.njk # CV-only for PDF generation
│ ├── ledmatrix/ # LED Matrix WebServer documentation
│ └── assets/ # CSS, JS, images, favicons
-├── shared/ # 🔧 Shared components
+├── shared/ # Shared components
│ ├── _includes/
│ │ ├── base.njk # base layout (header, site-switcher, footer)
│ │ └── card-grid.njk # card-grid template with emoji support
│ ├── base.css # shared CSS (layout, cards, typography)
│ └── theme-*.css # accent colors per domain
├── scripts/
-│ └── github-aggregator/ # 🐍 Python: reads .moonweb.yml → repos.json
-│ ├── aggregate.py
-│ ├── example.moonweb.yml
-│ └── README.md
+│ ├── github-aggregator/ # Python: reads .moonweb.yml -> repos.json
+│ └── merge-moonweb.sh # Merge script for deployment
├── .github/workflows/
-│ └── build-deploy.yml # ⚙️ CI/CD: build + deploy to Cloudflare
-├── DESIGN.md # 📋 Initial concept (German)
-├── SPEC.md # 📋 Full specification (English, 159 lines)
-├── PLAN.md # 📋 Implementation plan
-├── TODO.md # 📋 Open items & workflow
+│ ├── build-deploy-moonweb.yml # CI/CD: build + deploy to IONOS SFTP
+│ └── deploy-stefankoelle.yml # CI/CD: stefankoelle.de to IONOS SFTP
+├── DESIGN.md # Initial concept
+├── SPEC.md # Full specification
+├── PLAN.md # Implementation plan
+├── TODO.md # Open items & workflow
└── package.json # npm scripts for dev/build
```
---
-## 🔄 CI/CD Pipeline
+## CI/CD Pipeline
-### Cloudflare Pages (moonweb sites)
+### IONOS SFTP (www.moonweb.org)
-Defined in `.github/workflows/build-deploy.yml`:
+Defined in `.github/workflows/build-deploy-moonweb.yml`:
```
push to main
- │
- ├── Build (matrix: hub, infra, smarthome, code, retro)
- │ ├── checkout → setup-node (22) → npm ci
- │ ├── npm run build:
- │ ├── validate dist// exists & non-empty
- │ └── upload artifact (7-day retention)
- │
- └── Deploy (matrix: 5 Cloudflare Workers)
- ├── download artifact
- ├── generate wrangler.toml
- └── wrangler pages deploy
+ |
+ +-- Build (matrix: hub, infra, smarthome, code, retro)
+ | +-- checkout -> setup-node (22) -> npm ci
+ | +-- npm run build:
+ | +-- validate dist// exists & non-empty
+ | +-- upload artifact (7-day retention)
+ |
+ +-- Build timecapsule
+ | +-- cd timecapsule && npm ci
+ | +-- npm run build:timecapsule
+ | +-- upload artifact
+ |
+ +-- Merge
+ | +-- download all artifacts
+ | +-- merge into dist/ (hub=root, others=subdirs)
+ | +-- upload merged artifact
+ |
+ +-- Deploy
+ +-- download merged artifact
+ +-- SFTP upload to IONOS /websites/moonweb/
```
**Required secrets:**
-- `CLOUDFLARE_API_TOKEN` — Workers:Edit permission
-- `CLOUDFLARE_ACCOUNT_ID` — Cloudflare account ID
+- `IONOS_SFTP_HOST`
+- `IONOS_SFTP_USER`
+- `IONOS_SFTP_PASSWORD`
### IONOS SFTP (stefankoelle.de)
@@ -184,12 +177,12 @@ Defined in `.github/workflows/deploy-stefankoelle.yml`:
```
push to main (paths: stefankoelle/**)
- │
- ├── Build stefankoelle
- │ └── npm run build:stefankoelle
- │
- └── Deploy via SFTP
- └── lftp mirror → IONOS /deploy/stefankoelle/
+ |
+ +-- Build stefankoelle
+ | +-- npm run build:stefankoelle
+ |
+ +-- Deploy via SFTP
+ +-- SFTP upload to IONOS /websites/stefankoelle/
```
**Required secrets:**
@@ -199,7 +192,30 @@ push to main (paths: stefankoelle/**)
---
-## 🐍 GitHub Aggregator (code.moonweb.org)
+## URL Structure
+
+All moonweb.org sites are accessible under `www.moonweb.org` as subdirectories:
+
+| URL | Content |
+|-----|---------|
+| `www.moonweb.org/` | Hub (root) |
+| `www.moonweb.org/infra/` | Infrastructure |
+| `www.moonweb.org/smarthome/` | Smart Home |
+| `www.moonweb.org/code/` | Code catalog |
+| `www.moonweb.org/retro/` | Retro hardware |
+| `www.moonweb.org/timecapsule/` | 2000s time capsule |
+| `www.moonweb.org/impressum/` | Legal notice |
+
+Cloudflare redirects forward old subdomains:
+- `hub.moonweb.org/*` -> `www.moonweb.org/*`
+- `infra.moonweb.org/*` -> `www.moonweb.org/infra/*`
+- `smarthome.moonweb.org/*` -> `www.moonweb.org/smarthome/*`
+- `code.moonweb.org/*` -> `www.moonweb.org/code/*`
+- `retro.moonweb.org/*` -> `www.moonweb.org/retro/*`
+
+---
+
+## GitHub Aggregator (www.moonweb.org/code/)
`scripts/github-aggregator/aggregate.py` automatically builds the project catalog:
@@ -214,7 +230,7 @@ push to main (paths: stefankoelle/**)
```yaml
title: "MVG Departures"
category: code # code | smarthome | infra
-subcategory: "Web Apps" # drives grouping on code.moonweb.org
+subcategory: "Web Apps" # drives grouping on www.moonweb.org/code/
status: active
stack: [Python, FastAPI]
hosted_on: "Docker Host Debian (PVE)"
@@ -229,42 +245,41 @@ export GITHUB_TOKEN=ghp_xxx
python scripts/github-aggregator/aggregate.py
```
-> **Deliberately manual** — no scheduled CI job. The catalog is refreshed on demand, not on every push.
-
---
-## 📏 Content Rules
+## Content Rules
| Site | Detail pages? | Rule |
|------|--------------|------|
-| smarthome | ✅ Yes | When enough content exists — no placeholder cards |
-| infra | ⚠️ Rarely | Deliberately shallow — sensitive data (IPs, keys, passwords) stripped |
-| code | ❌ Never | Overview cards + GitHub links only — no README duplication |
-| retro | 🔨 Minimal | Still WIP — honest minimal overview, no over-investment |
+| smarthome | Yes | When enough content exists - no placeholder cards |
+| infra | Rarely | Deliberately shallow - sensitive data (IPs, keys, passwords) stripped |
+| code | Never | Overview cards + GitHub links only - no README duplication |
+| retro | Minimal | Honest minimal overview, no over-investment |
+| timecapsule | Static | 1:1 migration of original 2001 design, no changes |
**Infra redaction rule:** Architecture-level only (Proxmox, Synology, Docker, VLAN concept). No concrete IPs, WireGuard keys, passwords, internal hostnames.
---
-## 🌍 Language
+## Language
-All five sites are written **entirely in English**. German source documents are translated once during migration (AI-assisted). New content is authored in English from the start.
+All moonweb sites are written **entirely in English**. The timecapsule uses the original 2001 English content.
---
-## 📚 Documentation
+## Documentation
| File | Purpose |
|------|---------|
-| `DESIGN.md` | Initial concept and design decisions (German) |
-| `SPEC.md` | Complete specification — what gets built (English) |
+| `DESIGN.md` | Initial concept and design decisions |
+| `SPEC.md` | Complete specification - what gets built |
| `PLAN.md` | Phased implementation plan |
| `TODO.md` | Open items, workflow, and current status |
-| `README.md` | This file — project overview for GitHub |
+| `README.md` | This file - project overview for GitHub |
---
-## 📄 License
+## License
[](https://creativecommons.org/licenses/by-nc-sa/4.0/)
diff --git a/TODO.md b/TODO.md
index 49f8433..95ae694 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,76 +1,84 @@
-# TODO — moonweb-site Offene Items
+# TODO: Consolidation zu www.moonweb.org
-Stand: 2026-08-14
+## Uebersicht
-## Aktueller Status
+Alle moonweb.org Sites (hub, infra, smarthome, code, retro, timecapsule) unter `www.moonweb.org` als Subverzeichnisse vereinen. Deployment von Cloudflare Pages zu IONOS SFTP migrieren.
-| Phase | Status | Bemerkung |
-|-------|--------|-----------|
-| Phase 0 — Repo & Tooling | ✅ fertig | Eleventy 3.1.6, CI/CD, .gitignore erweitert |
-| Phase 1 — Content | ✅ fertig | hub, code, infra, smarthome komplett, retro bewusst rudimentär |
-| Phase 2 — CI/CD | ✅ fertig | build-deploy.yml mit Caching + Validation + Summary |
-| Phase 3 — Launch | ✅ fertig | Cloudflare Pages live, Smoke-Test bestanden |
-| Phase 4 — Deferred | ⏸️ zurückgestellt | 28k8, Analytics |
-| Phase 5 — stefankoelle.de | ✅ fertig | Ins Monorepo migriert, Eleventy-Build, SFTP-Deployment |
+**URL-Struktur nach Migration:**
+| URL | Inhalt |
+|-----|--------|
+| `www.moonweb.org/` | Hub (neue Root) |
+| `www.moonweb.org/infra/` | Infra |
+| `www.moonweb.org/smarthome/` | Smarthome |
+| `www.moonweb.org/code/` | Code |
+| `www.moonweb.org/retro/` | Retro |
+| `www.moonweb.org/timecapsule/` | Altes www (2001-Retro) |
+| `stefankoelle.de/` | CV (bleibt separat) |
-## Offene Items
+---
-### P4 — Deferred (nicht dringend)
+## Phase 1: Timecapsule in Monorepo integrieren
-- [ ] 28k8.moonweb.org Zukunft klären
-- [ ] Perplexity-Rückkanal
-- [ ] Apex-Domain Redirect (moonweb.org → hub.moonweb.org)
-- [ ] PDF-Build fuer CV (WeasyPrint, lokal testen)
-- [ ] Querverlinkungen stefankoelle.de <-> smarthome
-- [ ] Ledmatrix ggf. nach smarthome verschieben
-- [ ] **Dotnet Home-Automation-Projekt beschreiben** — Interne .NET Core Software für Kommunikation auf buttons.html und InfluxDB. Code muss erst aufgeraeumt und nach GitHub publiziert werden, dann Beschreibung auf stefankoelle.de und ggf. smarthome ergänzen.
+- [x] 1.1 Dateien aus ../moonweb-www/src/ nach timecapsule/src/ kopieren
+- [x] 1.2 timecapsule/eleventy.config.js erstellen (Eleventy 2.x)
+- [x] 1.3 timecapsule/package.json erstellen (eigene Dependencies)
+- [x] 1.4 timecapsule/src/_data/site.json anpassen (Domain mit /timecapsule/)
+- [x] 1.5 Alle internen Pfade mit /timecapsule/ prefixieren
+- [x] 1.6 Passthrough Copy in eleventy.config.js anpassen
+- [x] 1.7 Build-Output pruefen (dist/timecapsule/)
-### Offene Entscheidungen
+## Phase 2: Eleventy-Configs aller Sites anpassen
-- [ ] **stefankoelle.de SFTP: `delete_remote_files`?** — Derzeit werden beim Deploy nur Dateien hochgeloaden, alte bleiben liegen. Mit `delete_remote_files: true` waere jeder Deploy ein sauberes Image (alles weg + neu). Kurzer Ausfall moeglich. Entscheidung offen.
+- [x] 2.1 hub/eleventy.config.js: site.url auf www.moonweb.org
+- [x] 2.2 infra/eleventy.config.js: site.url auf www.moonweb.org
+- [x] 2.3 smarthome/eleventy.config.js: site.url auf www.moonweb.org
+- [x] 2.4 code/eleventy.config.js: site.url auf www.moonweb.org
+- [x] 2.5 retro/eleventy.config.js: site.url auf www.moonweb.org
+- [x] 2.6 shared/_includes/base.njk anpassen
+- [x] 2.7 hub/index.njk: Card-Hrefs relativieren
+- [x] 2.8 hub/impressum.njk: Domain-Liste aktualisieren
-## Schon erledigt (Stand 2026-08-14)
+## Phase 3: Build-System anpassen
-### stefankoelle.de Migration (2026-08-14)
-- [x] Eleventy-Config + package.json erweitert
-- [x] Onepager-Layout mit Anchor-Links beibehalten
-- [x] CV-Partial (zentral fuer Web + PDF)
-- [x] CSS ausgelagert + modernisiert (Custom Properties, box-sizing)
-- [x] Assets in assets/ verschoben
-- [x] Ledmatrix als eigene Seite integriert
-- [x] Alte Dateien geloescht (index.html, browserconfig.xml, sitemap.txt)
-- [x] Deployment-Workflow fuer IONOS SFTP
-- [x] Cloudflare-Workflow um stefankoelle erweitert (paths-ignore)
+- [x] 3.1 package.json: Neue Scripts fuer timecapsule + merge
+- [x] 3.2 scripts/merge-moonweb.sh erstellen
+- [x] 3.3 Lokal Build testen (alle Sites)
-### Vorherige Erledigungen (Stand 2026-08-13)
-- [x] Impressum angelegt + Footer-Link auf allen Sites
-- [x] Favicons (SVG mit Emojis) pro Subdomain — `shared/favicon/*.svg`, per Passthrough Copy
-- [x] Meta descriptions auf allen 33 Seiten
-- [x] CSS @import-Kette bereinigt (kein Render-Blocking mehr)
-- [x] .gitignore erweitert (.env*, Zertifikate, Swap-Files)
-- [x] Placeholder-Cards `"#"` bereinigt — keine mehr vorhanden
-- [x] README.md überarbeitet (Emojis, Architektur, Tech-Stack, CI/CD)
-- [x] Lizenz hinzugefügt (CC BY-NC-SA 4.0)
-- [x] Content-Review — alle Seiten geprüft, alles passt
-- [x] Cloudflare Pages Projects erstellt (moonweb-hub, -infra, -smarthome, -code, -retro)
-- [x] DNS & Custom Domains gebunden
-- [x] Secrets konfiguriert (CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID)
-- [x] Smoke-Test Cross-Linking — alles funktioniert auf live
+## Phase 4: Deployment umstellen
-## Workflow für neue Contexts
+- [x] 4.1 Neuen Workflow .github/workflows/build-deploy-moonweb.yml erstellen
+- [x] 4.2 Alten Workflow .github/workflows/build-deploy.yml entfernen
+- [ ] 4.3 Alten deploy-moonweb.yml in moonweb-www deaktivieren
-Wenn du einen neuen Context öffnest, lies diese Datei und prüfe:
-1. Welche P4-Items sind relevant? → Nur wenn angefordert
+## Phase 5: Cloudflare Redirects (manuell nach Deploy)
-## Definition of done
+- [ ] 5.1 Redirect-Regeln einrichten:
-Alle 5 Sites live auf Cloudflare Pages:
-- ✅ hub.moonweb.org — verlinkt alles (+ stefankoelle.de extern)
-- ✅ code.moonweb.org — GitHub-Katalog via Aggregator
-- ✅ smarthome.moonweb.org — Smart Home Übersicht + Detailseiten
-- ✅ infra.moonweb.org — Infra-Übersicht (redigiert)
-- ✅ retro.moonweb.org — Ehrliche minimale Übersicht (WIP)
+| Quell-Domain | Ziel-URL | Type |
+|-------------|----------|------|
+| `hub.moonweb.org/*` | `https://www.moonweb.org/$1` | 301 |
+| `infra.moonweb.org/*` | `https://www.moonweb.org/infra/$1` | 301 |
+| `smarthome.moonweb.org/*` | `https://www.moonweb.org/smarthome/$1` | 301 |
+| `code.moonweb.org/*` | `https://www.moonweb.org/code/$1` | 301 |
+| `retro.moonweb.org/*` | `https://www.moonweb.org/retro/$1` | 301 |
-stefankoelle.de live auf IONOS (SFTP-Deployment):
-- ✅ stefankoelle.de — Onepager mit CV, Projects, Languages, Impressum
-- ✅ stefankoelle.de/ledmatrix/ — LED Matrix WebServer Dokumentation
+## Phase 6: SEO
+
+- [ ] 6.1 Google Search Console: Neue Property www.moonweb.org
+- [ ] 6.2 Sitemap submiten
+
+## Phase 7: Cleanup
+
+- [ ] 7.1 moonweb-www Repository archivieren
+- [ ] 7.2 Cloudflare Pages Projects loeschen (nach Redirect-Test)
+
+---
+
+## Abgeschlossen
+
+Alle Code-Aenderungen sind fertig. Nächste Schritte:
+1. Commit auf feature/consolidate-www Branch
+2. Push und PR erstellen
+3. Deployen
+4. Cloudflare Redirects einrichten
+5. Google Search Console aktualisieren
diff --git a/code/eleventy.config.js b/code/eleventy.config.js
index ae9fb63..8b6d6a1 100644
--- a/code/eleventy.config.js
+++ b/code/eleventy.config.js
@@ -1,5 +1,5 @@
module.exports = function (eleventyConfig) {
- eleventyConfig.addGlobalData("site", { url: "https://code.moonweb.org" });
+ eleventyConfig.addGlobalData("site", { url: "https://www.moonweb.org" });
eleventyConfig.addFilter("date", (d) => d.toISOString());
eleventyConfig.addPassthroughCopy({ "shared/theme-code.css": "theme.css" });
eleventyConfig.addPassthroughCopy({ "shared/base.css": "shared-base.css" });
diff --git a/hub/eleventy.config.js b/hub/eleventy.config.js
index 73d8732..99a5a20 100644
--- a/hub/eleventy.config.js
+++ b/hub/eleventy.config.js
@@ -1,5 +1,5 @@
module.exports = function (eleventyConfig) {
- eleventyConfig.addGlobalData("site", { url: "https://hub.moonweb.org" });
+ eleventyConfig.addGlobalData("site", { url: "https://www.moonweb.org" });
eleventyConfig.addFilter("date", (d) => d.toISOString());
eleventyConfig.addPassthroughCopy({ "shared/theme-hub.css": "theme.css" });
eleventyConfig.addPassthroughCopy({ "shared/base.css": "shared-base.css" });
diff --git a/hub/impressum.njk b/hub/impressum.njk
index 11a95c2..7ef4836 100644
--- a/hub/impressum.njk
+++ b/hub/impressum.njk
@@ -19,7 +19,7 @@ layout: base.njk
- Scope of this legal notice: This legal notice and the privacy policy below apply to the following websites, all operated by Stefan Kölle: hub.moonweb.org, smarthome.moonweb.org, infra.moonweb.org, code.moonweb.org, retro.moonweb.org, buildbroken.moonweb.org, 28k8.moonweb.org, www.moonweb.org, and stefankoelle.de. All of these sites are part of the same personal project network and are covered jointly by this single document.
+ Scope of this legal notice: This legal notice and the privacy policy below apply to the following websites, all operated by Stefan Kölle: www.moonweb.org (including /infra/, /smarthome/, /code/, /retro/, /timecapsule/), buildbroken.moonweb.org, 28k8.moonweb.org, and stefankoelle.de. All of these sites are part of the same personal project network and are covered jointly by this single document.
@@ -41,7 +41,7 @@ layout: base.njk
2. Purpose of these Websites
- The moonweb.org subdomains (hub, smarthome, infra, code, retro) document my private home-lab, home-automation and retro-computing hobby projects. buildbroken.moonweb.org is an archive of a blog I created with friends in our spare time. 28k8.moonweb.org is a homage to the 90s era. www.moonweb.org is an archived version of my original website from 2001. stefankoelle.de presents my professional CV and background as the same person. All are part of one personal project network and share this legal notice and privacy policy.
+ The moonweb.org websites (hub, smarthome, infra, code, retro, timecapsule) document my private home-lab, home-automation and retro-computing hobby projects. buildbroken.moonweb.org is an archive of a blog I created with friends in our spare time. 28k8.moonweb.org is a homage to the 90s era. stefankoelle.de presents my professional CV and background as the same person. All are part of one personal project network and share this legal notice and privacy policy.
3. Hosting
@@ -49,19 +49,17 @@ layout: base.njk
Two different hosting providers are used within this network:
-
- Hosted via Cloudflare Pages, operated by Cloudflare, Inc., 101 Townsend St, San Francisco, CA 94107, USA. Cloudflare processes connection-level data (e.g. your IP address, request headers) as part of its content delivery and DDoS/security systems. This is governed by Cloudflare's Data Processing Addendum, which incorporates the EU Standard Contractual Clauses (2021) as a safeguard for the transfer of data to the USA. See cloudflare.com/privacypolicy.
-
-
-
b) www.moonweb.org and stefankoelle.de — IONOS SE
+
a) www.moonweb.org (hub, smarthome, infra, code, retro, timecapsule) — IONOS SE
Hosted on web space provided by IONOS SE, Elgendorfer Str. 57, 56410 Montabaur, Germany, acting as a processor under Art. 28 GDPR (Data Processing Agreement in place).
+
b) stefankoelle.de, buildbroken.moonweb.org, 28k8.moonweb.org — IONOS SE
- Legal basis for both: Art. 6(1)(f) GDPR (legitimate interest in reliable, secure delivery of the websites).
-
+ Hosted on web space provided by IONOS SE, Elgendorfer Str. 57, 56410 Montabaur, Germany, acting as a processor under Art. 28 GDPR (Data Processing Agreement in place).
+
+
+
Legal basis for both: Art. 6(1)(f) GDPR (legitimate interest in reliable, secure delivery of the websites).
4. No Tracking, No Cookies, No Analytics (current state)
diff --git a/hub/index.njk b/hub/index.njk
index 75291b4..f484fc4 100644
--- a/hub/index.njk
+++ b/hub/index.njk
@@ -9,19 +9,19 @@ sections:
cards:
- title: "infra"
summary: "Stack overview: Proxmox, Synology, network, backups, and how I work."
- href: "https://infra.moonweb.org"
+ href: "/infra/"
emoji: "🏗️"
- title: "smarthome"
summary: "What's actually running on the homelab, and why."
- href: "https://smarthome.moonweb.org"
+ href: "/smarthome/"
emoji: "🏠"
- title: "code"
summary: "Curated catalog of my GitHub projects."
- href: "https://code.moonweb.org"
+ href: "/code/"
emoji: "💻"
- title: "retro"
summary: "Physical retro hardware collection."
- href: "https://retro.moonweb.org"
+ href: "/retro/"
emoji: "🕹️"
- heading: "About me"
cards:
@@ -37,7 +37,7 @@ sections:
emoji: "💾"
- title: "www.moonweb.org"
summary: "The 2000s internet projects, networking and engineering."
- href: "https://www.moonweb.org"
+ href: "/timecapsule/"
emoji: "🌐"
- title: "inseco.de"
summary: "Internet services & consulting for gastronomy and clubs, Peak 2003–2008. Custom PHP/CMS."
@@ -63,7 +63,7 @@ sections:
What this site is about
moonweb is a collection of personal projects that have grown over the past 25 years. What started as a single 486 running a BBS in the mid-90s has turned into a full homelab with Proxmox, Docker, smart home automation, and a growing collection of retro hardware. The name "moonweb" comes from the original domain moonweb.org, which has been online since 2000.
-
Each section of this site documents a different part of the setup. The infrastructure section covers the Proxmox cluster, Synology NAS, Docker containers, networking, and backup strategies. The smart home section shows what automation projects are running, from Tasmota energy monitoring to MQTT sensors and AirPlay audio. The code section lists the public GitHub projects that power these setups, and the retro section documents the hardware collection.
+
Each section of this site documents a different part of the setup. The infrastructure section covers the Proxmox cluster, Synology NAS, Docker containers, networking, and backup strategies. The smart home section shows what automation projects are running, from Tasmota energy monitoring to MQTT sensors and AirPlay audio. The code section lists the public GitHub projects that power these setups, and the retro section documents the hardware collection.
What I do professionally
I work as a Senior Software Developer & Architect at TENHIL GmbH (formerly stellenanzeigen.de), where I build and maintain microservices on .NET Core and Kubernetes. My day job involves designing cloud-native architectures, building APIs, and migrating legacy applications to modern stacks. I've been working with .NET since the early 2000s and have used everything from ASP Classic to the latest .NET 8 features.
diff --git a/infra/eleventy.config.js b/infra/eleventy.config.js
index 3338af4..56d2baa 100644
--- a/infra/eleventy.config.js
+++ b/infra/eleventy.config.js
@@ -1,5 +1,5 @@
module.exports = function (eleventyConfig) {
- eleventyConfig.addGlobalData("site", { url: "https://infra.moonweb.org" });
+ eleventyConfig.addGlobalData("site", { url: "https://www.moonweb.org" });
eleventyConfig.addFilter("date", (d) => d.toISOString());
eleventyConfig.addPassthroughCopy({ "shared/theme-infra.css": "theme.css" });
eleventyConfig.addPassthroughCopy({ "shared/base.css": "shared-base.css" });
diff --git a/package.json b/package.json
index d23157d..2699bcc 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,8 @@
{
"name": "moonweb-site",
- "version": "0.2.0",
+ "version": "0.3.0",
"private": true,
- "description": "Monorepo for hub/infra/smarthome/code/retro (Eleventy, static, deployed to Cloudflare Pages)",
+ "description": "Monorepo for hub/infra/smarthome/code/retro/timecapsule (Eleventy, static, deployed to IONOS SFTP)",
"scripts": {
"dev:hub": "npx @11ty/eleventy --config=hub/eleventy.config.js --serve --port=8081",
"dev:infra": "npx @11ty/eleventy --config=infra/eleventy.config.js --serve --port=8082",
@@ -10,14 +10,18 @@
"dev:code": "npx @11ty/eleventy --config=code/eleventy.config.js --serve --port=8084",
"dev:retro": "npx @11ty/eleventy --config=retro/eleventy.config.js --serve --port=8085",
"dev:stefankoelle": "npx @11ty/eleventy --config=stefankoelle/eleventy.config.js --serve --port=8086",
- "dev": "npm run dev:hub & npm run dev:infra & npm run dev:smarthome & npm run dev:code & npm run dev:retro & npm run dev:stefankoelle",
+ "dev:timecapsule": "cd timecapsule && npx @11ty/eleventy --serve --port=8087",
+ "dev": "npm run dev:hub & npm run dev:infra & npm run dev:smarthome & npm run dev:code & npm run dev:retro & npm run dev:stefankoelle & npm run dev:timecapsule",
"build:hub": "npx @11ty/eleventy --config=hub/eleventy.config.js",
"build:infra": "npx @11ty/eleventy --config=infra/eleventy.config.js",
"build:smarthome": "npx @11ty/eleventy --config=smarthome/eleventy.config.js",
"build:code": "npx @11ty/eleventy --config=code/eleventy.config.js",
"build:retro": "npx @11ty/eleventy --config=retro/eleventy.config.js",
"build:stefankoelle": "npx @11ty/eleventy --config=stefankoelle/eleventy.config.js",
- "build": "npm run build:hub && npm run build:infra && npm run build:smarthome && npm run build:code && npm run build:retro && npm run build:stefankoelle",
+ "build:timecapsule": "cd timecapsule && npx @11ty/eleventy && mkdir -p ../../dist/timecapsule && cp -r _site/timecapsule/* ../../dist/timecapsule/",
+ "build": "npm run build:hub && npm run build:infra && npm run build:smarthome && npm run build:code && npm run build:retro && npm run build:timecapsule && npm run build:stefankoelle",
+ "build:moonweb": "npm run build:hub && npm run build:infra && npm run build:smarthome && npm run build:code && npm run build:retro && npm run build:timecapsule",
+ "merge:moonweb": "bash scripts/merge-moonweb.sh",
"pdf:cv": "bash stefankoelle/pdf/build-pdf.sh",
"prebuild": "bash prebuild.sh"
},
diff --git a/retro/eleventy.config.js b/retro/eleventy.config.js
index 729f1d4..0812a61 100644
--- a/retro/eleventy.config.js
+++ b/retro/eleventy.config.js
@@ -1,5 +1,5 @@
module.exports = function (eleventyConfig) {
- eleventyConfig.addGlobalData("site", { url: "https://retro.moonweb.org" });
+ eleventyConfig.addGlobalData("site", { url: "https://www.moonweb.org" });
eleventyConfig.addFilter("date", (d) => d.toISOString());
eleventyConfig.addPassthroughCopy({ "shared/theme-retro.css": "theme.css" });
eleventyConfig.addPassthroughCopy({ "shared/base.css": "shared-base.css" });
diff --git a/scripts/merge-moonweb.sh b/scripts/merge-moonweb.sh
new file mode 100755
index 0000000..d2b50f8
--- /dev/null
+++ b/scripts/merge-moonweb.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+set -e
+
+echo "Merging moonweb sites for deployment..."
+
+# Clean previous merge
+rm -rf dist/root
+
+# Hub becomes root
+echo " hub → dist/ (root)"
+cp -r dist/hub dist/root
+rm -rf dist/hub
+
+# Copy timecapsule from its build output
+if [ -d "timecapsule/_site/timecapsule" ]; then
+ echo " timecapsule → dist/root/timecapsule/"
+ cp -r timecapsule/_site/timecapsule dist/root/timecapsule
+else
+ echo " WARNING: timecapsule/_site/timecapsule not found, skipping"
+fi
+
+# Subdirectories
+for site in infra smarthome code retro; do
+ if [ -d "dist/$site" ]; then
+ echo " $site → dist/root/$site/"
+ cp -r "dist/$site" "dist/root/$site"
+ else
+ echo " WARNING: dist/$site not found, skipping"
+ fi
+done
+
+# Copy CSS to root (accessible from all subdirectories)
+echo " Copying shared CSS to root..."
+cp shared/base.css dist/root/shared-base.css
+cp shared/favicon/hub.svg dist/root/favicon.svg
+
+# Theme CSS files are already copied during build as theme.css
+# The root theme is hub's theme
+if [ -f "dist/root/theme.css" ]; then
+ echo " Root theme.css already in place"
+fi
+
+echo ""
+echo "Merge complete. Final structure:"
+find dist/root -maxdepth 2 -type f | sort | head -50
+echo "..."
+echo ""
+echo "Total files:"
+find dist/root -type f | wc -l
diff --git a/shared/_includes/base.njk b/shared/_includes/base.njk
index 6227245..fe0d6fd 100644
--- a/shared/_includes/base.njk
+++ b/shared/_includes/base.njk
@@ -17,7 +17,6 @@
{% if ogImage %}{% endif %}
-
@@ -45,8 +44,8 @@
"@context": "https://schema.org",
"@type": "Person",
"name": "Stefan Koelle",
- "url": "https://hub.moonweb.org",
- "image": "https://hub.moonweb.org/stefan-koelle-foto.jpg",
+ "url": "https://www.moonweb.org",
+ "image": "https://www.moonweb.org/stefan-koelle-foto.jpg",
"jobTitle": "Senior Software Developer & Architect",
"address": {
"@type": "PostalAddress",
@@ -69,11 +68,11 @@
{{ section }}.moonweb.org
@@ -84,8 +83,8 @@