diff --git a/Changes.md b/Changes.md
index 07bbf6b..fab17ec 100644
--- a/Changes.md
+++ b/Changes.md
@@ -1,5 +1,47 @@
# Änderungen
+## Termine und Verträge wandern unter die Verwaltung (13.08.2026)
+
+Die Seitenleiste war lang geworden. *Termine* und *Verträge* sind kein täglicher Einstieg –
+die Reihen laufen von selbst, Verträge sind Stammdaten – und stehen deshalb nicht mehr im
+Hauptmenü, sondern als letzte Kacheln in der Verwaltung.
+
+**Navigation** (`Views/layout/kopf.php`)
+- Die Menüpunkte *Termine* und *Verträge* entfallen.
+- Ein Menüeintrag kann jetzt weitere Pfade mitführen (`auch`), unter denen er als aktiv
+ gilt. *Verwaltung* leuchtet damit auch auf `/termine`, `/termine/kalender`,
+ `/termine/erinnerungen` und unterhalb von `/vertraege` – sonst stünde die Seitenleiste
+ dort ohne Markierung.
+
+**Verwaltung** (`Views/verwaltung/index.php`, `VerwaltungController`)
+- Neue Kachel *Termine* mit der Zahl der aktiven Reihen, den offenen Erinnerungen und
+ Wegen zu regelmäßigen Buchungen, Finanzkalender und Erinnerungen.
+- Neue letzte Kachel *Verträge* mit der Zahl der laufenden Verträge, den in den nächsten
+ 90 Tagen ablaufenden Kündigungsfristen und Wegen zu Verträgen, Adressen, Sparzielen und
+ Krediten.
+- Beide Kacheln führen mehrere Wege und nutzen deshalb kleine Knöpfe und einen knappen
+ Beitext.
+- Alle übrigen Kacheln ziehen nach: *Kategorien*, *Klassen*, *Konten*, *QIF-Import* und
+ *Online-Banking* tragen jetzt dieselben kleinen Knöpfe. Vorher standen zwei Größen
+ nebeneinander im selben Raster.
+
+**Knopfleisten stehen am Kachelfuß** (`static/app.css`)
+- Das Raster der Verwaltung heißt `kachelraster fussbuendig`: die Kacheln werden zu
+ Flexspalten, der freie Platz sammelt sich über der Knopfleiste. Die Knöpfe stehen damit
+ in jeder Kachel einer Zeile auf gleicher Höhe unten, statt der jeweiligen Textlänge zu
+ folgen. Der Abstand zum Text steckt im Padding – `margin-top: auto` schluckt den
+ Außenabstand und ließe die Knöpfe in der höchsten Kachel sonst am Text kleben.
+
+**Knopfleisten brechen um** (`static/app.css`)
+- `.knopfleiste` bekommt `flex-wrap: wrap`. Bisher ragten Leisten mit mehreren Knöpfen bei
+ schmalen Kacheln über den rechten Rand hinaus, statt in die nächste Zeile zu rutschen.
+ Das gilt für alle Knopfleisten, nicht nur die der Verwaltung.
+
+Alle Adressen unter `/termine` und `/vertraege` bleiben unverändert erreichbar, ebenso die
+Reiter innerhalb der Seiten und die Verlinkungen aus Cockpit und Buchungsvorlagen.
+
+**Test:** `tests/24_NavigationTest.php`
+
## QIF-Import: nur ausgewählte Konten übernehmen (12.08.2026)
Der QIF-Import kannte bisher nur den Zeitraum als Filter – ein Export ließ sich nur ganz
diff --git a/public/static/app.css b/public/static/app.css
index 11ada55..c43a674 100644
--- a/public/static/app.css
+++ b/public/static/app.css
@@ -278,6 +278,23 @@ form.inline { display: inline; margin: 0; }
.kachel.einzeln { max-width: 640px; }
+/* Kacheln mit unterschiedlich langem Text – etwa in der Verwaltung – lassen ihre
+ Knopfleisten sonst auf verschiedenen Höhen enden. Die Kachel wird zur
+ Flexspalte, der freie Platz sammelt sich über der Knopfleiste, und die Knöpfe
+ stehen in jeder Kachel derselben Zeile auf gleicher Höhe am unteren Rand. */
+.kachelraster.fussbuendig > .kachel {
+ display: flex;
+ flex-direction: column;
+}
+
+/* Der Abstand nach oben wandert ins Padding: `margin-top: auto` schluckt den
+ Außenabstand und ließe die Knöpfe in der höchsten Kachel – die keinen freien
+ Platz mehr hat – direkt am Text kleben. */
+.kachelraster.fussbuendig > .kachel > .knopfleiste {
+ margin-top: auto;
+ padding-top: 1.25rem;
+}
+
.kachel header { margin-bottom: .6rem; }
.kachel header.mitschalter {
@@ -1159,8 +1176,11 @@ table.splittabelle input.rechts { text-align: right; }
.optional { font-weight: 400; color: var(--text-gedaempft); }
+/* Umbruch statt Überlauf: Knopfleisten mit mehreren Wegen – etwa in den Kacheln
+ der Verwaltung – ragten sonst über den rechten Kachelrand hinaus. */
.knopfleiste {
display: flex;
+ flex-wrap: wrap;
gap: .6rem;
margin-top: 1.25rem;
}
diff --git a/src/Controllers/VerwaltungController.php b/src/Controllers/VerwaltungController.php
index e344a4e..9e1d77a 100644
--- a/src/Controllers/VerwaltungController.php
+++ b/src/Controllers/VerwaltungController.php
@@ -4,10 +4,13 @@ declare(strict_types=1);
namespace Finanzmanager\Controllers;
+use Finanzmanager\Models\Erinnerung;
use Finanzmanager\Models\Kategorie;
use Finanzmanager\Models\Klasse;
use Finanzmanager\Models\Konto;
use Finanzmanager\Models\Kontengruppe;
+use Finanzmanager\Models\RegelmaessigeBuchung;
+use Finanzmanager\Models\Vertrag;
use Finanzmanager\View;
/**
@@ -30,6 +33,10 @@ class VerwaltungController extends BaseController
'klassen' => Klasse::anzahl(),
'konten' => Konto::anzahl(),
'kontengruppen' => count(Kontengruppe::alle()),
+ 'reihen' => count(RegelmaessigeBuchung::alle(true)),
+ 'erinnerungen' => Erinnerung::anzahlOffen(),
+ 'vertraege' => count(Vertrag::alle(true)),
+ 'fristen' => count(Vertrag::fristenLaufenAb(90)),
],
]);
}
diff --git a/src/Views/layout/kopf.php b/src/Views/layout/kopf.php
index 2b19549..992b439 100644
--- a/src/Views/layout/kopf.php
+++ b/src/Views/layout/kopf.php
@@ -14,17 +14,26 @@ $navigation = [
['pfad' => '/zahlungsverkehr', 'name' => 'Zahlungsverkehr', 'icon' => '⇄'],
['pfad' => '/auswertungen', 'name' => 'Auswertungen', 'icon' => '◱'],
['pfad' => '/planung', 'name' => 'Planung', 'icon' => '◷'],
- ['pfad' => '/termine', 'name' => 'Termine', 'icon' => '⏱'],
- ['pfad' => '/vertraege', 'name' => 'Verträge', 'icon' => '§'],
['pfad' => '/wertpapiere', 'name' => 'Wertpapiere', 'icon' => '↗'],
- ['pfad' => '/verwaltung', 'name' => 'Verwaltung', 'icon' => '⚙'],
+ // Termine und Verträge haben keinen eigenen Menüpunkt mehr, sind aber weiter
+ // erreichbar – deshalb leuchtet für sie die Verwaltung, unter der sie hängen.
+ ['pfad' => '/verwaltung', 'name' => 'Verwaltung', 'icon' => '⚙', 'auch' => ['/termine', '/vertraege']],
];
-$istAktiv = static function (string $pfad) use ($aktuellerPfad): bool {
+/** @param list = (int)$zahlen['kategorien'] ?>Kategorien
= (int)$zahlen['reihen'] ?>
++ Aktive Reihen – offene Erinnerungen: = (int)$zahlen['erinnerungen'] ?>. +
+ += (int)$zahlen['vertraege'] ?>
++ Laufende Verträge – Fristen in den nächsten 90 Tagen: = (int)$zahlen['fristen'] ?>. +
+