feat(aether): initial commit – self-hosted Cloud, Phasen 1–7

Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA.
Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb,
Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming,
Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office
(Collabora/OnlyOffice).

Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort)
sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Opus 5 committed 2026-08-24 09:25:36 +02:00
commit 31a027c93a
225 files changed
+38042

No files matched your search

+82
View File
@@ -0,0 +1,82 @@
@import "tailwindcss";
/* ── Design tokens (CSS variables) ──────────────────────────────────────────
Admin sets these globally in Phase 4. Users can override their own palette.
Defaults here are the Aether built-in theme. */
:root {
--color-primary: #6366f1;
--color-primary-rgb: 99, 102, 241; /* für halbtransparente Flächen */
--color-primary-fg: #ffffff;
--color-accent: #8b5cf6;
--color-accent-rgb: 139, 92, 246;
--color-accent-fg: #ffffff;
--color-background: #0f172a;
--color-surface: #1e293b;
--color-surface-2: #334155;
--color-border: #334155;
--color-text: #f1f5f9;
--color-text-muted: #94a3b8;
--color-danger: #ef4444;
/* Ordnergelb. Vier Stellen benutzten diesen Namen bereits, definiert war er
nie – die Symbole erschienen deshalb schwarz. */
--color-warning: #f59e0b;
--color-success: #22c55e;
--radius: 0.5rem;
}
body {
background-color: var(--color-background);
color: var(--color-text);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
-webkit-font-smoothing: antialiased;
margin: 0;
/* Kein Gummiband-Scrollen am Rand: In der installierten App sieht ein
Inhalt, der sich über den Anschlag hinausziehen lässt, nach einem Fehler
aus – es gibt ja keine Adressleiste, die dabei mitfährt. */
overscroll-behavior-y: none;
}
/* ── Sichere Bereiche (installierte App) ────────────────────────────────────
Mit viewport-fit=cover reicht die Seite bis unter Statusleiste und
Wischbalken. Ohne diese Abstände säße der obere Rand hinter der Uhr und der
Speicherbalken der Seitenleiste hinter dem Wischbalken – erreichbar wäre er
dann nicht mehr.
**Als Variablen, nicht als Klassen.** Vorher standen hier
`.aether-safe-top { padding-top: env(...) }` und zwei Geschwister – und sie
wirkten nirgends. Alle drei Stellen setzen ihren Abstand als Inline-Stil
(`style={{ padding: '12px 16px' }}`), und ein Inline-Stil schlägt jede
Klasse. Der Abstand wurde also berechnet und sofort überschrieben; in der
installierten App klebte die Kopfleiste an der Statusleiste.
Mit Variablen gibt es diesen Wettstreit nicht: Die Stelle, die den Abstand
ohnehin setzt, rechnet ihn selbst ein –
`paddingTop: 'calc(12px + var(--safe-top))'`.
env() ist auf Geräten ohne Aussparung 0, die Variablen kosten dort nichts.
Nur in der installierten App gesetzt: Im Browser übernimmt die Adressleiste
diese Aufgabe schon. */
:root {
--safe-top: 0px;
--safe-bottom: 0px;
--safe-left: 0px;
}
@media (display-mode: standalone) {
:root {
--safe-top: env(safe-area-inset-top, 0px);
--safe-bottom: env(safe-area-inset-bottom, 0px);
--safe-left: env(safe-area-inset-left, 0px);
}
}
* {
box-sizing: border-box;
}
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--color-surface-2); border-radius: 999px; }
::-webkit-scrollbar-thumb:hover { background: var(--color-text-muted); }
::selection { background: var(--color-primary); color: #fff; }