diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..458fa0c
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,50 @@
+# Changelog
+
+Alle nennenswerten Änderungen an Flimmer stehen in dieser Datei.
+
+Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/),
+die Versionierung [Semantic Versioning](https://semver.org/lang/de/).
+
+## [Unveröffentlicht]
+
+## [0.1.0] — 2026-09-01
+
+Erste lauffähige Etappe: Gerüst, Marke, Datenmodell und Anmeldung.
+
+### Hinzugefügt
+
+- **Projektgerüst** mit Next.js 16 (App Router), TypeScript, Tailwind CSS v4
+ und `standalone`-Build für schlanke Container.
+- **Marke Flimmer**: Logo als SVG in drei Varianten (Bildmarke, Bildmarke mit
+ Wortmarke, monochrom) plus Maskable-Variante. Die Wortmarke ist aus Pfaden
+ konstruiert und braucht keine installierte Schrift.
+- **Icon-Generator** (`npm run icons`): erzeugt Favicon (SVG und ICO),
+ PWA-Icons in sieben Größen, Maskable-Icons, Apple-Touch-Icon und OG-Bild
+ aus den SVG-Quellen.
+- **Design-Tokens** als CSS-Variablen, über `@theme inline` an Tailwind
+ angebunden. Dunkles Standard-Theme und heller Modus mit Umschalter
+ (Dunkel / Hell / System), ohne Aufblitzen beim Laden. Alle Farbkombinationen
+ erfüllen WCAG AA; getrennte Verläufe für Flächen und Text sorgen dafür, dass
+ auch der Signaturverlauf im hellen Modus lesbar bleibt.
+- **Datenmodell** (Prisma, PostgreSQL) für Konten, Katalog (Titel, Staffeln,
+ Episoden, Streamingdienste), persönliches Tracking, Universen mit
+ Reihenfolgen sowie Benachrichtigungen und Hintergrundläufe.
+- **Authentifizierung**: Registrierung und Anmeldung mit E-Mail und Passwort
+ (bcrypt), Sitzungen als opake Token in der Datenbank mit httpOnly-Cookie.
+ Der erste registrierte Zugang wird automatisch Administrator; die
+ Registrierung lässt sich instanzweit abschalten.
+- **Optionales SSO** über OIDC (Authorization Code mit PKCE) für Authelia,
+ Keycloak, Authentik und Verwandte — per Umgebungsvariablen aktivierbar,
+ mit Zuordnung zu vorhandenen Konten über die E-Mail-Adresse.
+- **API-Schlüssel** je Nutzer als Grundlage für die spätere REST-API.
+- **Docker-Compose-Setup** für den Selbstbetrieb (App und PostgreSQL,
+ persistente Volumes, Healthcheck) samt Entrypoint, der ausstehende
+ Migrationen beim Start einspielt.
+- **Healthcheck** unter `/api/health`, der auch die Datenbank prüft.
+- **PWA-Manifest** mit allen Icon-Größen.
+- **Oberflächentexte** auf Deutsch, gebündelt in `src/i18n` und so aufgebaut,
+ dass weitere Sprachen als zusätzliche Datei dazukommen können.
+- **Seed-Skript** mit Demo-Konten sowie README und Design-Dokumentation.
+
+[Unveröffentlicht]: https://git.wilde-server.de/florian.wilde/flimmer/compare/v0.1.0...HEAD
+[0.1.0]: https://git.wilde-server.de/florian.wilde/flimmer/releases/tag/v0.1.0
diff --git a/CLAUDE.md b/CLAUDE.md
index 2d67c14..9e03a9d 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -83,3 +83,13 @@ Statistiken, Benachrichtigungen, REST-API, PWA. Oberflächensprache **Deutsch**.
## Fortschritt
- Stand: **Etappe 1 läuft** (Start 2026-09-01 18:09)
+
+
+
+# This is NOT the Next.js you know
+
+This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.
+
+This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
+
+
diff --git a/DEVLOG.md b/DEVLOG.md
index dd83e3a..121b11c 100644
--- a/DEVLOG.md
+++ b/DEVLOG.md
@@ -1,7 +1,6 @@
# DEVLOG — Entwicklungszeiterfassung Flimmer
Alle Zeiten per `date`-Befehl erfasst (Europe/Berlin), nicht geschätzt.
-Format je Eintrag: `Start – Ende (Dauer) — Beschreibung`.
---
@@ -9,4 +8,23 @@ Format je Eintrag: `Start – Ende (Dauer) — Beschreibung`.
| # | Start | Ende | Dauer | Arbeitsschritt |
|---|---|---|---|---|
-| 1.1 | 2026-09-01 18:09 | | | Rückfragen geklärt, Repo/Toolchain geprüft, Projekt-CLAUDE.md angelegt |
+| 1.1 | 18:09 | 18:12 | 3 min | Rückfragen geklärt, Repo und Werkzeugkette geprüft, Projekt-`CLAUDE.md` als Gedächtnis angelegt |
+| 1.2 | 18:12 | 18:22 | 10 min | `package.json`, TypeScript-, Next- und PostCSS-Konfiguration; Abhängigkeiten installiert (Aufräumen nach hängendem npm-Prozess) |
+| 1.3 | 18:22 | 18:26 | 4 min | Design-Tokens in `globals.css`: Farbwelt dunkel/hell, Verläufe, Bausteine, Mikro-Animation |
+| 1.4 | 18:26 | 18:33 | 7 min | Logo entworfen: Bildmarke, Wortmarke aus Pfaden, Lockup, monochrom, Maskable; Icon-Generator und alle Rasterableitungen |
+| 1.5 | 18:33 | 18:36 | 3 min | Prisma-Schema (22 Modelle), Umstellung auf Prisma 7 mit Treiber-Adapter, erste Migration |
+| 1.6 | 18:36 | 18:40 | 4 min | Kernbibliotheken: Umgebungsprüfung, DB-Singleton, Auth (Passwörter, Sitzungen, API-Schlüssel), Instanz-Einstellungen, i18n |
+| 1.7 | 18:40 | 18:44 | 4 min | App-Hülle: Layout mit Theme-Bootstrap, Header, Navigation, Nutzermenü, Anmeldung und Registrierung, Healthcheck; visuelle Kontrolle in beiden Themes und Kontrastkorrektur für den hellen Modus |
+| 1.8 | 18:44 | 18:52 | 8 min | Docker-Setup (Dockerfile, Compose, Entrypoint mit Migrationslauf), OIDC-Anbindung, Seed-Skript, README, Design-Dokumentation, Changelog |
+
+**Etappe 1 gesamt: 43 min** (18:09 – 18:52)
+
+---
+
+## Gesamtübersicht
+
+| Etappe | Version | Dauer |
+|---|---|---|
+| 1 — Gerüst, Branding, Docker, Schema, Auth | 0.1.0 | 43 min |
+
+**Bisher gesamt: 43 min**
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e13bc55
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2026 Florian Wilde
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9d9d3f0
--- /dev/null
+++ b/README.md
@@ -0,0 +1,198 @@
+
+
+
+
+
+ Serien und Filme tracken — selbst gehostet, ohne fremde Konten.
+ Episodenfortschritt, eigene Universen mit mehreren Reihenfolgen, Statistiken
+ und Benachrichtigungen, wenn es weitergeht.
+
+
+---
+
+**Flimmer** ist ein selbst hostbarer Tracker für Serien und Filme — benannt nach
+der Flimmerkiste und dem warmen Flimmern, das ein Bildschirm im dunklen Zimmer
+verbreitet. Metadaten kommen von [TMDB](https://www.themoviedb.org/), die Daten
+bleiben auf deinem Server.
+
+## Was Flimmer kann
+
+- **Tracking** — Serien und Filme mit Status (Schaue gerade, Pausiert,
+ Abgeschlossen, Abgebrochen, Watchlist), Episodenfortschritt einzeln oder
+ staffelweise, „+1 Episode"-Knopf, Rewatch-Zählung, Bewertung, Notizen, Tags.
+- **Universen** — MCU, Star Wars, Wizarding World … beliebige Filme *und* Serien
+ in einem Universum bündeln, mit mehreren Reihenfolgen (Erscheinung,
+ Story-Chronologie, Einsteiger-Route) und Gesamtfortschritt.
+- **Metadaten von TMDB** — Suche, Poster, Staffeln und Episoden, offizielle
+ Collections, Streaming-Verfügbarkeit in deiner Region.
+- **Benachrichtigungen** — bei neuen Episoden und Releases, per E-Mail, ntfy,
+ Gotify oder Webhook (Discord/Slack-kompatibel), pro Nutzer einstellbar.
+- **Mehrere Nutzer** — jede Person hat ihre eigene Bibliothek; Universen lassen
+ sich teilen. Der erste registrierte Zugang wird Administrator.
+- **REST-API und PWA** — dokumentierte Schnittstelle mit eigenen API-Schlüsseln,
+ installierbar auf dem Startbildschirm.
+
+## Schnellstart
+
+Voraussetzungen: Docker und Docker Compose.
+
+```bash
+git clone https://git.wilde-server.de/florian.wilde/flimmer.git
+cd flimmer
+cp .env.example .env
+```
+
+In der `.env` mindestens diese drei Werte setzen:
+
+```dotenv
+POSTGRES_PASSWORD=ein-langes-zufaelliges-passwort
+AUTH_SECRET=noch-ein-langes-zufaelliges-geheimnis
+APP_URL=https://flimmer.example.com
+```
+
+Geheimnisse erzeugen:
+
+```bash
+node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
+```
+
+Dann starten:
+
+```bash
+docker compose up -d
+```
+
+Flimmer läuft auf . Der **erste** Zugang, der sich
+registriert, wird automatisch Administrator — lege ihn also gleich an. Danach
+lässt sich die Registrierung in der Verwaltung schließen.
+
+### TMDB-Schlüssel
+
+Ohne TMDB findet die Suche keine Metadaten. Der Schlüssel ist kostenlos:
+
+1. Konto auf [themoviedb.org](https://www.themoviedb.org/signup) anlegen
+2. Unter *Einstellungen → API* einen Schlüssel beantragen
+3. In die `.env` eintragen und `docker compose up -d` erneut ausführen:
+
+```dotenv
+TMDB_API_KEY=dein-schluessel
+TMDB_REGION=DE
+TMDB_LANGUAGE=de-DE
+```
+
+## Betrieb hinter einem Reverse Proxy
+
+`APP_URL` muss auf die öffentliche Adresse zeigen — daraus werden Links in
+Benachrichtigungen und der OIDC-Rücksprung gebildet. Als Healthcheck eignet
+sich `/api/health`; der Endpunkt prüft auch die Datenbankverbindung.
+
+Beispiel für Caddy:
+
+```caddyfile
+flimmer.example.com {
+ reverse_proxy flimmer:3000
+}
+```
+
+## Aktualisieren
+
+```bash
+cd flimmer
+git pull
+docker compose build
+docker compose up -d
+```
+
+Datenbankmigrationen laufen automatisch beim Start des Containers — ein eigener
+Handgriff ist nicht nötig. **Vor** einem Update ein Backup zu ziehen ist
+trotzdem eine gute Angewohnheit.
+
+## Backup
+
+Alles, was zählt, steckt in der Datenbank; das Volume `flimmer-data` enthält
+nur den Bild-Cache und lässt sich jederzeit neu aufbauen.
+
+```bash
+# Sicherung
+docker compose exec -T db pg_dump -U flimmer -d flimmer --clean --if-exists \
+ | gzip > flimmer-$(date +%F).sql.gz
+
+# Rückspielen
+gunzip -c flimmer-2026-09-01.sql.gz \
+ | docker compose exec -T db psql -U flimmer -d flimmer
+```
+
+Für einen nächtlichen Lauf genügt ein Cron-Eintrag mit demselben Befehl.
+Wer zusätzlich den Bild-Cache sichern will:
+
+```bash
+docker run --rm -v flimmer_flimmer-data:/data -v "$PWD":/backup alpine \
+ tar czf /backup/flimmer-data.tar.gz -C /data .
+```
+
+## Konfiguration
+
+Sämtliche Einstellungen laufen über Umgebungsvariablen; die vollständige Liste
+mit Erklärungen steht in [`.env.example`](.env.example). Die wichtigsten:
+
+| Variable | Bedeutung |
+|---|---|
+| `APP_URL` | Öffentliche Adresse der Instanz |
+| `AUTH_SECRET` | Geheimnis für Sitzungen — mindestens 32 Zeichen |
+| `TMDB_API_KEY` | TMDB-Schlüssel für Metadaten |
+| `TMDB_REGION` | Region für die Streaming-Verfügbarkeit (Standard `DE`) |
+| `ALLOW_REGISTRATION` | Selbstregistrierung bei der Erstinbetriebnahme |
+| `ENABLE_SCHEDULER` | Eingebauter Hintergrundlauf für Sync und Benachrichtigungen |
+| `SMTP_*` | E-Mail-Versand |
+| `OIDC_*` | Optionale SSO-Anbindung (Authelia, Keycloak, Authentik …) |
+
+## Entwicklung
+
+```bash
+npm install
+docker compose -f docker-compose.dev.yml up -d # nur PostgreSQL
+cp .env.example .env # DATABASE_URL auf localhost:5439
+npm run db:migrate
+npm run db:seed # Demo-Konten
+npm run dev
+```
+
+| Befehl | Wirkung |
+|---|---|
+| `npm run dev` | Entwicklungsserver |
+| `npm run build` | Produktionsbuild |
+| `npm run typecheck` | TypeScript prüfen |
+| `npm run db:migrate` | Migration erzeugen und anwenden |
+| `npm run db:studio` | Prisma Studio |
+| `npm run db:seed` | Beispieldaten |
+| `npm run icons` | Favicon und PWA-Icons aus dem SVG-Logo neu erzeugen |
+
+Aufbau des Projekts:
+
+```
+src/
+ app/ Routen (App Router), API-Endpunkte
+ components/ Wiederverwendbare Bausteine
+ lib/ Serverseitige Logik: DB, Auth, TMDB, Benachrichtigungen
+ i18n/ Oberflächentexte
+prisma/ Schema, Migrationen, Seed
+public/brand/ Logo in allen Varianten
+docker/ Entrypoint des Containers
+docs/ Anleitung, Design-Dokumentation
+```
+
+## Technik
+
+Next.js (App Router) mit TypeScript, PostgreSQL über Prisma, Tailwind CSS.
+Warum Next und nicht SvelteKit: Oberfläche, REST-API und Hintergrundläufe
+stecken in **einem** Deployment, Server Components halten den Datenbankzugriff
+serverseitig, und der `standalone`-Build ergibt ein schlankes Image ohne
+Build-Werkzeuge. Für ein selbst gehostetes Werkzeug zählt vor allem, dass ein
+einziger Container genügt.
+
+## Lizenz
+
+MIT — siehe [LICENSE](LICENSE).
+
+Metadaten stammen von TMDB. Flimmer wird von TMDB weder betrieben noch
+unterstützt.
diff --git a/docs/DESIGN.md b/docs/DESIGN.md
new file mode 100644
index 0000000..86d8109
--- /dev/null
+++ b/docs/DESIGN.md
@@ -0,0 +1,122 @@
+# Flimmer — Design-Sprache
+
+Diese Datei hält fest, warum die Oberfläche aussieht, wie sie aussieht, und
+welche Werte dabei gelten. Sie ist die Referenz für alles, was später dazukommt.
+
+## Idee
+
+Der Name kommt von der **Flimmerkiste** und vom warmen Flimmern eines
+Bildschirms im abgedunkelten Zimmer. Genau das trägt die Gestaltung: ein sehr
+dunkler, blauvioletter Raum, in den ein warmes Licht fällt. Alles Farbige in
+der Oberfläche ist dieses Licht — es gibt keine zweite, konkurrierende
+Signalfarbe.
+
+## Marke
+
+| Variante | Datei | Einsatz |
+|---|---|---|
+| Bildmarke | `public/brand/flimmer-icon.svg` | App-Icon, Favicon, Avatare |
+| Bildmarke + Wortmarke | `public/brand/flimmer-logo.svg` | Header, Login, README |
+| Monochrom | `public/brand/flimmer-mono.svg` | Druck, E-Mail-Footer, Prägung |
+| Maskable | `public/brand/flimmer-icon-maskable.svg` | Android-Startbildschirm |
+| Wortmarke allein | `public/brand/flimmer-wordmark.svg` | Sonderfälle |
+
+Die Bildmarke ist ein abgerundetes Bildschirm-Rechteck mit weichem, warmem
+Glühen und einem Play-Dreieck; der angedeutete Standfuß macht daraus die
+Flimmerkiste. Die **Wortmarke ist aus Pfaden konstruiert** (geometrische, leicht
+gerundete Sans, Versalhöhe 90, x-Höhe 54, Strichstärke 15, runde Abschlüsse) —
+sie braucht damit keine installierte Schrift und sieht überall identisch aus.
+
+Im UI liegt die Marke als React-Komponente vor
+(`src/components/brand/FlimmerLogo.tsx`). Die Verläufe stehen einmalig in
+`` im Root-Layout; alle Instanzen referenzieren sie. Rasterdateien
+(Favicon, PWA-Icons, OG-Bild) sind reine Ableitungen und entstehen mit
+`npm run icons`.
+
+## Farbwelt
+
+Die Signaturfarbe ist kein einzelner Ton, sondern ein **Verlauf von Bernstein
+nach Magenta**. Er trägt Buttons, Fortschrittsbalken, aktive Navigation und das
+Glühen des Logos.
+
+### Dunkel (Standard)
+
+| Rolle | Wert | Kontrast auf Grund |
+|---|---|---|
+| Grund | `#0c0a14` | — |
+| Karte | `#171424` | — |
+| Rahmen | `#2e2745` | 1,4:1 (dekorativ) |
+| Text | `#f4f1fa` | **17,0:1** |
+| Text gedämpft | `#aca5c2` | **7,7:1** |
+| Text zurückhaltend | `#7c7594` | **4,6:1** |
+| Bernstein | `#ffb454` | **11,3:1** |
+| Magenta | `#ff4d9d` | **6,0:1** |
+| Text auf dem Verlauf | `#1a1024` | min. **5,5:1** (am Magenta-Ende) |
+
+### Hell
+
+| Rolle | Wert | Kontrast auf Grund |
+|---|---|---|
+| Grund | `#faf7f5` (warmgrau) | — |
+| Karte | `#ffffff` | — |
+| Text | `#1b1524` | **16,2:1** |
+| Text gedämpft | `#5b5268` | **6,7:1** |
+| Text zurückhaltend | `#766c84` | **4,6:1** |
+| Akzent als Text | `#8a4b00` | **6,4:1** |
+| Akzent-Alternative | `#b01262` | **6,4:1** |
+| Text auf dem Verlauf | `#23122c` | min. **6,1:1** |
+
+Damit erfüllt jede Text-/Hintergrund-Kombination **WCAG AA**.
+
+### Zwei Verläufe, nicht einer
+
+Der vollfarbige Verlauf funktioniert im Dunkeln überall — auf hellem Grund
+verschwindet sein Bernstein-Ende jedoch. Deshalb gibt es zwei Tokens:
+
+- `--fl-gradient` — Flächen (Buttons, Fortschritt, Glühen). In beiden Themes
+ vollfarbig, weil darauf immer dunkler Text (`--fl-on-accent`) sitzt.
+- `--fl-gradient-ink` — **Text** und feine Linien. Im Dunkeln identisch, im
+ Hellen abgedunkelt auf `#8a4b00 → #b01262`, damit AA gilt.
+
+Analog dazu die Logo-Stops `--fl-brand-1/2/3`: im Hellen tiefer angesetzt
+(`#c26a00 → #c9186f`), damit die Wortmarke auf warmem Weiß lesbar bleibt, ohne
+die Bewegung von Bernstein nach Magenta aufzugeben.
+
+## Tokens
+
+Alle Werte liegen als CSS-Variablen `--fl-*` in `src/app/globals.css` und werden
+über `@theme inline` an Tailwind durchgereicht. Ein Theme-Wechsel setzt nur das
+Attribut `data-theme` am ``-Element; ein Inline-Skript im Layout tut das,
+bevor der erste Pixel gemalt wird, damit nichts aufblitzt.
+
+Ein zusätzliches Theme braucht daher genau einen neuen Selektor-Block mit
+denselben Variablennamen — keine Änderung an Komponenten.
+
+## Bausteine
+
+| Klasse | Zweck |
+|---|---|
+| `.fl-card` | Karte: halbtransparent, weicher Rahmen, Rückenunschärfe |
+| `.fl-poster-card` | Posterkachel mit sanftem Aufglimmen beim Hover |
+| `.fl-btn` + `.fl-btn-primary` / `.fl-btn-ghost` | Schaltflächen |
+| `.fl-input` | Eingabefelder samt Fokusring im Magenta |
+| `.fl-progress` | Fortschrittsbalken im Signaturverlauf |
+| `.fl-glimmer` | Mikro-Animation beim Abhaken einer Episode |
+
+## Bewegung
+
+Ruhig und kurz: 200–420 ms, `cubic-bezier(0.22, 1, 0.36, 1)`. Keine harten
+Blitze — beim Abhaken einer Episode glimmt die Zeile einmal warm auf und
+verklingt. `prefers-reduced-motion: reduce` schaltet sämtliche Übergänge ab.
+
+## Typografie
+
+**Outfit** — geometrisch, leicht gerundet, passt zur Wortmarke. Wird beim Bauen
+heruntergeladen und mit ausgeliefert; die laufende Instanz fragt nie bei Google
+an. Rückfallkette: Inter, dann System-Sans.
+
+## Grundhaltung
+
+Posterlastig und filmisch: großzügige Poster, abgerundete Ecken, weiche
+Verläufe statt harter Linien. Farbe ist knapp und bedeutet etwas — der Verlauf
+markiert, was gerade dran ist. Der Rest bleibt im Dunkeln.
diff --git a/prisma/seed.ts b/prisma/seed.ts
new file mode 100644
index 0000000..08877f6
--- /dev/null
+++ b/prisma/seed.ts
@@ -0,0 +1,75 @@
+/**
+ * Beispieldaten für die Entwicklung.
+ *
+ * npm run db:seed
+ *
+ * Das Skript ist idempotent: mehrfaches Ausführen legt nichts doppelt an.
+ * Es fasst ausschließlich die Demo-Konten und deren Daten an — eine echte
+ * Instanz nimmt dadurch keinen Schaden, sollte es versehentlich laufen.
+ */
+import { PrismaPg } from "@prisma/adapter-pg";
+import bcrypt from "bcryptjs";
+import { PrismaClient } from "../src/generated/prisma/client";
+
+try {
+ process.loadEnvFile(".env");
+} catch {
+ // Werte kommen aus der Umgebung.
+}
+
+const prisma = new PrismaClient({
+ adapter: new PrismaPg({ connectionString: process.env.DATABASE_URL }),
+});
+
+const DEMO_PASSWORD = "flimmer-demo-2026";
+
+async function seedUsers() {
+ const passwordHash = await bcrypt.hash(DEMO_PASSWORD, 12);
+
+ const admin = await prisma.user.upsert({
+ where: { email: "demo@flimmer.local" },
+ update: {},
+ create: {
+ email: "demo@flimmer.local",
+ name: "Demo Nutzer",
+ passwordHash,
+ role: "ADMIN",
+ region: "DE",
+ publicProfile: true,
+ profileSlug: "demo",
+ },
+ });
+
+ const friend = await prisma.user.upsert({
+ where: { email: "gast@flimmer.local" },
+ update: {},
+ create: {
+ email: "gast@flimmer.local",
+ name: "Gast Nutzerin",
+ passwordHash,
+ role: "USER",
+ region: "DE",
+ },
+ });
+
+ return { admin, friend };
+}
+
+async function main() {
+ console.log("Seed: lege Demo-Konten an ...");
+ const { admin, friend } = await seedUsers();
+
+ console.log("");
+ console.log("Fertig. Anmelden mit:");
+ console.log(` ${admin.email} / ${DEMO_PASSWORD} (Administrator)`);
+ console.log(` ${friend.email} / ${DEMO_PASSWORD}`);
+}
+
+main()
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ })
+ .finally(async () => {
+ await prisma.$disconnect();
+ });
diff --git a/releases/v0.1.0.md b/releases/v0.1.0.md
new file mode 100644
index 0000000..01b8211
--- /dev/null
+++ b/releases/v0.1.0.md
@@ -0,0 +1,38 @@
+# Flimmer 0.1.0
+
+Erste lauffähige Etappe: Gerüst, Marke, Datenmodell und Anmeldung.
+
+### Hinzugefügt
+
+- **Projektgerüst** mit Next.js 16 (App Router), TypeScript, Tailwind CSS v4
+ und `standalone`-Build für schlanke Container.
+- **Marke Flimmer**: Logo als SVG in drei Varianten (Bildmarke, Bildmarke mit
+ Wortmarke, monochrom) plus Maskable-Variante. Die Wortmarke ist aus Pfaden
+ konstruiert und braucht keine installierte Schrift.
+- **Icon-Generator** (`npm run icons`): erzeugt Favicon (SVG und ICO),
+ PWA-Icons in sieben Größen, Maskable-Icons, Apple-Touch-Icon und OG-Bild
+ aus den SVG-Quellen.
+- **Design-Tokens** als CSS-Variablen, über `@theme inline` an Tailwind
+ angebunden. Dunkles Standard-Theme und heller Modus mit Umschalter
+ (Dunkel / Hell / System), ohne Aufblitzen beim Laden. Alle Farbkombinationen
+ erfüllen WCAG AA; getrennte Verläufe für Flächen und Text sorgen dafür, dass
+ auch der Signaturverlauf im hellen Modus lesbar bleibt.
+- **Datenmodell** (Prisma, PostgreSQL) für Konten, Katalog (Titel, Staffeln,
+ Episoden, Streamingdienste), persönliches Tracking, Universen mit
+ Reihenfolgen sowie Benachrichtigungen und Hintergrundläufe.
+- **Authentifizierung**: Registrierung und Anmeldung mit E-Mail und Passwort
+ (bcrypt), Sitzungen als opake Token in der Datenbank mit httpOnly-Cookie.
+ Der erste registrierte Zugang wird automatisch Administrator; die
+ Registrierung lässt sich instanzweit abschalten.
+- **Optionales SSO** über OIDC (Authorization Code mit PKCE) für Authelia,
+ Keycloak, Authentik und Verwandte — per Umgebungsvariablen aktivierbar,
+ mit Zuordnung zu vorhandenen Konten über die E-Mail-Adresse.
+- **API-Schlüssel** je Nutzer als Grundlage für die spätere REST-API.
+- **Docker-Compose-Setup** für den Selbstbetrieb (App und PostgreSQL,
+ persistente Volumes, Healthcheck) samt Entrypoint, der ausstehende
+ Migrationen beim Start einspielt.
+- **Healthcheck** unter `/api/health`, der auch die Datenbank prüft.
+- **PWA-Manifest** mit allen Icon-Größen.
+- **Oberflächentexte** auf Deutsch, gebündelt in `src/i18n` und so aufgebaut,
+ dass weitere Sprachen als zusätzliche Datei dazukommen können.
+- **Seed-Skript** mit Demo-Konten sowie README und Design-Dokumentation.
diff --git a/scripts/shot.mjs b/scripts/shot.mjs
new file mode 100644
index 0000000..d57ff8e
--- /dev/null
+++ b/scripts/shot.mjs
@@ -0,0 +1,21 @@
+/**
+ * Schnelles Einzelbild einer Seite — Werkzeug für die Entwicklung.
+ * node scripts/shot.mjs [breite] [hoehe] [theme]
+ */
+import { chromium } from "playwright";
+
+const [, , url, out, w = "1440", h = "900", theme = "dark"] = process.argv;
+
+const browser = await chromium.launch();
+const page = await browser.newPage({
+ viewport: { width: Number(w), height: Number(h) },
+ deviceScaleFactor: 2,
+});
+await page.addInitScript((mode) => {
+ localStorage.setItem("flimmer-theme", mode);
+}, theme);
+await page.goto(url, { waitUntil: "networkidle" });
+await page.waitForTimeout(600);
+await page.screenshot({ path: out });
+await browser.close();
+console.log("ok", out);