feat: Phase 0 – Gerüst (FastAPI+SQLite, Multi-User-Login, React-App-Shell, Deploy)
Grundgerüst für Certain Finance: - Backend: FastAPI + SQLAlchemy + SQLite, Alembic-Migrationen (Batch-Mode), argon2-Passwort-Hashing, server-seitige Sitzungen im Cookie, Erst-Admin, Benutzerverwaltung mit Temporär-Passwort, Einstellungen je Benutzer. - Ein Prozess, ein Port: uvicorn liefert API (/api) und gebautes SPA aus, inkl. SPA-Deeplink-Fallback. - Frontend: React 18 + Vite + JSX, Design-Tokens (Light/Dark), i18n DE/EN, Inline-SVG-Icons (keine Emojis), Login, Passwort-ändern, Dashboard-Platzhalter, Benutzer- und Einstellungsseiten. - Deploy: nativer LXC-Installer + Update-Skript (systemd), env-Vorlage, Doku. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
/* Eigene Stil-Ergänzungen für Certain Finance – bewusst getrennt von der aus
|
||||
der Vorlage übernommenen styles.css, damit Basis und Ergänzung sauber bleiben. */
|
||||
|
||||
.brand-mark {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-2);
|
||||
}
|
||||
.brand-name {
|
||||
font-weight: 650;
|
||||
font-size: 1rem;
|
||||
letter-spacing: -0.01em;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
/* Beträge: Vorzeichenfarbe. Grün = Einnahme/im Budget, Rot = Ausgabe/über Budget. */
|
||||
.amount.pos { color: var(--ok); }
|
||||
.amount.neg { color: var(--danger); }
|
||||
.amount.muted { color: var(--muted); }
|
||||
|
||||
/* Umgerechneter Zweitbetrag (Originalwährung -> Hauptwährung) klein und gedämpft. */
|
||||
.amount-converted {
|
||||
color: var(--muted);
|
||||
font-size: 0.82em;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
/* Schlichtes zentriertes Layout für Login / Passwort ändern. */
|
||||
.auth-screen {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: var(--sp-5);
|
||||
background: var(--bg);
|
||||
}
|
||||
.auth-card {
|
||||
width: 100%;
|
||||
max-width: 380px;
|
||||
}
|
||||
.auth-card .brand-mark {
|
||||
justify-content: center;
|
||||
margin-bottom: var(--sp-4);
|
||||
}
|
||||
|
||||
/* Eingabefeld mit angehängtem Icon-Knopf (z. B. Passwort ein-/ausblenden). */
|
||||
.input-with-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-2);
|
||||
}
|
||||
.input-with-button > input {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
/* Leerer Zustand (z. B. Dashboard ohne Karten). */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
color: var(--muted);
|
||||
padding: var(--sp-6) var(--sp-4);
|
||||
}
|
||||
.empty-state .icon {
|
||||
opacity: 0.5;
|
||||
margin-bottom: var(--sp-3);
|
||||
}
|
||||
Reference in New Issue
Block a user