Finanzmanager/public/static/app.css
fds2610-bot b1712bb7ea Phase 0: Projektgerüst mit nginx, php-fpm und MariaDB
Docker Compose mit drei Services (nginx auf Port 8000), Migrationsmechanik,
Update- und Backup-Skript. Anwendung: Router mit CSRF-Prüfung, Anmeldung und
Ersteinrichtung, zentraler Einstellungsdialog mit Reitern, ein- und
ausschaltbares Debug-Log mit Maskierung von Zugangsdaten.

Layout nach Vorbild des FinanzManagers: feste Navigation links,
Werkzeugleiste oben, Tab-Leiste; Farbschema hell/dunkel/System.

Tests: 51 PHP-Prüfungen und 7 Playwright-Tests, alle grün.
2026-08-09 20:21:42 +02:00

525 lines
12 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Finanzmanager – Grundgestaltung
*
* Layout wie im Lexware FinanzManager: feste Navigation links, Werkzeugleiste
* oben, darunter Tab-Leiste und dichte Datentabellen. Optik moderner: ruhigere
* Farben, mehr Weißraum, klare Typografie.
*
* Farben ausschließlich über Custom Properties. Die helle Palette steht auf
* blankem :root, die dunkle wird an zwei Stellen nachgezogen – einmal für die
* Systemvorgabe, einmal für die ausdrückliche Wahl im Einstellungsdialog.
*/
:root {
--grund: #f4f6f8;
--flaeche: #ffffff;
--flaeche-gedaempft: #eef1f5;
--rand: #d6dce4;
--rand-kraeftig: #b8c2cf;
--text: #1c2530;
--text-gedaempft: #5b6875;
--akzent: #1f6feb;
--akzent-text: #ffffff;
--akzent-schwach: #e5efff;
--navi-grund: #24313f;
--navi-text: #cdd7e2;
--navi-text-aktiv: #ffffff;
--navi-aktiv: #1f6feb;
--positiv: #1a7f4b;
--negativ: #c0392b;
--warnung: #9a6700;
--schatten: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .1);
--radius: 6px;
--schrift: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
--schrift-zahl: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
}
@media (prefers-color-scheme: dark) {
:root:not([data-thema="hell"]) {
--grund: #161b22;
--flaeche: #1c2330;
--flaeche-gedaempft: #232b39;
--rand: #303a49;
--rand-kraeftig: #44506180;
--text: #e5eaf1;
--text-gedaempft: #9aa7b6;
--akzent: #4d8ef7;
--akzent-text: #0d1117;
--akzent-schwach: #1d2b45;
--navi-grund: #10151c;
--navi-text: #9aa7b6;
--navi-text-aktiv: #ffffff;
--navi-aktiv: #2f6fd0;
--positiv: #46b877;
--negativ: #f0705f;
--warnung: #d9a441;
--schatten: 0 1px 2px rgba(0, 0, 0, .4);
}
}
:root[data-thema="dunkel"] {
--grund: #161b22;
--flaeche: #1c2330;
--flaeche-gedaempft: #232b39;
--rand: #303a49;
--rand-kraeftig: #445061;
--text: #e5eaf1;
--text-gedaempft: #9aa7b6;
--akzent: #4d8ef7;
--akzent-text: #0d1117;
--akzent-schwach: #1d2b45;
--navi-grund: #10151c;
--navi-text: #9aa7b6;
--navi-text-aktiv: #ffffff;
--navi-aktiv: #2f6fd0;
--positiv: #46b877;
--negativ: #f0705f;
--warnung: #d9a441;
--schatten: 0 1px 2px rgba(0, 0, 0, .4);
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--grund);
color: var(--text);
font: 15px/1.5 var(--schrift);
-webkit-font-smoothing: antialiased;
}
a { color: var(--akzent); text-decoration: none; }
a:hover { text-decoration: underline; }
code {
font-family: var(--schrift-zahl);
font-size: .9em;
background: var(--flaeche-gedaempft);
padding: .1em .35em;
border-radius: 4px;
}
/* ── Grundraster ─────────────────────────────────────────────────────────── */
.rahmen {
display: grid;
grid-template-columns: 232px 1fr;
min-height: 100vh;
}
.seitenleiste {
background: var(--navi-grund);
color: var(--navi-text);
padding: 0 0 2rem;
position: sticky;
top: 0;
height: 100vh;
overflow-y: auto;
}
.marke {
font-size: 1.05rem;
font-weight: 600;
color: #fff;
padding: 1.25rem 1.25rem 1rem;
letter-spacing: .01em;
}
.seitenleiste ul {
list-style: none;
margin: 0;
padding: 0;
}
.seitenleiste a {
display: flex;
align-items: center;
gap: .7rem;
padding: .6rem 1.25rem;
color: var(--navi-text);
border-left: 3px solid transparent;
font-size: .95rem;
}
.seitenleiste a:hover {
background: rgba(255, 255, 255, .05);
color: var(--navi-text-aktiv);
text-decoration: none;
}
.seitenleiste a.aktiv {
background: var(--navi-aktiv);
border-left-color: #fff;
color: var(--navi-text-aktiv);
font-weight: 500;
}
.seitenleiste .icon {
width: 1.1em;
text-align: center;
opacity: .85;
}
.hauptbereich {
display: flex;
flex-direction: column;
min-width: 0;
}
/* ── Werkzeugleiste ──────────────────────────────────────────────────────── */
.werkzeugleiste {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: .85rem 1.5rem;
background: var(--flaeche);
border-bottom: 1px solid var(--rand);
position: sticky;
top: 0;
z-index: 10;
}
.werkzeugleiste h1 {
margin: 0;
font-size: 1.35rem;
font-weight: 600;
color: var(--akzent);
}
.werkzeuge {
display: flex;
align-items: center;
gap: .75rem;
}
.werkzeug {
background: none;
border: 1px solid transparent;
color: var(--text-gedaempft);
font: inherit;
font-size: .9rem;
padding: .35rem .6rem;
border-radius: var(--radius);
cursor: pointer;
}
.werkzeug:hover {
background: var(--flaeche-gedaempft);
border-color: var(--rand);
color: var(--text);
text-decoration: none;
}
.benutzer {
font-size: .9rem;
color: var(--text-gedaempft);
}
form.inline { display: inline; margin: 0; }
.inhalt {
padding: 1.25rem 1.5rem 3rem;
flex: 1;
min-width: 0;
}
/* ── Tab-Leiste ──────────────────────────────────────────────────────────── */
.tableiste {
display: flex;
gap: .25rem;
border-bottom: 1px solid var(--rand);
margin-bottom: 1.25rem;
overflow-x: auto;
}
.tab {
padding: .5rem .9rem;
border: 1px solid transparent;
border-bottom: none;
border-radius: var(--radius) var(--radius) 0 0;
color: var(--text-gedaempft);
font-size: .93rem;
white-space: nowrap;
}
.tab:hover { background: var(--flaeche-gedaempft); text-decoration: none; }
.tab.aktiv {
background: var(--flaeche);
border-color: var(--rand);
color: var(--text);
font-weight: 500;
margin-bottom: -1px;
padding-bottom: calc(.5rem + 1px);
}
/* ── Kacheln ─────────────────────────────────────────────────────────────── */
.kachelraster {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 1rem;
}
.kachel {
background: var(--flaeche);
border: 1px solid var(--rand);
border-radius: var(--radius);
box-shadow: var(--schatten);
padding: 1rem 1.15rem 1.25rem;
}
.kachel.einzeln { max-width: 640px; }
.kachel header { margin-bottom: .6rem; }
.kachel h2 {
margin: 0;
font-size: 1rem;
font-weight: 600;
}
.phasenmarke {
display: inline-block;
background: var(--akzent-schwach);
color: var(--akzent);
font-size: .8rem;
font-weight: 600;
padding: .15rem .5rem;
border-radius: 999px;
margin: 0 0 .75rem;
}
.platzhalter {
color: var(--text-gedaempft);
font-size: .92rem;
margin: .5rem 0 0;
}
.checkliste {
list-style: none;
margin: 0;
padding: 0;
font-size: .92rem;
}
.checkliste li {
padding: .3rem 0 .3rem 1.5rem;
position: relative;
color: var(--text-gedaempft);
}
.checkliste li::before {
content: "○";
position: absolute;
left: 0;
}
.checkliste li.erledigt { color: var(--text); }
.checkliste li.erledigt::before { content: "●"; color: var(--positiv); }
/* ── Tabellen ────────────────────────────────────────────────────────────── */
table.liste {
width: 100%;
border-collapse: collapse;
background: var(--flaeche);
border: 1px solid var(--rand);
border-radius: var(--radius);
overflow: hidden;
font-size: .92rem;
}
table.liste th,
table.liste td {
padding: .45rem .7rem;
text-align: left;
border-bottom: 1px solid var(--rand);
}
table.liste thead th {
background: var(--flaeche-gedaempft);
font-weight: 600;
color: var(--text-gedaempft);
white-space: nowrap;
}
table.liste tbody tr:last-child td { border-bottom: none; }
table.liste tbody tr:hover { background: var(--flaeche-gedaempft); }
.rechts { text-align: right; }
.betrag {
font-family: var(--schrift-zahl);
font-variant-numeric: tabular-nums;
text-align: right;
white-space: nowrap;
}
.betrag.negativ { color: var(--negativ); }
/* ── Formulare ───────────────────────────────────────────────────────────── */
.formular {
display: flex;
flex-direction: column;
gap: .35rem;
max-width: 380px;
}
.formular.breit {
max-width: 620px;
background: var(--flaeche);
border: 1px solid var(--rand);
border-radius: var(--radius);
padding: 1.25rem;
box-shadow: var(--schatten);
}
.formular label {
font-size: .9rem;
font-weight: 500;
margin-top: .6rem;
}
.formular label.ankreuzfeld {
display: flex;
align-items: center;
gap: .5rem;
font-weight: 500;
}
.formular input[type="text"],
.formular input[type="password"],
.formular input[type="number"],
.formular select {
font: inherit;
padding: .5rem .6rem;
border: 1px solid var(--rand-kraeftig);
border-radius: var(--radius);
background: var(--flaeche);
color: var(--text);
width: 100%;
}
.formular input:focus-visible,
.formular select:focus-visible,
.knopf:focus-visible {
outline: 2px solid var(--akzent);
outline-offset: 1px;
}
.formular h3 {
margin: 1.5rem 0 .5rem;
font-size: .95rem;
}
.feldhinweis {
font-size: .85rem;
color: var(--text-gedaempft);
margin: .15rem 0 0;
}
.optional { font-weight: 400; color: var(--text-gedaempft); }
.knopfleiste {
display: flex;
gap: .6rem;
margin-top: 1.25rem;
}
.knopf {
display: inline-block;
font: inherit;
font-size: .93rem;
padding: .5rem 1rem;
border: 1px solid var(--rand-kraeftig);
border-radius: var(--radius);
background: var(--flaeche);
color: var(--text);
cursor: pointer;
}
.knopf:hover { background: var(--flaeche-gedaempft); text-decoration: none; }
.knopf.primaer {
background: var(--akzent);
border-color: var(--akzent);
color: var(--akzent-text);
font-weight: 500;
margin-top: 1.25rem;
}
.knopf.primaer:hover { filter: brightness(1.08); }
/* ── Meldungen ───────────────────────────────────────────────────────────── */
.meldung {
padding: .65rem .9rem;
border-radius: var(--radius);
border: 1px solid var(--rand);
margin-bottom: 1rem;
font-size: .92rem;
}
.meldung-erfolg { background: var(--akzent-schwach); border-color: var(--akzent); }
.meldung-fehler { background: color-mix(in srgb, var(--negativ) 12%, var(--flaeche)); border-color: var(--negativ); }
.meldung-warnung { background: color-mix(in srgb, var(--warnung) 15%, var(--flaeche)); border-color: var(--warnung); }
.hinweis { color: var(--text-gedaempft); font-size: .93rem; }
/* ── Schlichter Rahmen (Anmeldung, Fehlerseiten) ─────────────────────────── */
body.schlicht {
display: grid;
place-items: center;
min-height: 100vh;
padding: 1.5rem;
}
.karte-mitte {
background: var(--flaeche);
border: 1px solid var(--rand);
border-radius: 10px;
box-shadow: var(--schatten);
padding: 2rem;
width: 100%;
max-width: 400px;
}
.marke.gross {
padding: 0 0 1.25rem;
font-size: 1.3rem;
color: var(--text);
}
/* ── Schmale Fenster ─────────────────────────────────────────────────────── */
@media (max-width: 820px) {
.rahmen { grid-template-columns: 1fr; }
.seitenleiste {
position: static;
height: auto;
padding-bottom: .5rem;
}
.seitenleiste ul {
display: flex;
overflow-x: auto;
}
.seitenleiste a {
border-left: none;
border-bottom: 3px solid transparent;
white-space: nowrap;
}
.seitenleiste a.aktiv {
border-left: none;
border-bottom-color: #fff;
}
}