Files
certain/web/src/finance.css
T
GuidoandClaude Opus 5 e93f565629 fix: Einstellungskarten in feste Spalten statt Spaltenfluss
Beim Abrufen und beim Bearbeiten sprang die halbe Seite. Ursache war der
CSS-Spaltenfluss: Aendert eine Karte ihre Hoehe, verteilt der Browser ALLE
Karten neu auf die Spalten. Ich hatte das zweimal am Symptom kuriert
(Formular in den Dialog verschoben), aber die naechste wachsende Karte
brachte es zurueck.

Jetzt bekommt jede Karte fest ihre Spalte. Waechst eine, verschiebt sich
nur, was in derselben Spalte darunter steht. Die Spaltenzahl kommt aus der
tatsaechlichen Containerbreite (ResizeObserver), nicht aus der
Fensterbreite – in der schmalen Seitenleisten-Ansicht stimmte das sonst
nicht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 20:54:03 +02:00

1100 lines
22 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.
/* 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-logo {
display: block;
flex: 0 0 auto;
}
.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;
min-width: 0;
}
/* Flex-Kinder dürfen schrumpfen – sonst drängt ein 100%-breites select/input
ein danebenliegendes Feld auf 0 (das war der Grund für das winzige IBAN-Feld). */
.row > * {
min-width: 0;
}
/* 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);
}
/* Farbiges Icon-Plättchen (Konten/Kategorien). */
.icon-chip {
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-sm);
flex: 0 0 auto;
}
/* Betrag + umgerechneter Wert (rechtsbündig gestapelt). */
.money {
display: inline-flex;
flex-direction: column;
align-items: flex-end;
line-height: 1.3;
}
.money .amount {
font-variant-numeric: tabular-nums;
font-weight: 560;
}
/* Icon-Auswahlgitter. */
.icon-picker {
display: flex;
flex-wrap: wrap;
gap: var(--sp-2);
margin-top: 5px;
}
.icon-picker-item {
width: 38px;
height: 38px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid var(--border-strong);
border-radius: var(--radius-sm);
background: var(--surface);
color: var(--muted);
cursor: pointer;
transition: border-color .12s, color .12s, background .12s;
}
.icon-picker-item:hover {
color: var(--text);
background: var(--surface-2);
}
.icon-picker-item.selected {
background: var(--accent-soft);
}
/* Farbwähler-Zeile. */
.color-row {
display: flex;
align-items: center;
gap: var(--sp-2);
margin-top: 5px;
}
.color-row input[type="color"] {
width: 44px;
height: 34px;
padding: 2px;
cursor: pointer;
}
/* Name + Icon nebeneinander (Listen). */
.named {
display: flex;
align-items: center;
gap: var(--sp-3);
min-width: 0;
}
.named .named-text {
min-width: 0;
}
.named .named-sub {
color: var(--muted);
font-size: 0.8rem;
}
/* Kategorien-Verwaltung: durchgehende Liste in EINER Karte, die Gruppen nur als
dezente Zwischenüberschrift dazwischen (keine abgesetzten Gruppen-Karten). */
.cat-section + .cat-section {
margin-top: var(--sp-5);
}
.cat-section-head {
display: flex;
align-items: center;
gap: var(--sp-2);
padding-bottom: var(--sp-2);
margin-bottom: 2px;
border-bottom: 2px solid var(--border-strong);
}
.cat-section-name {
flex: 1;
min-width: 0;
font-size: 1.05rem;
font-weight: 650;
}
.cat-row {
display: flex;
align-items: center;
gap: var(--sp-3);
padding: 9px 4px;
border-bottom: 1px solid var(--border);
}
.cat-section .cat-row:last-child {
border-bottom: none;
}
.cat-row:hover {
background: var(--surface-2);
}
.cat-row .grow {
flex: 1;
min-width: 0;
}
/* Seitenkopf mit Titel + Aktion rechts. */
.page-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--sp-3);
margin-bottom: var(--sp-4);
}
.page-head h1 {
margin: 0;
}
/* Konten. */
.account-total {
display: flex;
align-items: baseline;
justify-content: space-between;
padding-bottom: var(--sp-3);
margin-bottom: var(--sp-2);
border-bottom: 1px solid var(--border);
}
.account-total strong {
font-size: 1.2rem;
font-variant-numeric: tabular-nums;
}
.account-list {
display: flex;
flex-direction: column;
}
.account-row {
display: flex;
align-items: center;
gap: var(--sp-3);
padding: var(--sp-3) 0;
border-bottom: 1px solid var(--border);
}
.account-row:last-child {
border-bottom: none;
}
.row-actions {
display: flex;
gap: 4px;
flex: 0 0 auto;
}
/* Filterleiste. */
.filter-bar {
display: flex;
gap: var(--sp-3);
flex-wrap: wrap;
margin-bottom: var(--sp-4);
}
.filter-bar select {
width: auto;
min-width: 160px;
margin-top: 0;
}
/* Segmentierte Umschaltung (Ausgabe/Einnahme/Transfer). */
.seg {
display: flex;
border: 1px solid var(--border-strong);
border-radius: var(--radius-sm);
overflow: hidden;
margin-bottom: var(--sp-4);
}
.seg-btn {
flex: 1;
padding: 8px 10px;
border: none;
background: var(--surface);
color: var(--muted);
font-weight: 560;
cursor: pointer;
border-right: 1px solid var(--border);
}
.seg-btn:last-child {
border-right: none;
}
.seg-btn.active {
background: var(--accent);
color: #fff;
}
.nowrap {
white-space: nowrap;
}
/* Nimmt den freien Platz in einer Flex-Zeile und darf schrumpfen (Ellipsis). */
.grow {
flex: 1 1 auto;
min-width: 0;
}
/* Nutzer-Chip in der Seitenleisten-Fußzeile ist ein Link auf „Mein Konto". */
a.sidebar-user {
text-decoration: none;
border-radius: var(--radius-sm);
padding: 2px 4px;
margin: -2px -4px;
transition: background .12s;
}
a.sidebar-user:hover {
background: var(--surface-2);
}
a.sidebar-user:hover .name {
color: var(--accent);
}
/* Budget: mehrere Monate nebeneinander. */
.budget-months {
display: grid;
gap: var(--sp-4);
grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr));
align-items: start;
}
@media (max-width: 820px) {
.budget-months {
grid-template-columns: 1fr;
}
}
.budget-col {
min-width: 0;
}
.budget-col-head {
display: flex;
align-items: center;
gap: 4px;
padding-bottom: var(--sp-2);
margin-bottom: var(--sp-2);
border-bottom: 2px solid var(--border-strong);
}
.budget-col-head strong {
font-size: 1.05rem;
}
.budget-col-income {
display: flex;
align-items: center;
gap: var(--sp-2);
padding: 4px 0 var(--sp-2);
margin-bottom: var(--sp-2);
border-bottom: 1px solid var(--border);
}
.budget-crow {
display: flex;
align-items: center;
gap: var(--sp-2);
padding: 6px 0;
border-bottom: 1px solid var(--border);
}
.budget-crow:last-child {
border-bottom: none;
}
.budget-crow .amount.small {
flex: 0 0 auto;
}
/* Budget. */
.budget-navbar {
display: flex;
align-items: center;
gap: var(--sp-3);
}
.budget-month {
font-size: 1.05rem;
min-width: 170px;
text-align: center;
}
.flip {
transform: rotate(180deg);
}
.budget-group + .budget-group {
margin-top: var(--sp-4);
}
.budget-group-head {
display: flex;
align-items: center;
gap: var(--sp-2);
padding: var(--sp-2) 0;
margin-bottom: 4px;
border-bottom: 2px solid var(--border-strong);
}
.budget-cat {
display: flex;
align-items: center;
gap: var(--sp-3);
padding: 7px 0;
border-bottom: 1px solid var(--border);
}
.budget-cat:last-child {
border-bottom: none;
}
.budget-cat-name {
display: flex;
align-items: center;
gap: var(--sp-2);
min-width: 0;
}
.budget-cat-bar {
flex: 1;
}
.amount-input {
width: 96px;
text-align: right;
margin-top: 0;
padding: 5px 8px;
font-variant-numeric: tabular-nums;
}
.budget-actual {
width: 96px;
text-align: right;
font-variant-numeric: tabular-nums;
}
.budget-slash {
margin: 0 -4px;
}
.budget-bar {
height: 7px;
background: var(--surface-2);
border-radius: 4px;
overflow: hidden;
}
.budget-bar-fill {
height: 100%;
background: var(--ok);
border-radius: 4px;
transition: width 0.2s;
}
.budget-bar-fill.over {
background: var(--danger);
}
.budget-total-row.card-total {
display: flex;
align-items: center;
gap: var(--sp-2);
padding-top: var(--sp-3);
margin-top: var(--sp-2);
border-top: 2px solid var(--border-strong);
}
tr.budget-total-row td {
border-top: 2px solid var(--border-strong);
padding-top: var(--sp-2);
}
/* Sparen-Option im Transfer-Formular. */
.savings-opt {
padding: var(--sp-3);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--surface-2);
margin-bottom: var(--sp-4);
}
.checkline {
display: flex;
align-items: center;
gap: var(--sp-2);
margin-bottom: var(--sp-2);
}
.checkline span {
color: var(--text);
font-weight: 560;
}
/* ---------- Dashboard-Grid ---------- */
.dash-toolbar {
display: flex;
align-items: center;
gap: var(--sp-2);
position: relative;
}
.dash-add {
position: relative;
}
.dash-add-menu {
position: absolute;
right: 0;
top: calc(100% + 4px);
z-index: 20;
background: var(--surface);
border: 1px solid var(--border-strong);
border-radius: var(--radius-sm);
box-shadow: var(--shadow);
min-width: 200px;
overflow: hidden;
}
.dash-add-item {
display: block;
width: 100%;
text-align: left;
padding: 8px 12px;
border: none;
background: none;
color: var(--text);
cursor: pointer;
}
.dash-add-item:hover {
background: var(--surface-2);
}
/* Karten-Optionen im Anordnen-Modus (z. B. Gruppen vs. Kategorien). */
.dash-config-bar {
display: flex;
flex-wrap: wrap;
gap: var(--sp-3);
padding-bottom: var(--sp-2);
margin-bottom: var(--sp-2);
border-bottom: 1px solid var(--border);
}
.dash-config-opt {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
min-width: 0;
flex: 1 1 140px;
}
.seg.sm {
margin-bottom: 0;
width: 100%;
}
.seg.sm .seg-btn {
padding: 4px 9px;
font-size: 0.78rem;
}
.dash-grid {
position: relative;
}
.dash-card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow);
display: flex;
flex-direction: column;
overflow: hidden;
}
.dash-card-head {
display: flex;
align-items: center;
gap: var(--sp-2);
padding: 8px 12px;
border-bottom: 1px solid var(--border);
flex: 0 0 auto;
}
.dash-card-title {
font-size: 0.7rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--muted);
font-weight: 650;
flex: 1;
}
.dash-grid.editing .dash-card-head {
cursor: move;
background: var(--surface-2);
}
.dash-remove {
color: var(--danger);
}
.dash-card-body {
flex: 1;
min-height: 0;
overflow: auto;
padding: var(--sp-3);
}
.dash-list {
display: flex;
flex-direction: column;
gap: 2px;
}
.dash-line {
display: flex;
align-items: center;
gap: var(--sp-2);
padding: 6px 0;
border-bottom: 1px solid var(--border);
}
.dash-line:last-child {
border-bottom: none;
}
.dash-total {
display: flex;
align-items: baseline;
gap: var(--sp-2);
padding-top: var(--sp-2);
margin-top: 2px;
border-top: 2px solid var(--border-strong);
font-variant-numeric: tabular-nums;
}
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dash-loading, .dash-empty {
padding: var(--sp-4);
text-align: center;
}
.dash-progress {
padding: 6px 0;
}
.dash-progress-top {
display: flex;
align-items: center;
gap: var(--sp-2);
margin-bottom: 4px;
}
.dash-kpis {
display: flex;
flex-direction: column;
justify-content: center;
gap: var(--sp-2);
height: 100%;
}
.dash-kpi {
display: flex;
align-items: baseline;
justify-content: space-between;
}
.dash-kpi strong {
font-size: 1.1rem;
font-variant-numeric: tabular-nums;
}
/* react-grid-layout: Platzhalter + Resize-Griff an das Theme angleichen. */
.react-grid-item.react-grid-placeholder {
background: var(--accent);
opacity: 0.15;
border-radius: var(--radius);
}
.react-grid-item > .react-resizable-handle::after {
border-right-color: var(--border-strong);
border-bottom-color: var(--border-strong);
}
/* ---------- CSV-Import ---------- */
.table-scroll {
overflow-x: auto;
}
.raw-table {
font-size: 0.8rem;
}
.raw-table th,
.raw-table td {
white-space: nowrap;
max-width: 220px;
overflow: hidden;
text-overflow: ellipsis;
}
.raw-table th {
color: var(--muted);
font-weight: 600;
}
.map-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
gap: var(--sp-3);
margin-top: var(--sp-3);
}
.map-grid label {
margin-bottom: 0;
}
tr.row-invalid {
opacity: 0.45;
}
tr.row-dup {
opacity: 0.55;
}
.doc-text {
max-height: 240px;
overflow: auto;
font-size: 0.78rem;
white-space: pre-wrap;
color: var(--muted);
background: var(--surface-2);
padding: var(--sp-3);
border-radius: var(--radius-sm);
margin-top: var(--sp-2);
}
/* Beleg-Seiten als Bildstreifen (horizontal scrollbar). */
.doc-pages {
display: flex;
gap: var(--sp-3);
overflow-x: auto;
padding-bottom: var(--sp-2);
}
.doc-page {
height: 440px;
width: auto;
flex: 0 0 auto;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: #fff;
}
.import-more {
margin-top: var(--sp-3);
}
.import-more > summary {
cursor: pointer;
}
/* DataTable-Zellen einzeilig halten, damit „…" greift (Excel-artig). */
.datatable td { white-space: nowrap; vertical-align: middle; }
.datatable td .named-text { min-width: 0; }
/* Interaktive Zellen (Import-Prüfansicht) füllen ihre Spalte, statt auf 60% zu
schrumpfen (globale .table td select/input-Regel überschreiben). */
.datatable td select,
.datatable td input[inputmode],
.datatable td input[type="text"] { max-width: none; width: 100%; }
.datatable td .catsel { width: 100%; }
/* ---------- Kategorie-Auswahl (auf-/zuklappbarer Baum, Ersatz für <select>) ---------- */
.catsel {
width: 100%;
}
.catsel-btn {
width: 100%;
margin-top: 5px;
display: flex;
align-items: center;
gap: var(--sp-2);
padding: 7px 10px;
border: 1px solid var(--border-strong);
border-radius: var(--radius-sm);
background: var(--surface);
color: var(--text);
font: inherit;
text-align: left;
cursor: pointer;
transition: border-color .12s, box-shadow .12s;
}
.catsel-btn:hover:not(:disabled) {
border-color: var(--accent);
}
.catsel-btn:disabled {
opacity: 0.6;
cursor: default;
}
.catsel-btn.open {
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.catsel-value {
flex: 1 1 auto;
min-width: 0;
display: flex;
align-items: center;
gap: var(--sp-2);
}
.catsel-caret {
flex: 0 0 auto;
color: var(--muted);
}
.catsel-panel {
position: fixed;
z-index: 1000;
display: flex;
flex-direction: column;
background: var(--surface);
border: 1px solid var(--border-strong);
border-radius: var(--radius);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
overflow: hidden;
}
.catsel-search {
display: flex;
align-items: center;
gap: var(--sp-2);
padding: 8px 10px;
border-bottom: 1px solid var(--border);
color: var(--muted);
flex: 0 0 auto;
}
.catsel-search input {
width: 100%;
border: none;
background: none;
outline: none;
margin: 0;
padding: 0;
color: var(--text);
font: inherit;
}
.catsel-list {
overflow-y: auto;
padding: 5px;
}
.catsel-group + .catsel-group {
margin-top: 2px;
}
.catsel-group-head {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
padding: 6px;
border: none;
background: none;
cursor: pointer;
color: var(--muted);
font-weight: 650;
font-size: 0.72rem;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.catsel-group-head:hover {
color: var(--text);
}
.catsel-gchev {
flex: 0 0 auto;
transition: transform .12s ease;
}
.catsel-gchev.collapsed {
transform: rotate(-90deg);
}
.catsel-opt {
display: flex;
align-items: center;
gap: var(--sp-2);
width: 100%;
padding: 6px 8px 6px 22px;
border: none;
border-radius: var(--radius-sm);
background: none;
color: var(--text);
font: inherit;
text-align: left;
cursor: pointer;
}
.catsel-opt:hover {
background: var(--surface-2);
}
.catsel-opt.selected {
background: var(--accent-soft);
color: var(--accent);
font-weight: 600;
}
.catsel-check {
margin-left: auto;
flex: 0 0 auto;
color: var(--accent);
}
.catsel-empty {
padding: 10px;
}
/* ---------- Schlagwörter (Kategorie-Popup + Prüfmeldungen) ---------- */
.kw-add {
display: flex;
gap: var(--sp-2);
margin-bottom: var(--sp-3);
}
.kw-add input {
flex: 1 1 auto;
min-width: 0;
margin-top: 0;
}
.kw-chips {
display: flex;
flex-wrap: wrap;
gap: var(--sp-2);
}
.kw-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 6px 4px 11px;
border-radius: 20px;
background: var(--surface-2);
border: 1px solid var(--border);
font-size: 0.85rem;
}
.kw-amount {
color: var(--muted);
font-variant-numeric: tabular-nums;
font-size: 0.8em;
}
.kw-chip button {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
padding: 0;
margin: 0;
border: none;
border-radius: 50%;
background: none;
color: var(--muted);
cursor: pointer;
}
.kw-chip button:hover {
background: var(--danger);
color: #fff;
}
/* Schlagwort-Knopf in der Kategorienliste. Belegte Kategorien tragen die
Akzentfarbe und die Anzahl – so sieht man der Liste an, wo schon etwas
hinterlegt ist, ohne jede Kategorie einzeln zu öffnen. */
.kw-btn {
gap: 5px;
}
.kw-btn.belegt {
color: var(--accent);
border-color: var(--accent-soft);
background: var(--accent-soft);
}
.kw-btn-zahl {
font-size: 0.72rem;
font-weight: 640;
font-variant-numeric: tabular-nums;
line-height: 1;
}
/* Das Schlagwort, das gerade oben in der Zeile liegt. Bearbeitet wird dort,
nicht im Chip – im Chip war für den Betrag kein Platz. */
.kw-chip.aktiv {
border-color: var(--accent);
box-shadow: 0 0 0 2px var(--accent-soft);
}
/* Passend dazu die Eingabezeile hervorheben, damit klar ist, dass dort gerade
ein vorhandenes Wort liegt und nicht ein neues entsteht. */
.kw-add.bearbeitet input {
border-color: var(--accent);
}
.kw-flag {
display: flex;
align-items: center;
gap: var(--sp-3);
padding: var(--sp-3) 0;
border-bottom: 1px solid var(--border);
}
.kw-flag:last-child {
border-bottom: none;
}
.kw-flag-main {
flex: 1;
min-width: 0;
}
.kw-flag-word {
font-weight: 600;
}
/* ---------- Passwort: Anforderungsliste, Zwei-Faktor ---------- */
/* Nur für Screenreader – optisch weg, aber vorlesbar. */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
border: 0;
}
/* Hakt sich beim Tippen ab. Farben ausschliesslich aus Tokens, sonst bricht
das dunkle Thema. */
.pw-rules {
list-style: none;
margin: var(--sp-2) 0 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 3px;
font-size: 0.82rem;
}
.pw-rule {
display: flex;
align-items: center;
gap: var(--sp-2);
color: var(--muted);
transition: color 0.16s ease;
}
.pw-rule.erfuellt {
color: var(--ok);
}
.pw-rule-mark {
flex: 0 0 auto;
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
}
/* Offener Punkt, solange die Regel nicht erfüllt ist. */
.pw-rule-dot {
width: 7px;
height: 7px;
border-radius: 50%;
border: 1.5px solid currentColor;
opacity: 0.55;
}
/* Kurzer Impuls, wenn das Häkchen erscheint. */
.pw-rule.erfuellt .pw-rule-mark {
animation: pw-rule-pop 0.18s ease-out;
}
@keyframes pw-rule-pop {
from { transform: scale(0.4); opacity: 0; }
60% { transform: scale(1.18); opacity: 1; }
to { transform: scale(1); opacity: 1; }
}
/* styles.css hat keinen globalen Bewegungs-Reset, nur eine Aufzählung –
deshalb hier noch einmal ausdrücklich für die neuen Bewegungen. */
@media (prefers-reduced-motion: reduce) {
.pw-rule { transition: none; }
.pw-rule.erfuellt .pw-rule-mark { animation: none; }
}
/* Zwei-Faktor: QR-Code, Secret und Wiederherstellungscodes. */
.tfa-qr {
display: block;
width: 190px;
height: 190px;
/* Der QR-Code braucht weissen Grund, damit er auch im dunklen Thema
zuverlässig gescannt wird. */
background: #fff;
padding: var(--sp-2);
border-radius: var(--radius-sm);
border: 1px solid var(--border);
}
.tfa-secret {
display: inline-block;
padding: 6px var(--sp-2);
border-radius: var(--radius-sm);
background: var(--surface-2);
border: 1px solid var(--border);
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 0.9rem;
letter-spacing: 0.06em;
/* styles.css setzt body { user-select: none } – ohne das hier liesse sich
das Secret nicht markieren und kopieren. */
user-select: text;
}
.tfa-codes {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: var(--sp-2);
margin: var(--sp-3) 0;
padding: var(--sp-3);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--surface-2);
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 0.9rem;
user-select: text;
}
.tfa-codes .verbraucht {
color: var(--muted);
text-decoration: line-through;
}
/* Zusammenfassung der Prüfansicht beim Wiederherstellen. */
.restore-summary {
width: 100%;
border-collapse: collapse;
margin-top: var(--sp-2);
font-size: 0.88rem;
}
.restore-summary td {
padding: 3px 0;
border-bottom: 1px solid var(--border);
}
.restore-summary td:last-child {
text-align: right;
font-variant-numeric: tabular-nums;
color: var(--muted);
}
.restore-summary tr:last-child td {
border-bottom: none;
}
/* Zweiter Buchen-Knopf unter der Prüfliste – bei vielen Zeilen ist der obere
längst aus dem Bild gescrollt. */
.commit-footer {
display: flex;
justify-content: flex-end;
padding-top: var(--sp-3);
margin-top: var(--sp-2);
border-top: 1px solid var(--border);
}
/* Ausgaben-Anteile: der Prozentwert ist die Kernaussage der Karte und steht
deshalb vor dem Betrag, mit gleichbleibender Ziffernbreite. */
.share-pct {
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
/* Wird die Karte schmal, gibt zuerst der Betrag nach – ohne den Kategorienamen
sagt die Zeile nichts mehr aus, ohne den Betrag bleibt der Anteil lesbar. */
.share-row .share-name {
min-width: 4.5rem;
}
.share-row .share-amount {
flex: 0 1 auto;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}