diff --git a/.planning/.continue-here.md b/.planning/.continue-here.md
new file mode 100644
index 0000000..39fc0c9
--- /dev/null
+++ b/.planning/.continue-here.md
@@ -0,0 +1,154 @@
+---
+context: default
+phase: null
+task: null
+total_tasks: null
+status: paused
+last_updated: 2026-09-22T14:15:00.000Z
+---
+
+
+Kein laufender Meilenstein. Alle 18 Phasen sind abgeschlossen; seit der Freigabe
+1.2.0 laeuft die Arbeit als Quick-Tasks. **Version 1.3.0 wurde am 22.09.2026
+freigegeben** (Tag `v1.3.0` auf `d146234`, Abbilder `live` und `v1.3.0`,
+Gitea-Release mit `Tessera-Setup-1.3.0.exe` und `Tessera-1.3.0.AppImage`).
+
+`main == origin/main` auf `1315f37`, Arbeitsbaum sauber, CI gruen. Der lokale
+Docker-Stack laeuft mit genau diesem Stand (web, api, db).
+
+Unterbrochen wurde NICHT mitten in einer Aufgabe — alle acht Auftraege dieser
+Sitzung sind fertig, nachgewiesen und gepusht. Der naechste Auftrag (Proxmox)
+ist inhaltlich geklaert, wartet aber auf Zugangsdaten des Nutzers.
+
+
+
+
+Diese Sitzung (21.09. abends bis 22.09. nachmittags):
+
+- quick-260921-pi9 — Dashboard-Widget „Bilderrahmen" (Upload oder https-Adresse, Diashow, Grossansicht)
+- quick-260921-qd3 — Dashboard-Widget „XFrame" (Webseite als Rahmen, Sandbox ohne Top-Navigation)
+- quick-260922-frg — Tray-Update-Eintrag nennt den Grund einer fehlgeschlagenen Pruefung, Klick prueft erneut, Pruefung alle 4 h
+- fast `747a4d4` — Download-Knoepfe im Desktop-Client oeffnen den System-Browser (waren ohne Funktion)
+- quick-260922-ge2 — XFrame: Ausschnitt waehlen und einpassen, Zoom, „Nur anzeigen"
+- **Freigabe 1.3.0** — CHANGELOG abgeschlossen, `live` vorgezogen, Tag gepusht, drei CI-Laeufe gruen
+- quick-260922-hk4 — Bilderrahmen-Bilder in den Dateibereich `user-files` statt in die Datenbank, automatischer Umzug beim Start, Selbstheilung aus der alten Spalte
+- quick-260922-m1h — Widget-Typen an EINER Stelle, Katalog aus der Registry + Modulfilter, Kachel kennt ihr Modul
+
+Jeder Punkt wurde im Browser (Playwright-MCP) gegen den lokalen Stack geprueft;
+die Pruefprotokolle stehen in den jeweiligen SUMMARY.md unter `.planning/quick/`.
+
+
+
+
+1. **Proxmox-Modul** (PVE, PBS, PMG) — **nur beobachten**, keine Eingriffe.
+ Seite: Server anbinden, VMs/Container mit CPU, Arbeitsspeicher, Plattenplatz
+ und Erreichbarkeit; bei PBS Sicherungslaeufe und Pruefstatus, bei PMG die
+ Mail-Zahlen (zugestellt, gefiltert, blockiert, Quarantaene).
+2. **Proxmox-Kachel** — kompakte Fassung ueber den neuen Weg (drei Stellen,
+ siehe unten). Vorschlag fuer den Inhalt steht in der Sitzung: Ampel je Server
+ + drei Balken; PBS: Alter der letzten Sicherung, Pruefergebnis, freier Platz;
+ PMG: Tageszahlen in einer Zeile. Idee fuer spaeter: eine Sammelkachel
+ „Alles in Ordnung?" mit einer Zeile je Server.
+
+
+
+
+- **Bilder auf die Festplatte, nicht in die Datenbank** — Grund ist die Sicherung
+ (`pg_dump` von Hand; 30 Bilder à 5 MiB je Benutzer waeren 150 MB pro Benutzer
+ im Abzug), nicht die Geschwindigkeit, und die Einheitlichkeit mit Avataren
+ (`user-files/avatars`) und DKV-Exporten.
+- **Zweistufige Umstellung:** Spalte `data` bleibt vorerst stehen; `getBytes`
+ stellt eine fehlende Datei daraus wieder her. DROP erst, wenn alpha UND live
+ einmal mit dieser Version gelaufen sind — Todo liegt unter
+ `.planning/todos/pending/2026-09-22-dashboard-image-data-spalte-entfernen.md`.
+- **Proxmox: nur beobachten**, Zugriff ueber die normale Modulfreigabe
+ (Nutzeransage 22.09.).
+- **Kacheln gesperrter Module erscheinen gar nicht erst im Katalog**
+ (Nutzeransage 22.09.) — so umgesetzt in m1h.
+- **Basic-Auth am Proxy vor alpha bleibt** (Nutzerentscheidung). Aus dem
+ Firmennetz greift eine Ausnahme; von aussen 401, und der Client sagt das seit
+ frg selbst. **Nicht erneut vorschlagen, das Thema ist entschieden.**
+
+
+
+- Proxmox braucht Zugangsdaten und Serveradressen des Nutzers (API-Token, nur
+ lesend, z. B. Rolle `PVEAuditor`). Der Nutzer legt sie morgen an. Planung und
+ Modulskelett koennen vorher entstehen, die Anbindung nicht getestet werden.
+
+
+## Required Reading (in order)
+
+1. `.planning/quick/260922-m1h-dashboard-widgets-ein-modul-bringt-seine/260922-m1h-SUMMARY.md` — Abschnitt „So fuegt man kuenftig eine Modul-Kachel hinzu": drei Stellen statt sieben.
+2. `docs/anleitung-entwicklung.md` — Modul-Walkthrough (Backend + Frontend) und der neue Abschnitt „Eine Kachel zum Modul".
+3. `.planning/quick/260922-hk4-bilderrahmen-bilder-auf-die-festplatte/260922-hk4-SUMMARY.md` — Dateiablage, wenn das Proxmox-Modul jemals Dateien speichert.
+4. `.planning/STATE.md` — Abschnitte „Current Position" und die letzten Zeilen der Quick-Tabelle.
+
+## Critical Anti-Patterns (do NOT repeat these)
+
+- [ANTI-PATTERN]: Planannahmen ueber den Bestand ungeprueft uebernehmen → m1h: der Plan
+ behauptete, `apps/web` importiere `@tessera/shared` bereits; es gab KEINE
+ Abhaengigkeit, und zwei Kommentare hielten das als Absicht fest. Der Executor
+ hat vor der ersten Zeile Code nachgemessen (Bau, Produktions-Abbild, natives
+ Type-Stripping unter `node:24-alpine`) statt der Annahme zu folgen.
+ **Mitigation:** jede Plan-Behauptung ueber vorhandene Abhaengigkeiten oder
+ Muster vor dem Umsetzen einmal am Code pruefen.
+- [ANTI-PATTERN]: Vorschau und Darstellung mit unterschiedlichen Layoutmassen →
+ ge2: die Kachel nutzte eine andere Rahmenhoehe als die Vorschau, wodurch Seiten
+ mit fensterhoehen-abhaengigem Layout (`vh`) an anderer Stelle lagen als
+ ausgewaehlt. **Mitigation:** Auswahl und Darstellung immer gegen dieselben
+ Masse rechnen.
+- [ANTI-PATTERN]: `position: fixed` in einer Dashboard-Kachel → pi9: die
+ Grossansicht blieb auf die Kachelflaeche beschraenkt, weil `react-grid-item`
+ eine CSS-`transform` traegt und damit zum Bezugsrahmen wird.
+ **Mitigation:** Overlays aus einer Kachel per `createPortal` in `document.body`
+ rendern (Muster: Kalender-Tooltip, jetzt auch `picture-frame-lightbox.tsx`).
+- [ANTI-PATTERN]: Playwright klickt in einem per `transform` skalierten iframe
+ nicht → ge2. **Mitigation:** Klickpunkt umrechnen und per
+ `elementFromPoint` + `mouse.click` pruefen; ist eine Werkzeuggrenze, kein Produktfehler.
+
+## Infrastructure State
+
+- **Lokaler Stack:** `docker compose` mit web, api, db laeuft auf dem Stand
+ `1315f37` (`up -d --build` am 22.09. nachmittags). `up` allein baut NICHT neu.
+ DB ohne Host-Port — Prisma vom Host ueber die Container-IP
+ (`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' tessera-ctl-db-1`,
+ `tessera:tessera_dev`).
+- **Testdaten lokal:** im Admin-Dashboard stehen ein Bilderrahmen (zwei Bilder)
+ und ein XFrame auf `example.com` mit Ausschnitt. Harmlos, darf bleiben.
+- **alpha** (`alpha.tessera.ctl.de`) wurde am 22.09. auf `80a0d23` gezogen; die
+ spaeteren Commits (hk4, m1h) sind dort noch nicht drauf. Basic-Auth am Proxy
+ bleibt — von aussen 401, deshalb Messungen gegen alpha nur am Proxy vorbei
+ (auf dem Testserver `docker compose exec api` gegen `localhost:3001` oder
+ Host-Port 3000).
+- **Live** (`tessera.ctl.de`) laeuft noch auf 1.2.0; der Pull auf 1.3.0 steht beim
+ Nutzer aus.
+- **Desktop-Client:** neuester CI-Stempel `5aa577a` (Lauf 405). Der Nutzer muss
+ ihn einmal per Browser installieren, danach laeuft das Update ueber das Tray.
+
+
+Die Sitzung war eine lange Kette kleiner, vollstaendig abgeschlossener Auftraege.
+Der rote Faden am Ende: Der Nutzer will als naechstes ein Proxmox-Modul, das
+zusaetzlich als Kachel auf dem Dashboard erscheint — und kuenftig sollen weitere
+Module dasselbe tun. Deshalb wurde zuerst das Fundament geraeumt (m1h), damit
+eine Modul-Kachel drei Handgriffe kostet statt sieben und Kacheln gesperrter
+Module automatisch verschwinden. Das Geruest dafuer (`WIDGET_MODULE_SLUGS`,
+serverseitiger Filter in `dashboard.service.ts`) ist vorhanden und noch leer;
+Proxmox waere der erste Eintrag.
+
+Fuer Proxmox selbst ist vorgemerkt: Serveradressen traegt nur ein Administrator
+ein (damit ist die Adresse eine bewusste Freigabe statt beliebiger Eingabe), fuer
+genau diese Adressen werden Zertifikatsfehler toleriert (Muster:
+`favorites/icon-discovery.service.ts`, undici-Dispatcher — Nodes globales `fetch`
+ignoriert ihn), Zugangsdaten verschluesselt per `CryptoService` (Muster
+`ldap-config.service.ts`), Abfrage im Hintergrund je Mandant nach dem Muster
+`dkv-scheduler.service.ts` (`onApplicationBootstrap`, nicht `onModuleInit`).
+
+
+
+Start with: Proxmox-Modul planen (`/gsd-quick` mit eigenem Plan wie bei ge2/hk4) —
+Datenmodell fuer Serverzugaenge (Adresse, Typ `pve|pbs|pmg`, verschluesselter
+Token), Abfrage im Hintergrund je Mandant, Modulskelett nach
+`docs/anleitung-entwicklung.md`, Seite mit Serverliste und Auslastung. Die
+Kachel kommt danach als eigener kleiner Auftrag ueber den neuen Weg. Vorher beim
+Nutzer abholen: Serveradressen und die lesenden API-Token.
+
diff --git a/.planning/HANDOFF.json b/.planning/HANDOFF.json
new file mode 100644
index 0000000..9bb01d1
--- /dev/null
+++ b/.planning/HANDOFF.json
@@ -0,0 +1,45 @@
+{
+ "version": "1.0",
+ "timestamp": "2026-09-22T14:15:00.000Z",
+ "phase": null,
+ "phase_name": "kein laufender Meilenstein — Quick-Tasks nach der Freigabe 1.3.0",
+ "phase_dir": null,
+ "plan": null,
+ "task": null,
+ "total_tasks": null,
+ "status": "paused",
+ "completed_tasks": [
+ {"id": 1, "name": "quick-260921-pi9 Bilderrahmen-Widget", "status": "done", "commit": "737974b,c080580,c3b4597,8bf3601"},
+ {"id": 2, "name": "quick-260921-qd3 XFrame-Widget", "status": "done", "commit": "d63d9f5,20a9eb2"},
+ {"id": 3, "name": "quick-260922-frg Tray-Update nennt den Grund, prueft alle 4 h", "status": "done", "commit": "d73aad1"},
+ {"id": 4, "name": "fast Download-Knoepfe im Desktop-Client", "status": "done", "commit": "747a4d4"},
+ {"id": 5, "name": "quick-260922-ge2 XFrame-Ausschnitt, Zoom, Nur anzeigen", "status": "done", "commit": "445b1d3,30fdd99,cf70a19"},
+ {"id": 6, "name": "Freigabe 1.3.0", "status": "done", "commit": "d146234 (Tag v1.3.0)"},
+ {"id": 7, "name": "quick-260922-hk4 Bilder in den Dateibereich statt in die Datenbank", "status": "done", "commit": "9039cea,8cbfb8b,82472ee"},
+ {"id": 8, "name": "quick-260922-m1h Modul bringt seine Kachel selbst mit", "status": "done", "commit": "56c07c3,8be0725"}
+ ],
+ "remaining_tasks": [
+ {"id": 9, "name": "Proxmox-Modul (PVE/PBS/PMG), nur beobachten — Plan schreiben und bauen", "status": "not_started"},
+ {"id": 10, "name": "Proxmox-Kachel (kompakte Version) ueber den neuen Weg", "status": "not_started"}
+ ],
+ "blockers": [
+ {"description": "Proxmox braucht Zugangsdaten des Nutzers (API-Token, nur lesend) und die Server-Adressen", "type": "human_action", "workaround": "Nutzer legt sie morgen an; Planung und Geruest koennen vorher entstehen"}
+ ],
+ "async_jobs": [],
+ "human_actions_pending": [
+ {"action": "Live-Server auf 1.3.0 ziehen (docker compose -f docker-compose.prod.yml pull && up -d --force-recreate api web)", "context": "Version 1.3.0 ist freigegeben, Abbilder live/v1.3.0 liegen bereit", "blocking": false},
+ {"action": "Neuen Desktop-Client einmal per Browser installieren", "context": "Danach laeuft das Update ueber das Tray-Symbol; Live hatte den Updater bis 1.2.0 nicht", "blocking": false},
+ {"action": "Proxmox-API-Token (nur lesend, z. B. Rolle PVEAuditor) fuer PVE, PBS und PMG anlegen und die Server-Adressen bereithalten", "context": "Voraussetzung fuer das naechste Modul; der Nutzer macht das morgen", "blocking": true}
+ ],
+ "decisions": [
+ {"decision": "Bilderrahmen-Bilder liegen im Dateibereich user-files, nicht als bytea in der Datenbank", "rationale": "Sicherung laeuft per pg_dump von Hand; 30 Bilder a 5 MiB je Benutzer waeren 150 MB pro Benutzer im Abzug. Geschwindigkeit war NICHT das Argument. Dazu Einheitlichkeit mit Avataren und DKV-Exporten.", "phase": null},
+ {"decision": "Spalte data bleibt vorerst stehen, DROP erst nach nachgewiesenem Lauf auf alpha und live", "rationale": "Zweistufige Umstellung; getBytes stellt eine fehlende Datei aus data wieder her (alter pg_dump + leeres Volume).", "phase": null},
+ {"decision": "Widget-Typen an EINER Stelle (packages/shared), Katalog filtert nach Modulzugriff", "rationale": "Vorarbeit fuer Proxmox und weitere Modul-Kacheln; vorher sieben Hartkodierungen je Kachel.", "phase": null},
+ {"decision": "Proxmox zunaechst NUR beobachten, keine Eingriffe; Zugriff ueber die normale Modulfreigabe", "rationale": "Ausdrueckliche Ansage des Nutzers am 22.09.", "phase": null},
+ {"decision": "Kacheln gesperrter Module erscheinen gar nicht erst im Katalog", "rationale": "Ausdrueckliche Ansage des Nutzers am 22.09.", "phase": null},
+ {"decision": "Basic-Auth am Proxy vor alpha bleibt", "rationale": "Entscheidung des Nutzers; aus dem Firmennetz greift eine Ausnahme. Nicht mehr ansprechen.", "phase": null}
+ ],
+ "uncommitted_files": [],
+ "next_action": "Proxmox-Modul planen: Prisma-Modelle fuer Serverzugaenge (Adresse, Typ pve|pbs|pmg, Token verschluesselt per CryptoService), Poller je Mandant nach dem Muster dkv-scheduler (onApplicationBootstrap), Modul-Skelett nach docs/anleitung-entwicklung.md, danach die Kachel ueber den neuen Weg (WIDGET_TYPES + WIDGET_MODULE_SLUGS + registerWidget).",
+ "context_notes": "Sitzung lief ueber 1,5 Tage: zwei neue Widgets, drei Desktop-Korrekturen, Freigabe 1.3.0, Speicherumstellung, Widget-Aufraeumen. Alles gepusht, main == origin/main auf 1315f37, Arbeitsbaum sauber, CI gruen. Der lokale Docker-Stack laeuft mit dem aktuellen Stand; Testfavoriten/Test-Widgets im Admin-Dashboard sind lokal stehen geblieben (harmlos). Naechster Schritt ist inhaltlich klar, haengt aber an den Zugangsdaten des Nutzers."
+}