Skip to content

Commit 43736b1

Browse files
author
Neo
committed
v1.2.0: Performance, Impressum, README, Dynamic Stats
- Three.js Code-Split: dynamischer Import (~600KB weniger Initial-Bundle) - Three.js auf Mobile komplett deaktiviert - Hero-Stats live aus /api/stats.json statt hardcoded - Changelog v1.2.0 mit allen Optimierungen - Impressum & Datenschutz Seiten erstellt - Footer: Links zu Impressum/Datenschutz + v1.2.0 - README: Vollständige Projektdokumentation
1 parent 1f6f6b3 commit 43736b1

7 files changed

Lines changed: 251 additions & 44 deletions

File tree

README.md

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,64 @@
1-
# Astro Starter Kit: Minimal
1+
# NEO — Self-Hosted AI auf Custom Hardware
22

3-
```sh
4-
npm create astro@latest -- --template minimal
5-
```
3+
<p align="center">
4+
<img src="public/img/og-image.png" alt="NEO — Self-Hosted AI" width="600" />
5+
</p>
66

7-
> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
7+
> Ein KI-Agent. Ein MiniPC. Null Cloud. Gebaut von Merlin Lietz.
88
9-
## 🚀 Project Structure
9+
**[🌐 Live ansehen → neo.lietztech.com](https://neo.lietztech.com)**
1010

11-
Inside of your Astro project, you'll see the following folders and files:
11+
---
1212

13-
```text
14-
/
15-
├── public/
16-
├── src/
17-
│ └── pages/
18-
│ └── index.astro
19-
└── package.json
20-
```
13+
## Was ist NEO?
14+
15+
NEO ist mein persönliches Homelab-Projekt: ein vollständig self-hosted KI-System auf einem €200-MiniPC.
16+
Kein Cloud-Abo, kein Vendor Lock-in — alles läuft auf eigener Hardware.
2117

22-
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
18+
Diese Website dokumentiert das Projekt als interaktives Showcase mit Live-Dashboard, Terminal-Demo und System-Statistiken in Echtzeit.
2319

24-
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
20+
## Tech Stack
2521

26-
Any static assets, like images, can be placed in the `public/` directory.
22+
| Kategorie | Technologie |
23+
|-----------|------------|
24+
| **Frontend** | Astro v6, Tailwind CSS v4, Three.js, GSAP |
25+
| **Hardware** | ACE Magic S (Intel N97, 16GB RAM) |
26+
| **Virtualisierung** | Proxmox VE 9 |
27+
| **Container** | Docker (8+ Services) |
28+
| **Reverse Proxy** | Caddy + Cloudflare Tunnel |
29+
| **KI** | LiteLLM, Ollama (11 Modelle) |
30+
| **Automatisierung** | n8n, Cron, OpenClaw Agent |
31+
| **DMS** | Paperless-ngx |
32+
| **Benachrichtigungen** | Gotify, Telegram Bot |
2733

28-
## 🧞 Commands
34+
## Features
2935

30-
All commands are run from the root of the project, from a terminal:
36+
- 🎨 **Cinematic 3D Background** — PBR-Orbs mit Fresnel-Shader (Three.js)
37+
- 📊 **Live Dashboard** — CPU, RAM, Disk, Docker-Stats in Echtzeit
38+
- 💻 **Terminal Demo** — Interaktiver Chat + 8 Bot-Szenarien
39+
- 📱 **Telegram Preview** — Echte Bot-Konversation als Mockup
40+
- 🤖 **AI Model Roster** — Alle 11 KI-Modelle mit Benchmarks
41+
-**Automation Timeline** — 14 Automatisierungen visualisiert
42+
- 💰 **Cost Ticker** — Self-Hosted vs. Cloud Kostenvergleich
43+
- 🎯 **Performance** — Three.js Code-Split, Mobile-Disable, IntersectionObserver
3144

32-
| Command | Action |
33-
| :------------------------ | :----------------------------------------------- |
34-
| `npm install` | Installs dependencies |
35-
| `npm run dev` | Starts local dev server at `localhost:4321` |
36-
| `npm run build` | Build your production site to `./dist/` |
37-
| `npm run preview` | Preview your build locally, before deploying |
38-
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
39-
| `npm run astro -- --help` | Get help using the Astro CLI |
45+
## Entwicklung
46+
47+
```bash
48+
npm install # Dependencies
49+
npm run dev # Dev-Server (localhost:4321)
50+
npm run build # Produktions-Build
51+
```
52+
53+
## Deployment
54+
55+
Build via rsync auf Nginx-Server (LXC 113). Cloudflare Tunnel routet neo.lietztech.com.
56+
57+
```bash
58+
npm run build
59+
rsync -avz dist/ root@192.168.8.113:/var/www/neo-website/
60+
```
4061

41-
## 👀 Want to learn more?
62+
## Lizenz
4263

43-
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
64+
MIT © Merlin Lietz

src/components/sections/Changelog.astro

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,33 @@
33
* Changelog — Website-Versionshistorie
44
* Zeigt die Evolution dieser Seite, wann welche Features dazu kamen
55
*/
6-
const currentVersion = 'v1.1.0'
6+
const currentVersion = 'v1.2.0'
77
88
const releases = [
9+
{
10+
version: 'v1.2.0',
11+
date: '27. März 2026',
12+
tag: 'current',
13+
title: 'Performance & Professionalisierung',
14+
changes: [
15+
{ type: 'perf', text: 'Three.js Code-Split — dynamischer Import, ~600KB weniger Initial-Bundle' },
16+
{ type: 'perf', text: 'Three.js auf Mobile komplett deaktiviert' },
17+
{ type: 'perf', text: 'Ticker & CostTicker pausieren offscreen (IntersectionObserver)' },
18+
{ type: 'perf', text: 'Three.js pausiert bei Tab-Wechsel (Visibility API)' },
19+
{ type: 'feat', text: 'Hero-Statistiken live aus /api/stats.json statt hardcoded' },
20+
{ type: 'feat', text: 'OG-Image als PNG (1200×630) für Social Media' },
21+
{ type: 'feat', text: 'Schema.org JSON-LD Structured Data' },
22+
{ type: 'feat', text: 'Dashboard Live/Cached-Badge' },
23+
{ type: 'feat', text: 'Impressum & Datenschutz Seiten' },
24+
{ type: 'fix', text: 'CostTicker große Zahlen animieren korrekt' },
25+
{ type: 'fix', text: 'Automations-Zähler überall auf 14 vereinheitlicht' },
26+
{ type: 'refactor', text: 'Accessibility: role=navigation, aria-live für Toasts' },
27+
],
28+
},
929
{
1030
version: 'v1.1.0',
1131
date: '26. März 2026',
12-
tag: 'current',
32+
tag: '',
1333
title: 'Changelog & Versionierung',
1434
changes: [
1535
{ type: 'feat', text: 'Website-Changelog als eigene Section' },

src/components/sections/Hero.astro

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,19 +153,32 @@
153153
}
154154
setTimeout(typeLoop, 800)
155155

156-
// Live Stats — static fallback values (no WP dependency)
156+
// Live Stats — fetch from stats.json, fallback to known values
157157
function animateCounter(el: HTMLElement | null, target: number) {
158158
if (!el) return
159159
const start = performance.now()
160160
function step(now: number) { const p = Math.min((now - start) / 1200, 1); el!.textContent = String(Math.round(target * (1 - Math.pow(1 - p, 3)))); if (p < 1) requestAnimationFrame(step) }
161161
requestAnimationFrame(step)
162162
}
163-
// Set known values directly — these are real stats from the server
164-
animateCounter(document.getElementById('count-containers'), 8)
165-
animateCounter(document.getElementById('count-automations'), 14)
166-
animateCounter(document.getElementById('count-uptime-days'), 180)
167-
const stEl = document.getElementById('status-text')
168-
if (stEl) stEl.textContent = 'Alle Systeme online'
163+
164+
async function loadHeroStats() {
165+
let containers = 8, automations = 14, uptimeDays = 180
166+
try {
167+
const res = await fetch('/api/stats.json')
168+
if (res.ok) {
169+
const data = await res.json()
170+
if (data.docker_containers) containers = data.docker_containers
171+
if (data.cron_jobs) automations = data.cron_jobs
172+
if (data.uptime_days) uptimeDays = data.uptime_days
173+
}
174+
} catch { /* fallback values */ }
175+
animateCounter(document.getElementById('count-containers'), containers)
176+
animateCounter(document.getElementById('count-automations'), automations)
177+
animateCounter(document.getElementById('count-uptime-days'), uptimeDays)
178+
const stEl = document.getElementById('status-text')
179+
if (stEl) stEl.textContent = 'Alle Systeme online'
180+
}
181+
loadHeroStats()
169182

170183
// Live Proof — measure actual response time to this server
171184
async function measureResponseTime() {

src/components/ui/Footer.astro

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@
4141
Self-Hosted <span class="text-accent-cyan">AI</span> auf Custom Hardware
4242
</p>
4343
<p class="text-text-muted text-xs">
44-
&copy; {new Date().getFullYear()} Merlin Lietz — Ein Homelab-Projekt
44+
&copy; {new Date().getFullYear()} Merlin Lietz — Ein Homelab-Projekt ·
45+
<a href="/impressum" class="hover:text-accent-cyan transition-colors">Impressum</a> ·
46+
<a href="/datenschutz" class="hover:text-accent-cyan transition-colors">Datenschutz</a>
4547
</p>
4648
<p class="text-text-muted text-[10px] font-mono">
47-
v1.1.0 · Astro v6 · Intel N97 MiniPC · Docker · Caddy · Cloudflare
49+
v1.2.0 · Astro v6 · Intel N97 MiniPC · Docker · Caddy · Cloudflare
4850
</p>
4951
</div>
5052
</div>

src/layouts/BaseLayout.astro

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,23 @@ const canonicalUrl = Astro.url.href
9191

9292
<!-- GSAP + Three.js init -->
9393
<script>
94-
import { initBackground } from '../lib/three-bg'
9594
import { initScrollAnimations } from '../lib/animations'
9695

97-
document.addEventListener('DOMContentLoaded', () => {
96+
document.addEventListener('DOMContentLoaded', async () => {
97+
// Three.js nur auf Desktop laden (hover-fähig + breiter Screen)
98+
const isDesktop = window.matchMedia('(hover: hover) and (min-width: 768px)').matches
9899
const bgCanvas = document.getElementById('bg-canvas') as HTMLCanvasElement
99100
const fgCanvas = document.getElementById('fg-canvas') as HTMLCanvasElement
100-
if (bgCanvas && fgCanvas) initBackground(bgCanvas, fgCanvas)
101+
102+
if (isDesktop && bgCanvas && fgCanvas) {
103+
const { initBackground } = await import('../lib/three-bg')
104+
initBackground(bgCanvas, fgCanvas)
105+
} else {
106+
// Mobile: Canvases ausblenden, kein Three.js
107+
bgCanvas?.remove()
108+
fgCanvas?.remove()
109+
}
110+
101111
initScrollAnimations()
102112

103113
// Scroll progress bar

src/pages/datenschutz.astro

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
import BaseLayout from '../layouts/BaseLayout.astro'
3+
---
4+
5+
<BaseLayout title="Datenschutz — NEO" description="Datenschutzerklärung für neo.lietztech.com">
6+
<main class="min-h-screen flex items-start justify-center px-4 sm:px-6 pt-24 pb-16">
7+
<div class="glass-panel max-w-3xl w-full p-8 sm:p-12 space-y-6">
8+
<a href="/" class="text-accent-cyan text-xs font-mono hover:text-accent-purple transition-colors">← Zurück zur Startseite</a>
9+
10+
<h1 class="text-3xl font-display font-bold bg-gradient-to-r from-accent-purple to-accent-cyan bg-clip-text text-transparent">
11+
Datenschutzerklärung
12+
</h1>
13+
14+
<div class="space-y-4 text-text-secondary text-sm leading-relaxed">
15+
<section>
16+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">1. Verantwortlicher</h2>
17+
<p>
18+
Merlin Lietz<br />
19+
E-Mail: <a href="mailto:merlin@lietztech.com" class="text-accent-purple hover:text-accent-cyan transition-colors">merlin@lietztech.com</a>
20+
</p>
21+
</section>
22+
23+
<section>
24+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">2. Hosting</h2>
25+
<p>
26+
Diese Website wird auf eigener Hardware (Self-Hosted) betrieben. Der Zugriff erfolgt über
27+
Cloudflare Tunnel. Cloudflare kann dabei technische Daten wie IP-Adressen verarbeiten.
28+
Weitere Informationen: <a href="https://www.cloudflare.com/privacypolicy/" target="_blank" rel="noopener" class="text-accent-purple hover:text-accent-cyan transition-colors">Cloudflare Privacy Policy</a>.
29+
</p>
30+
</section>
31+
32+
<section>
33+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">3. Zugriffsdaten / Server-Logs</h2>
34+
<p>
35+
Beim Besuch dieser Website werden automatisch technische Daten erhoben (z.B. IP-Adresse,
36+
Browsertyp, Zeitstempel). Diese Daten werden ausschließlich zur Sicherstellung des Betriebs
37+
verwendet und nicht mit anderen Daten zusammengeführt.
38+
</p>
39+
</section>
40+
41+
<section>
42+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">4. Cookies</h2>
43+
<p>
44+
Diese Website verwendet keine Cookies und kein Tracking. Es werden keine Analyse-Tools wie
45+
Google Analytics eingesetzt.
46+
</p>
47+
</section>
48+
49+
<section>
50+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">5. Externe Dienste</h2>
51+
<p>
52+
<strong class="text-text-primary">Google Fonts:</strong> Diese Website lädt Schriftarten von Google Fonts.
53+
Dabei wird eine Verbindung zu Servern von Google hergestellt. Weitere Informationen:
54+
<a href="https://policies.google.com/privacy" target="_blank" rel="noopener" class="text-accent-purple hover:text-accent-cyan transition-colors">Google Datenschutzerklärung</a>.
55+
</p>
56+
</section>
57+
58+
<section>
59+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">6. Betroffenenrechte</h2>
60+
<p>
61+
Sie haben das Recht auf Auskunft, Berichtigung, Löschung und Einschränkung der Verarbeitung
62+
Ihrer personenbezogenen Daten. Kontaktieren Sie mich hierfür per E-Mail.
63+
</p>
64+
</section>
65+
66+
<section>
67+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">7. Kontakt</h2>
68+
<p>
69+
Bei Fragen zum Datenschutz erreichen Sie mich unter:
70+
<a href="mailto:merlin@lietztech.com" class="text-accent-purple hover:text-accent-cyan transition-colors">merlin@lietztech.com</a>
71+
</p>
72+
</section>
73+
</div>
74+
</div>
75+
</main>
76+
</BaseLayout>

src/pages/impressum.astro

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
import BaseLayout from '../layouts/BaseLayout.astro'
3+
---
4+
5+
<BaseLayout title="Impressum — NEO" description="Impressum gemäß §5 TMG für neo.lietztech.com">
6+
<main class="min-h-screen flex items-start justify-center px-4 sm:px-6 pt-24 pb-16">
7+
<div class="glass-panel max-w-3xl w-full p-8 sm:p-12 space-y-6">
8+
<a href="/" class="text-accent-cyan text-xs font-mono hover:text-accent-purple transition-colors">← Zurück zur Startseite</a>
9+
10+
<h1 class="text-3xl font-display font-bold bg-gradient-to-r from-accent-purple to-accent-cyan bg-clip-text text-transparent">
11+
Impressum
12+
</h1>
13+
14+
<div class="space-y-4 text-text-secondary text-sm leading-relaxed">
15+
<section>
16+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">Angaben gemäß § 5 TMG</h2>
17+
<p>
18+
Merlin Lietz<br />
19+
<!-- Postanschrift bitte manuell ergänzen -->
20+
<span class="text-text-muted italic">[Anschrift bitte ergänzen]</span>
21+
</p>
22+
</section>
23+
24+
<section>
25+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">Kontakt</h2>
26+
<p>
27+
E-Mail: <a href="mailto:merlin@lietztech.com" class="text-accent-purple hover:text-accent-cyan transition-colors">merlin@lietztech.com</a>
28+
</p>
29+
</section>
30+
31+
<section>
32+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">Verantwortlich für den Inhalt</h2>
33+
<p>Merlin Lietz (Anschrift wie oben)</p>
34+
</section>
35+
36+
<section>
37+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">Haftung für Inhalte</h2>
38+
<p>
39+
Die Inhalte dieser Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und
40+
Aktualität der Inhalte kann jedoch keine Gewähr übernommen werden. Als Diensteanbieter bin ich gemäß § 7 Abs. 1
41+
TMG für eigene Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich.
42+
</p>
43+
</section>
44+
45+
<section>
46+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">Haftung für Links</h2>
47+
<p>
48+
Diese Website enthält Links zu externen Websites Dritter, auf deren Inhalte ich keinen Einfluss habe.
49+
Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter verantwortlich.
50+
</p>
51+
</section>
52+
53+
<section>
54+
<h2 class="text-accent-cyan font-mono text-xs uppercase tracking-widest mb-2">Urheberrecht</h2>
55+
<p>
56+
Die durch den Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen
57+
Urheberrecht. Beiträge Dritter sind als solche gekennzeichnet. Die Vervielfältigung, Bearbeitung und
58+
jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der Zustimmung des jeweiligen
59+
Autors bzw. Erstellers.
60+
</p>
61+
</section>
62+
</div>
63+
</div>
64+
</main>
65+
</BaseLayout>

0 commit comments

Comments
 (0)