.app-shell { min-height: 100vh; }
.sidebar {
  position: fixed;
  z-index: 20;
  inset: 0 auto 0 0;
  display: flex;
  width: var(--sidebar-width);
  flex-direction: column;
  padding: var(--space-5) var(--space-4);
  border-right: 1px solid var(--border);
  background: var(--surface);
}
.brand { display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--space-2) var(--space-5); font-size: var(--text-md); font-weight: var(--weight-bold); letter-spacing: var(--tracking-tight); }
.brand-mark { display: grid; width: 32px; height: 32px; place-items: center; border-radius: var(--radius-sm); background: var(--text); color: var(--surface); font-size: var(--text-sm); }
.primary-nav { display: grid; gap: var(--space-1); }
.primary-nav a {
  display: flex;
  min-height: 44px;
  align-items: center;
  gap: var(--space-3);
  padding: 0 var(--space-3);
  border-radius: var(--radius-md);
  color: var(--text-muted);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
}
.primary-nav a:hover { background: var(--surface-muted); color: var(--text); }
.primary-nav a[aria-current="page"] { background: var(--accent-soft); color: var(--accent-ink); }
.sidebar-footer { margin-top: auto; }
.storage-note { margin: var(--space-2) var(--space-3) 0; color: var(--text-muted); font-size: var(--text-xs); line-height: var(--leading-snug); }

.workspace { min-height: 100vh; margin-left: var(--sidebar-width); }
/* Sticky: auf langen Seiten waren Suche und Synchronisierungsstatus nach
   wenigen Zeilen Scrollen nicht mehr erreichbar. Der Hintergrund muss deckend
   sein, damit der Inhalt nicht durchscheint; die Trennlinie kommt erst beim
   Scrollen (Klasse aus js/app.js), damit die Ruhelage ruhig bleibt. */
.topbar {
  position: sticky;
  z-index: 15;
  top: 0;
  display: flex;
  width: min(100%, calc(var(--content-width) + 64px));
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin: 0 auto;
  padding: var(--space-6) var(--space-6) var(--space-5);
  border-bottom: 1px solid transparent;
  background: var(--bg);
}
.topbar.is-scrolled { border-bottom-color: var(--border); }
/* min-width: 0 — ohne das schrumpfte der Seitentitel im Flex-Container auf
   21px und brach buchstabenweise um. Der Titel gibt beim Schrumpfen zuerst
   nach; die Aktionen behalten ihre Breite, damit vom Synchronisierungsstatus
   nicht nur ein Fleck uebrig bleibt. */
.topbar > div:first-child { min-width: 0; flex: 1 1 auto; }
/* Seitentitel und Eyebrow sind kurz; kuerzen ist hier ehrlicher als der
   buchstabenweise Umbruch, den overflow-wrap: anywhere sonst erzeugt. */
.topbar h1, .topbar .eyebrow { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-actions { display: flex; min-width: 0; flex: 0 0 auto; align-items: center; gap: var(--space-2); }
#app-content { width: min(100%, calc(var(--content-width) + 64px)); margin: 0 auto; padding: 0 var(--space-6) var(--space-7); }

.metric-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); }
.content-grid { display: grid; grid-template-columns: minmax(0, 1.45fr) minmax(300px, .75fr); gap: var(--space-4); margin-top: var(--space-4); }
/* minmax(0, 1fr) statt der impliziten auto-Spur: ein einzelnes breites Kind zog
   die Spur sonst über den Inhaltsbereich hinaus. Gemessen bei 320px endete die
   Reiterleiste dadurch 11,5px rechts neben dem Textbereich. */
.page-stack { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
.mobile-nav { display: none; }
/* Der schwebende Knopf gehoert zur unteren Leiste und existiert nur mobil.
   Ab 721px traegt "＋ Ausgabe" in der Kopfzeile dieselbe Aufgabe. */
.mobile-fab { display: none; }
/* "Mehr" haengt nur mobil in der Kopfzeile — auf dem Desktop steht es in der
   Seitenleiste, und zwei Einstiege nebeneinander waeren doppelt. */
.topbar-more { display: none; }
.topbar-add-expense { flex: 0 0 auto; padding: 0 var(--space-4); white-space: nowrap; }

/* Zwei Spalten nebeneinander lohnen erst ab 1280px. Darunter — Handy, Tablet
   und kleiner Desktop — steht der Inhalt einspaltig. minmax(0, 1fr) statt
   blankem 1fr: `1fr` ist `minmax(auto, 1fr)` und laesst die Spur von der
   min-content-Breite des Inhalts aufziehen; eine einzige lange Kategorie schob
   so die gesamte Seite ueber den Bildschirm. */
@media (max-width: 1279px) {
  .content-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Kleiner Desktop: die Seitenleiste kommt bei 1024px dazu und nimmt 216px vom
   Inhalt. Vier Kennzahlenkarten waeren hier 166px breit — deshalb zwei. Frueher
   galt diese Stufe fuer alles unter 1021px, also auch fuer Tablets ohne
   Seitenleiste; sie greift jetzt nur noch dort, wo die Leiste wirklich steht. */
@media (min-width: 1024px) and (max-width: 1279px) {
  :root { --sidebar-width: 216px; }
  .metric-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .asset-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Drei Schnellstartkarten liessen der Textspalte hier 106px. */
  .quick-action-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Sehr breite Bildschirme: bisher klebte die Seitenleiste am linken Rand,
   waehrend der Inhaltsblock in der Restflaeche zentriert stand — dadurch lag er
   um die halbe Leistenbreite (124px) rechts der Fenstermitte, und bei 2560px
   klafften 504px Leere zwischen Leiste und Inhalt. Jetzt werden Leiste und
   Inhalt als ein Block zentriert und stehen wieder nebeneinander. */
@media (min-width: 1600px) {
  .sidebar { left: max(0px, calc((100vw - var(--shell-width)) / 2)); }
  .workspace { margin-left: max(var(--sidebar-width), calc((100vw - var(--shell-width)) / 2 + var(--sidebar-width))); }
  .topbar,
  #app-content { margin-left: 0; }
}
