diff --git a/README.md b/README.md
index 04bdff2..733e3f2 100644
--- a/README.md
+++ b/README.md
@@ -92,3 +92,8 @@ Eingänge, Ausgänge und Transfers unterstützen `monthly`, `quarterly`, `semian
Der eingegebene Betrag ist immer der Betrag pro Intervall. Für Salden kann FixFin periodische Werte automatisch auf einen Monatsdurchschnitt umrechnen. Diese Berücksichtigung lässt sich global in der Übersicht ein-/ausschalten.
Für nicht-monatliche Positionen kann optional ein Fälligkeitsmonat angegeben werden. Bei vierteljährlichen und halbjährlichen Positionen ist dies der erste Fälligkeitsmonat. Die Jahresansicht verteilt die Position anschließend auf die tatsächlichen Fälligkeitsmonate. Positionen ohne Monat bleiben für die Monatsdurchschnittsrechnung nutzbar, werden in der Jahresprognose aber separat als nicht zugeordnet angezeigt.
+
+
+## Jahresansicht auf Mobilgeräten
+
+Die Jahresprognose verwendet kompakte Monats-Akkordeons. Monat, Eingänge, Ausgänge und Saldo sind immer sichtbar. Fällige Einzelpositionen werden erst beim Aufklappen angezeigt. Die mobile Bottom-Navigation bleibt auf allen Ansichten identisch.
diff --git a/package.json b/package.json
index 761a53d..3cfb96b 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "fixfin",
- "version": "1.2.0",
+ "version": "1.3.0",
"private": true,
"type": "module",
"scripts": {
diff --git a/src/main.jsx b/src/main.jsx
index 763b28a..b178c21 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -139,8 +139,30 @@ function Entries({type,items,accounts,onEdit,onDelete}){const accountName=id=>ac
function Transfers({data,onEdit,onDelete}){const accountName=id=>data.accounts.find(a=>a.id===id)?.name||'Unbekannt';return Fixe Transfers Verschiebungen zwischen eigenen Konten. Global saldoneutral.
{data.transfers.length===0? :Bezeichnung Von Nach Intervall Monat Betrag Ø / Monat {data.transfers.map(x=>{x.name} {accountName(x.fromAccountId)} {accountName(x.toAccountId)} {intervals[x.interval||'monthly'].label} {x.interval==='monthly'?'Jeden Monat':x.dueMonth?months[Number(x.dueMonth)-1]:'–'} {formatMoney(x.amount)} {formatMoney(monthlyEquivalent(x))} onEdit(x)}>Bearbeiten onDelete('transfers',x.id)}>Löschen )}
} }
function YearPage({forecast}){
- return
=forecast.yearExpense} negative={forecast.yearIncome
-
Jahresprognose Tatsächliche Fälligkeiten nach Monat. Transfers sind im Gesamtsaldo neutral.
Monat Eingänge Ausgänge Saldo Fällige Positionen {forecast.rows.map(r=>{r.name} +{formatMoney(r.income)} −{formatMoney(r.expense)} =0?'good-text':'bad-text'}`}>{formatMoney(r.balance)} {r.items.length===0?Keine :r.items.map((x,i)=>{x.name} · {formatMoney(x.amount)} )}
)}
+ const kindLabel={income:'Eingang',expense:'Ausgang',transfer:'Transfer'};
+ const kindSign={income:'+',expense:'−',transfer:''};
+ return
+
=forecast.yearExpense} negative={forecast.yearIncome
+
Jahresprognose Monatliche Basiswerte auf einen Blick. Details bei Bedarf ausklappen.
+ {forecast.rows.map(r=>
+
+ {r.name} {r.items.length===0?'Keine Fälligkeiten':`${r.items.length} ${r.items.length===1?'Position':'Positionen'}`}
+
+
Eingänge +{formatMoney(r.income)}
+
Ausgänge −{formatMoney(r.expense)}
+
Saldo =0?'good-text':'bad-text'}>{r.balance>=0?'+':''}{formatMoney(r.balance)}
+
+ ⌄
+
+
+ {r.items.length===0?
In diesem Monat sind keine einzelnen Fixpositionen fällig.
:r.items.map((x,i)=>
+
{kindLabel[x.kind]} {x.name}
+
{kindSign[x.kind]}{formatMoney(x.amount)}
+
)}
+ {(r.transferIn>0||r.transferOut>0)&&
Transfers in diesem Monat: {formatMoney(r.transferOut)}. Sie verändern den Gesamtsaldo nicht.
}
+
+ )}
+
{forecast.unassigned.length>0&&
Periodische Positionen ohne Monat Diese Werte können in den Monats-Saldo eingerechnet werden, sind aber keiner konkreten Jahresprognose zugeordnet.
{forecast.unassigned.map(x=>{x.name} · {intervals[x.interval].label} · {formatMoney(x.amount)} )}
}
;
}
diff --git a/src/styles.css b/src/styles.css
index c8e693c..101f743 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -148,3 +148,67 @@ code { color:#b8c3ff; }
.warning-panel { border-color:#5a4e2b; }
@media (max-width:760px) { .toggle-panel { align-items:flex-start; } .year-summary { grid-template-columns:1fr 1fr; } .mobile-nav { grid-template-columns:repeat(7,1fr); } }
@media (max-width:430px) { .year-summary { grid-template-columns:1fr; } }
+
+/* v1.3: mobile Jahresansicht als Akkordeon */
+.year-month-list { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }
+.year-month-card { background:#0d131c; border:1px solid #29364a; border-radius:14px; overflow:hidden; }
+.year-month-card[open] { border-color:#46577a; background:#0f1621; }
+.year-month-card summary { list-style:none; cursor:pointer; display:grid; grid-template-columns:minmax(105px,.75fr) minmax(0,2fr) 22px; gap:16px; align-items:center; padding:15px 16px; user-select:none; }
+.year-month-card summary::-webkit-details-marker { display:none; }
+.year-month-heading { min-width:0; }
+.year-month-heading strong { display:block; font-size:15px; }
+.year-month-heading span { display:block; color:var(--muted); font-size:10px; margin-top:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
+.year-month-basics { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; min-width:0; }
+.year-month-basics div { min-width:0; }
+.year-month-basics span { display:block; color:#718096; font-size:9px; text-transform:uppercase; letter-spacing:.055em; font-weight:800; margin-bottom:3px; }
+.year-month-basics strong { display:block; font-size:13px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
+.accordion-chevron { color:#8793a4; font-size:20px; line-height:1; text-align:center; transition:transform .18s ease; }
+.year-month-card[open] .accordion-chevron { transform:rotate(180deg); }
+.year-month-details { border-top:1px solid #202a39; padding:7px 16px 11px; }
+.year-detail-row { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:9px 0; border-bottom:1px solid #1e2937; }
+.year-detail-row:last-of-type { border-bottom:0; }
+.year-detail-name { display:flex; align-items:center; gap:8px; min-width:0; }
+.year-detail-name strong { font-size:12px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
+.year-kind { flex:0 0 auto; border-radius:999px; padding:3px 6px; font-size:8px; font-weight:850; text-transform:uppercase; letter-spacing:.04em; background:#1c2635; border:1px solid #304057; color:#b8c5d7; }
+.year-kind.income { border-color:#245947; color:#7de0b5; background:#112c24; }
+.year-kind.expense { border-color:#67333b; color:#ff9aa2; background:#321a20; }
+.year-kind.transfer { border-color:#414d7d; color:#adb9ff; background:#1c2340; }
+.year-detail-amount { flex:0 0 auto; font-size:12px; font-weight:800; white-space:nowrap; }
+.year-detail-empty { color:var(--muted); font-size:12px; padding:10px 0 6px; }
+.year-transfer-note { color:#8793a4; font-size:10px; border-top:1px dashed #2d394b; padding-top:9px; margin-top:5px; }
+
+@media (max-width: 900px) {
+ .year-month-list { grid-template-columns:1fr; }
+}
+
+@media (max-width: 760px) {
+ .year-page { min-width:0; }
+ .year-forecast-panel { padding:14px; }
+ .year-month-list { gap:9px; }
+ .year-month-card summary { grid-template-columns:1fr 22px; gap:9px 10px; padding:13px 12px; }
+ .year-month-heading { grid-column:1; }
+ .accordion-chevron { grid-column:2; grid-row:1; align-self:center; }
+ .year-month-basics { grid-column:1 / -1; grid-row:2; gap:6px; }
+ .year-month-basics div { background:#101823; border:1px solid #202c3c; border-radius:9px; padding:8px; }
+ .year-month-basics strong { font-size:12px; }
+ .year-month-basics span { font-size:8px; }
+ .year-month-balance { background:#141c2c !important; border-color:#2b3850 !important; }
+ .year-month-details { padding:5px 12px 9px; }
+ .year-detail-row { padding:9px 1px; }
+ .year-summary { grid-template-columns:1fr 1fr; gap:8px; }
+ .year-summary .metric { min-height:82px; padding:12px; }
+ .year-summary .metric strong { font-size:18px; }
+ .mobile-nav { width:100vw; max-width:100vw; overflow-x:auto; overscroll-behavior-x:contain; scrollbar-width:none; }
+ .mobile-nav::-webkit-scrollbar { display:none; }
+ .mobile-nav button { min-width:50px; }
+}
+
+@media (max-width: 430px) {
+ .year-summary { grid-template-columns:1fr 1fr; }
+ .year-month-heading strong { font-size:14px; }
+ .year-detail-name strong { font-size:11px; }
+ .year-kind { font-size:7px; padding:3px 5px; }
+}
+@media (max-width: 760px) {
+ .mobile-nav { grid-template-columns:repeat(7,minmax(50px,1fr)); }
+}