Der Schalter „nur aktive“ änderte kaum etwas: Neben ihm filterte noch das Σ-Kennzeichen, und stillgelegte Konten tragen es meist nicht – von 17 inaktiven Konten kam beim Ausschalten genau eines dazu. Das Kennzeichen filtert hier nicht mehr mit, der Schalter ist das einzige Kriterium. Balken jetzt 18 Bildpunkte breit mit 3 Punkten Abstand. Damit das auf dem Schirm ankommt, trägt das SVG seine Maße als Attribute und wird nicht mehr auf die Kachel gestreckt. Die Legende steht neben der Zeichnung, die sonst die halbe Kachel leer ließe. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1049 lines
27 KiB
CSS
1049 lines
27 KiB
CSS
/* 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;
|
||
}
|
||
|
||
/* Engere Spalten für das Cockpit: Die Diagrammkachel greift über zwei davon und
|
||
bleibt damit schmal, ohne dass eine Lücke zur Nachbarkachel entsteht. */
|
||
.kachelraster.dicht { grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
|
||
|
||
.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; }
|
||
|
||
/* Ein Diagramm mit zwölf Balken braucht mehr als eine Spalte – aber nicht die
|
||
ganze Zeile: über zwei Spalten bleibt es lesbar und die Kachel handlich. Unter
|
||
der Umbruchbreite muss der Ausgriff weg, sonst erzwänge er eine zweite Spalte,
|
||
die dort nicht mehr hineinpasst (siehe Media Query am Dateiende). */
|
||
.kachel.breit { grid-column: span 2; }
|
||
|
||
.kachel header { margin-bottom: .6rem; }
|
||
|
||
.kachel header.mitschalter {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: 1rem;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
/* Der Text gibt nach, damit der Schalter oben rechts stehen bleibt und nicht
|
||
unter die Überschrift rutscht; erst ganz schmal bricht die Zeile um. */
|
||
.kachel header.mitschalter > div {
|
||
flex: 1 1 11rem;
|
||
min-width: 0;
|
||
}
|
||
|
||
.kachelhinweis {
|
||
margin: .25rem 0 0;
|
||
color: var(--text-gedaempft);
|
||
font-size: .85rem;
|
||
}
|
||
|
||
.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); }
|
||
|
||
/* ── Diagramme ───────────────────────────────────────────────────────────────
|
||
|
||
Selbst erzeugtes SVG, keine Diagrammbibliothek. Die Farbe eines Kontos steht
|
||
als Klasse am Element: Ein fill-Attribut ginge zwar an der CSP vorbei, könnte
|
||
aber nicht auf das dunkle Thema reagieren. Jede Serie setzt --farbe, davon
|
||
leben Balken (fill) und Legendenpunkt (background) gleichermaßen. */
|
||
.serie-1 { --farbe: #4c78a8; }
|
||
.serie-2 { --farbe: #f58518; }
|
||
.serie-3 { --farbe: #54a24b; }
|
||
.serie-4 { --farbe: #e45756; }
|
||
.serie-5 { --farbe: #72b7b2; }
|
||
.serie-6 { --farbe: #b279a2; }
|
||
.serie-7 { --farbe: #d8b02c; }
|
||
.serie-8 { --farbe: #9d755d; }
|
||
.serie-9 { --farbe: #2f8f8a; }
|
||
.serie-10 { --farbe: #8f8ad4; }
|
||
.serie-11 { --farbe: #e07b91; }
|
||
.serie-12 { --farbe: #7b8a99; }
|
||
|
||
/* Das SVG bringt seine Maße als Attribute mit und wird nicht auf die Kachel
|
||
gestreckt: Nur so sind die 18 Punkte Balkenbreite auch 18 Bildpunkte. Erst
|
||
wenn die Kachel schmaler wird als die Zeichnung, skaliert sie mit. */
|
||
.diagrammbereich {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: flex-start;
|
||
gap: .5rem 1.5rem;
|
||
}
|
||
|
||
.diagramm {
|
||
max-width: 100%;
|
||
height: auto;
|
||
display: block;
|
||
overflow: visible;
|
||
flex: 0 1 auto;
|
||
}
|
||
|
||
.diagramm rect { fill: var(--farbe); }
|
||
|
||
.diagramm-gitter {
|
||
stroke: var(--rand);
|
||
stroke-width: 1;
|
||
}
|
||
|
||
.diagramm-nulllinie {
|
||
stroke: var(--rand-kraeftig);
|
||
stroke-width: 1.5;
|
||
}
|
||
|
||
.diagramm-achse,
|
||
.diagramm-beschriftung {
|
||
fill: var(--text-gedaempft);
|
||
font-family: var(--schrift);
|
||
font-size: 10px;
|
||
}
|
||
|
||
/* Ziffernschrift für die Achse, aber schmal genug für 21 Punkte Spaltenabstand
|
||
bleiben die Monatskürzel darunter. */
|
||
.diagramm-achse {
|
||
font-family: var(--schrift-zahl);
|
||
font-size: 11px;
|
||
}
|
||
|
||
.diagramm-beschriftung.schwach { opacity: .7; }
|
||
|
||
/* Neben der Zeichnung statt darunter: Die schmale Zeichnung ließe sonst die
|
||
halbe Kachel leer. */
|
||
.diagrammlegende {
|
||
list-style: none;
|
||
margin: 0;
|
||
padding: 0;
|
||
flex: 1 1 11rem;
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
|
||
gap: .1rem 1.2rem;
|
||
font-size: .88rem;
|
||
align-content: start;
|
||
}
|
||
|
||
.diagrammlegende li {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: .5rem;
|
||
padding: .15rem 0;
|
||
}
|
||
|
||
.legendenfarbe {
|
||
width: .8rem;
|
||
height: .8rem;
|
||
border-radius: 2px;
|
||
background: var(--farbe);
|
||
flex: none;
|
||
}
|
||
|
||
.legendenname {
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* ── Ein/Aus-Schalter ────────────────────────────────────────────────────────
|
||
|
||
Die Bahn mit dem laufenden Knopf, wie man ihn von Mobilgeräten kennt. Ein
|
||
abschickender Knopf statt eines Ankreuzfelds: Ohne Inline-Skript könnte ein
|
||
Ankreuzfeld sein Formular nicht selbst abschicken, und Inline-Skripte
|
||
verbietet die Content-Security-Policy. */
|
||
.schalterform { margin: 0; }
|
||
|
||
.schalter {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: .5rem;
|
||
padding: .15rem;
|
||
border: none;
|
||
border-radius: var(--radius);
|
||
background: none;
|
||
color: var(--text-gedaempft);
|
||
font: inherit;
|
||
font-size: .85rem;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.schalter[aria-checked="true"] { color: var(--text); }
|
||
|
||
.schalter:focus-visible {
|
||
outline: 2px solid var(--akzent);
|
||
outline-offset: 1px;
|
||
}
|
||
|
||
.schalterbahn {
|
||
position: relative;
|
||
flex: none;
|
||
width: 2.3rem;
|
||
height: 1.25rem;
|
||
border-radius: 999px;
|
||
background: var(--rand-kraeftig);
|
||
transition: background .15s ease;
|
||
}
|
||
|
||
.schalterknopf {
|
||
position: absolute;
|
||
top: .15rem;
|
||
left: .15rem;
|
||
width: .95rem;
|
||
height: .95rem;
|
||
border-radius: 50%;
|
||
background: #fff;
|
||
box-shadow: 0 1px 2px rgb(0 0 0 / 35%);
|
||
transition: transform .15s ease;
|
||
}
|
||
|
||
.schalter[aria-checked="true"] .schalterbahn { background: var(--akzent); }
|
||
.schalter[aria-checked="true"] .schalterknopf { transform: translateX(1.05rem); }
|
||
|
||
/* ── 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); }
|
||
|
||
.nowrap { white-space: nowrap; }
|
||
|
||
/* Gliederung der Kontenübersicht: Gruppenkopf, Gruppensumme, Gesamtsumme. */
|
||
table.liste tr.gruppenzeile th {
|
||
background: var(--flaeche-gedaempft);
|
||
border-top: 1px solid var(--rand);
|
||
font-size: .85rem;
|
||
letter-spacing: .03em;
|
||
text-transform: uppercase;
|
||
color: var(--text-gedaempft);
|
||
}
|
||
|
||
table.liste tr.gruppensumme td {
|
||
font-weight: 600;
|
||
background: color-mix(in srgb, var(--flaeche-gedaempft) 55%, var(--flaeche));
|
||
}
|
||
|
||
table.liste tfoot tr.summenzeile td {
|
||
font-weight: 700;
|
||
border-top: 2px solid var(--rand-kraeftig);
|
||
background: var(--flaeche-gedaempft);
|
||
}
|
||
|
||
table.liste tr.inaktiv td { color: var(--text-gedaempft); }
|
||
|
||
table.liste input[type="text"],
|
||
table.liste input[type="number"] {
|
||
width: 100%;
|
||
padding: .25rem .4rem;
|
||
border: 1px solid var(--rand);
|
||
border-radius: 4px;
|
||
background: var(--flaeche);
|
||
color: var(--text);
|
||
font: inherit;
|
||
}
|
||
|
||
table.liste input.schmal { width: 5rem; }
|
||
|
||
/* ── Budgetplaner ────────────────────────────────────────────────────────────
|
||
|
||
Zwölf Monatsspalten passen auf keinen Bildschirm: Die Tabelle scrollt in
|
||
ihrem eigenen Rahmen, die Kategoriespalte bleibt dabei stehen. */
|
||
.breittabelle {
|
||
overflow-x: auto;
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
table.budgetplaner { min-width: 100%; }
|
||
|
||
table.budgetplaner th,
|
||
table.budgetplaner td {
|
||
padding: .3rem .5rem;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
table.budgetplaner .spalte-kategorie {
|
||
position: sticky;
|
||
left: 0;
|
||
z-index: 1;
|
||
background: var(--flaeche);
|
||
min-width: 16rem;
|
||
}
|
||
|
||
table.budgetplaner thead .spalte-kategorie,
|
||
table.budgetplaner tfoot .spalte-kategorie { background: var(--flaeche-gedaempft); }
|
||
|
||
table.budgetplaner tbody tr:hover .spalte-kategorie { background: var(--flaeche-gedaempft); }
|
||
|
||
table.budgetplaner th.gruppenkopf {
|
||
text-align: center;
|
||
border-left: 1px solid var(--rand);
|
||
}
|
||
|
||
/* Der laufende Monat ist die Spalte, auf die man zuerst schaut. */
|
||
table.budgetplaner .laufend { background: color-mix(in srgb, var(--akzent) 8%, transparent); }
|
||
|
||
table.budgetplaner tr.summenzeile-kategorie td { font-weight: 600; }
|
||
|
||
/* Breit genug für „123.456,78“ – eine Stelle mehr, als der Haushalt braucht. */
|
||
table.budgetplaner input.betragsfeld {
|
||
width: 7rem;
|
||
text-align: right;
|
||
font-family: var(--schrift-zahl);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
table.budgetplaner td.rechts {
|
||
font-family: var(--schrift-zahl);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
/* Zahnrad vor jedem Eingabefeld: verteilt den Wert über die Zeile. Das Menü
|
||
dazu gibt es nur einmal; app.js hängt es in die angeklickte Zelle, die es
|
||
deshalb verankern muss. Positioniert wird über CSS, nicht über ein per
|
||
JavaScript gesetztes style-Attribut – das verwürfe die
|
||
Content-Security-Policy (style-src 'self'). */
|
||
table.budgetplaner td.budgetzelle { position: relative; }
|
||
|
||
.zahnrad {
|
||
border: none;
|
||
background: none;
|
||
color: var(--text-gedaempft);
|
||
cursor: pointer;
|
||
font-size: .85rem;
|
||
line-height: 1;
|
||
/* Ein Drittel des früheren Abstands: Der kam aus diesem Padding plus dem
|
||
Leerzeichen im Markup, das die Zelle in Ziffernschrift breit setzte. */
|
||
padding: 0 .27rem 0 0;
|
||
}
|
||
|
||
.zahnrad:hover,
|
||
.zahnrad[aria-expanded="true"] { color: var(--akzent); }
|
||
|
||
.zahnradmenue {
|
||
position: absolute;
|
||
top: 100%;
|
||
right: .3rem;
|
||
z-index: 3;
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-width: 10rem;
|
||
padding: .2rem;
|
||
border: 1px solid var(--rand-kraeftig);
|
||
border-radius: var(--radius);
|
||
background: var(--flaeche);
|
||
box-shadow: 0 4px 12px rgb(0 0 0 / 18%);
|
||
}
|
||
|
||
/* Fließtext, nicht Zahlensatz: Die Zelle vererbt sonst ihre Ziffernschrift. */
|
||
.menueeintrag {
|
||
border: none;
|
||
background: none;
|
||
color: var(--text);
|
||
cursor: pointer;
|
||
font: inherit;
|
||
font-family: var(--schrift);
|
||
font-size: .88rem;
|
||
text-align: left;
|
||
padding: .35rem .5rem;
|
||
border-radius: var(--radius);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.menueeintrag:hover { background: var(--flaeche-gedaempft); }
|
||
|
||
/* Aufklappen des Kategoriebaums; ohne JavaScript bleibt alles sichtbar. */
|
||
.klappknopf {
|
||
border: none;
|
||
background: none;
|
||
color: var(--text-gedaempft);
|
||
cursor: pointer;
|
||
font: inherit;
|
||
padding: 0 .3rem 0 0;
|
||
}
|
||
|
||
.klappknopf[aria-expanded="false"] { transform: rotate(-90deg); display: inline-block; }
|
||
|
||
tr.zugeklappt { display: none; }
|
||
|
||
/* Einrückung des Kategoriebaums. Die Ebene steht als data-Attribut an der
|
||
Zeile – so bleibt die Tabelle frei von verschachtelten Elementen. Kein
|
||
style-Attribut: Die Content-Security-Policy (style-src 'self') verwirft
|
||
Inline-Styles, die Einrückung fiele stillschweigend aus. */
|
||
.baumname {
|
||
display: inline-block;
|
||
padding-left: 0;
|
||
}
|
||
|
||
.baumname[data-ebene="1"] { padding-left: 1.4rem; }
|
||
.baumname[data-ebene="2"] { padding-left: 2.8rem; }
|
||
.baumname[data-ebene="3"] { padding-left: 4.2rem; }
|
||
.baumname[data-ebene="4"] { padding-left: 5.6rem; }
|
||
.baumname[data-ebene="5"] { padding-left: 7rem; }
|
||
.baumname[data-ebene="6"] { padding-left: 8.4rem; }
|
||
|
||
.nebentext {
|
||
color: var(--text-gedaempft);
|
||
font-size: .88rem;
|
||
}
|
||
|
||
.marke {
|
||
display: inline-block;
|
||
padding: .05rem .4rem;
|
||
border: 1px solid var(--rand-kraeftig);
|
||
border-radius: 999px;
|
||
font-size: .75rem;
|
||
color: var(--text-gedaempft);
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.kennzahl {
|
||
font-family: var(--schrift-zahl);
|
||
font-size: 2rem;
|
||
font-weight: 600;
|
||
margin: .2rem 0;
|
||
}
|
||
|
||
.protokoll {
|
||
margin: .4rem 0 0;
|
||
padding-left: 1.1rem;
|
||
font-size: .9rem;
|
||
}
|
||
|
||
.protokoll li.fehler { color: var(--negativ); }
|
||
|
||
/* ── Aktionsleiste über den Listen ───────────────────────────────────────── */
|
||
|
||
.seitenaktionen {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: .5rem;
|
||
margin-bottom: 1rem;
|
||
}
|
||
|
||
.seitenaktionen .fuellung { flex: 1; }
|
||
|
||
.saldoanzeige {
|
||
font-size: .9rem;
|
||
color: var(--text-gedaempft);
|
||
}
|
||
|
||
.saldoanzeige strong {
|
||
margin-left: .35rem;
|
||
font-family: var(--schrift-zahl);
|
||
font-size: 1.05rem;
|
||
color: var(--text);
|
||
}
|
||
|
||
.saldoanzeige strong.negativ { color: var(--negativ); }
|
||
|
||
/* ── Kontoblatt ──────────────────────────────────────────────────────────── */
|
||
|
||
.filterleiste {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
gap: .5rem;
|
||
margin-bottom: 1rem;
|
||
padding: .6rem .75rem;
|
||
background: var(--flaeche);
|
||
border: 1px solid var(--rand);
|
||
border-radius: var(--radius);
|
||
}
|
||
|
||
.filterleiste input[type="search"],
|
||
.filterleiste input[type="date"],
|
||
.filterleiste select {
|
||
padding: .3rem .45rem;
|
||
border: 1px solid var(--rand);
|
||
border-radius: 4px;
|
||
background: var(--flaeche);
|
||
color: var(--text);
|
||
font: inherit;
|
||
font-size: .9rem;
|
||
}
|
||
|
||
.filterleiste input[type="search"] { min-width: 16rem; }
|
||
.filterleiste select { max-width: 15rem; }
|
||
.filterleiste label { font-size: .88rem; color: var(--text-gedaempft); }
|
||
|
||
table.kontoblatt { font-size: .89rem; }
|
||
table.kontoblatt td { padding: .3rem .6rem; }
|
||
table.kontoblatt tr.gegensicht td { background: color-mix(in srgb, var(--akzent) 5%, transparent); }
|
||
|
||
.gekuerzt {
|
||
max-width: 26rem;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.blaettern {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: .75rem;
|
||
margin-top: .8rem;
|
||
}
|
||
|
||
/* Die Splittabelle sitzt im Formular und braucht schmalere Zellen. */
|
||
table.splittabelle td { padding: .3rem .4rem; }
|
||
table.splittabelle select { max-width: 14rem; width: 100%; }
|
||
table.splittabelle input.rechts { text-align: right; }
|
||
|
||
.buchungsmaske [hidden] { display: none; }
|
||
|
||
/* ── 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;
|
||
}
|
||
|
||
/* Mehrfachauswahl im Formular – etwa die Konten einer Kontengruppe. Bei vielen
|
||
Einträgen scrollt die Liste, statt das Formular auseinanderzuziehen. */
|
||
.auswahlliste {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: .35rem;
|
||
max-height: 22rem;
|
||
overflow-y: auto;
|
||
padding: .6rem .7rem;
|
||
border: 1px solid var(--rand);
|
||
border-radius: var(--radius);
|
||
background: var(--flaeche-gedaempft);
|
||
}
|
||
|
||
.auswahlliste .ankreuzfeld { margin: 0; }
|
||
|
||
.auswahlliste .nebentext { margin-left: .35rem; }
|
||
|
||
.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; }
|
||
|
||
/* Kein eigener Außenabstand: der primäre Knopf steht sonst in jeder Knopfleiste
|
||
um genau diesen Betrag tiefer als seine Nachbarn. Den Abstand nach oben setzt
|
||
allein die .knopfleiste. */
|
||
.knopf.primaer {
|
||
background: var(--akzent);
|
||
border-color: var(--akzent);
|
||
color: var(--akzent-text);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.knopf.primaer:hover { filter: brightness(1.08); }
|
||
|
||
.knopf.klein {
|
||
padding: .25rem .6rem;
|
||
font-size: .85rem;
|
||
}
|
||
|
||
/* Ein Knopf, der die gerade gewählte Ansicht markiert – etwa die drei
|
||
Spaltenbilder des Budgetplaners. */
|
||
.knopf.aktiv {
|
||
background: var(--akzent-schwach);
|
||
border-color: var(--akzent);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.knopf.gefahr {
|
||
border-color: var(--negativ);
|
||
color: var(--negativ);
|
||
background: var(--flaeche);
|
||
}
|
||
|
||
.knopf.gefahr:hover { background: color-mix(in srgb, var(--negativ) 12%, var(--flaeche)); }
|
||
|
||
.feldwert { margin: .1rem 0 .3rem; }
|
||
|
||
/* ── 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); }
|
||
|
||
/* Erfolgsmeldungen blenden sich nach einigen Sekunden aus (app.js). */
|
||
.meldung.verblasst {
|
||
opacity: 0;
|
||
transition: opacity .4s;
|
||
}
|
||
.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; }
|
||
|
||
/* Einspaltiges Raster: Ein Ausgriff über zwei Spalten erzwänge hier eine
|
||
zweite Spalte und damit den waagerechten Rollbalken. */
|
||
.kachel.breit { grid-column: auto; }
|
||
|
||
.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;
|
||
}
|
||
}
|