/* ══════════════════════════════════════════════════════════════
   FINA — Layout
   Seitengerüst: Kopfzeile, Reiter, Karten, Kennzahlen, Fußstatus.
   ══════════════════════════════════════════════════════════════ */

.wrap{max-width:none;margin:0;padding:0 var(--pagepad) 80px;--monw:100px;--pagepad:24px}

/* ── Hinweis auf eine neue Fassung ────────────────────────────
   Es gibt sie nur in der Mac- und der Windows-App (checkUpdate in
   js/app.js). Sie steht **über** der Kopfzeile und klebt nicht:
   sie ist eine Nachricht und keine Bedienung — wer zu arbeiten
   anfängt, scrollt sie weg und hat den Kopf wieder ganz oben.

   Orange trägt in FINA, was etwas anbietet statt etwas zu tun —
   dieselbe Farbe wie der Anleitungsknopf daneben. Rot wäre eine
   Warnung, und eine neue Fassung ist keine. */
.updatebar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  margin:0 -24px 0;padding:7px 24px;
  background:#FBEFE6;border-bottom:1px solid var(--accent);
  font-size:12.5px;color:var(--accent-2)}
.updatebar span{font-weight:600}
.updatebar .btn{padding:3px 10px;font-size:12px}

/* ── Kopfzeile: die Mac-Toolbar ───────────────────────────────
   Eine Titelleiste über die ganze Breite (die negativen
   Außenmaße heben das Polster von .wrap auf): links das
   Wortzeichen mit dem Jahr, in der Mitte die Ansichten als
   Segmented Control, rechts Dateiname und Hamburger. Darunter,
   nur in der Monatsansicht, die Monatsleiste. Die Höhe misst
   syncStickyTops() — hier steht kein top-Maß. */
header{position:sticky;top:0;z-index:40;margin:0 -24px;padding:0;background:var(--paper);
  box-shadow:0 6px 12px -8px rgba(0,0,0,.35)}
/* Damit die Mitte wirklich die Mitte ist, tragen beide Seiten
   dieselbe Flexbasis: das Wortzeichen links, Dateiname und Knopf
   rechts — die Segmented Control steht dazwischen. */
.masthead{display:flex;align-items:center;gap:14px;padding:8px 24px;
  background:var(--grad-bar);border-bottom:1px solid var(--rule)}
.brand{display:flex;align-items:baseline;gap:7px;flex:1 1 0;min-width:0}
.brand h1{font-family:var(--font-display);font-weight:700;font-size:19px;letter-spacing:.02em;margin:0;line-height:1.1}
/* Das Wortzeichen ist ein Link zur Startseite (im Browser; in der
   App nimmt renderChrome ihm das href) — aussehen soll es wie die
   Überschrift, die es ist. */
.brand h1 a{color:inherit;text-decoration:none}
.brand .sub{font-family:var(--font-data);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2)}
/* Rechts: Dateiname, dann der Hamburger mit dem Menü darunter. */
.hdrright{position:relative;display:flex;align-items:center;justify-content:flex-end;gap:9px;
  flex:1 1 0;min-width:0}
/* Der Dateiname steht seit 22.8.26 **nur noch im Menü** (.menufile
   zuoberst): in der Zeile stritt er mit der Segmented Control um
   den Platz, und der rote Punkt am Hamburger sagt „ungespeichert"
   auch ohne ihn. Das Element bleibt im HTML — renderStatus()
   schreibt es weiter —, sichtbar ist es nicht. */
.filepath{display:none}
.filepath.on{color:var(--ink)}
/* Ungespeichert: der Dateiname trägt die Warnung — und der rote
   Punkt am Hamburger (.dirtydot) sagt dasselbe, auch wenn der
   Name bei schmalem Fenster im Menü steckt. */
.filepath.warnpath{color:var(--seal)}
/* ── Der Hamburger ────────────────────────────────────────────
   28×26, drei Striche, der helle Knopfverlauf des Chrome. Hinter
   ihm stecken alle Aktionsknöpfe — auf jeder Breite. */
.burger{position:relative;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  width:28px;height:26px;padding:0;cursor:pointer;
  background:var(--grad-btn);border:1px solid var(--rule);border-radius:6px;box-shadow:var(--sh-btn)}
.burger:hover{border-color:var(--rule-strong)}
.burger[aria-expanded="true"]{background:var(--shade)}
.burger[hidden]{display:none!important}
.burger .bars{display:flex;flex-direction:column;gap:2.5px}
.burger .bars i{width:12px;height:1.5px;background:var(--ink);border-radius:1px}
.dirtydot{position:absolute;top:-4px;right:-4px;width:9px;height:9px;border-radius:50%;
  background:var(--seal);border:1.5px solid var(--chrome-hi)}
.dirtydot[hidden]{display:none}
/* ── Das Menü hinter dem Hamburger ────────────────────────────
   Ein Overlay unter dem Knopf: es legt sich über den Inhalt und
   verschiebt nie Layout. Auf und zu schaltet js/app.js über die
   Klasse .open — dieselbe Mechanik, die vorher nur das Telefon
   hatte. Trenner (.mi-sep) schließen eine Gruppe ab, die drei
   „Neu…"-Wege tragen die Farbe ihrer Geldart. */
.tools{position:absolute;top:calc(100% + 8px);right:0;z-index:46;display:none;flex-direction:column;
  width:230px;background:#fff;border:1px solid var(--rule);border-radius:8px;
  box-shadow:var(--sh-pop);overflow:hidden;padding:0}
.tools.open{display:flex}
.tools .btn{background:none;border:0;border-radius:0;text-align:left;
  padding:7px 12px;font-size:12px;color:var(--ink);transition:background .12s}
.tools .btn:hover{background:var(--paper-2)}
.tools .btn:disabled{opacity:.45}
.tools .mi-sep{border-bottom:1px solid var(--hairline)}
.tools #btnSave{font-weight:600}
/* Die drei „Neu…"-Wege: vor der Beschriftung ein Plus im Kreis,
   und **der Kreis** trägt die Farbe der Geldart — die Beschriftung
   bleibt Tinte wie jeder andere Eintrag. Das Zeichen kommt als
   ::before aus dem Stylesheet: renderChrome() schreibt die
   Beschriftung über textContent, ein Kind-Element überlebte das
   nicht. */
.tools .mi-in,.tools .mi-flex,.tools .mi-out{display:flex;align-items:center;gap:8px;
  font-weight:600;color:var(--ink)}
.tools .mi-in::before,.tools .mi-flex::before,.tools .mi-out::before{content:'+';
  flex:0 0 auto;width:15px;height:15px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:600;line-height:1;color:#fff}
.tools .mi-in::before{background:var(--ok)}
.tools .mi-flex::before{background:var(--amber)}
.tools .mi-out::before{background:var(--seal)}
/* Der Dateiname steht als Kopf **immer** oben im Menü — man soll
   sehen, an welcher Datei die Knöpfe darunter arbeiten, auch wenn
   der Name daneben in der Kopfzeile steht. */
.menufile{display:none}
.tools .menufile:not([hidden]){display:block;padding:8px 12px;
  font-family:var(--font-data);font-size:10.5px;font-weight:600;color:var(--ink-2);
  background:var(--paper-2);border-bottom:1px solid var(--hairline);
  white-space:normal;overflow-wrap:anywhere}
.tools .menufile.warnpath{color:var(--seal)}

/* ── Monatsleiste ─────────────────────────────────────────────
   Zwölf Kürzel in einer Zeile: erledigte Monate grün und
   durchgestrichen, der laufende als rote Pille, der gewählte mit
   dunkler Einfassung.

   **Sie steht seit 22.8.26 unter der Filterzeile**, nicht mehr an
   der Kopfzeile — an derselben Stelle, an der die Jahresmatrix
   ihre Monate hat, und im selben Bild: eine weiße Karte mit
   Radius 8, feiner Kante und dem flachen Schatten der Karten
   darunter. Damit steht in beiden Ansichten die Reihe der Monate
   dort, wo die Bereiche anfangen, und trägt dieselbe Schrift wie
   der Spaltenkopf der Matrix (9.5 px Mono-Versalien).

   Gebaut wird sie in monthTabs() (js/views/monat.js) und steckt in
   der .stickybar der Ansicht — sie klebt also mit der Auswertung
   und der Filterzeile oben unter der Kopfzeile. Der Abstand nach
   oben ist derselbe, den die Bereiche voneinander haben (10 px);
   den nach unten trägt das Polster der Leiste. */
.months{display:flex;align-items:center;margin:10px 0 0;padding:3px 8px;
  background:#fff;border:1px solid var(--rule);border-radius:8px;box-shadow:var(--sh-card);
  overflow-x:auto}
.mtab{flex:1 0 auto;min-width:44px;background:transparent;border:0;padding:3px 2px;
  font-family:var(--font-data);font-size:9.5px;font-weight:500;letter-spacing:.08em;
  color:var(--ink-2);text-transform:uppercase;
  text-align:center;cursor:pointer}
.mtab .mp{display:inline-block;padding:2px 8px;border-radius:9px}
.mtab:hover .mp{color:var(--ink)}
.mtab[aria-selected="true"] .mp{box-shadow:inset 0 0 0 1px var(--ink);color:var(--ink);font-weight:600}
.mtab.alldone{color:var(--ok);text-decoration:line-through;text-decoration-thickness:1.5px}
.mtab.current{text-decoration:none}
.mtab.current .mp{background:var(--seal);color:#fff;font-weight:600;box-shadow:none}

/* ── Ansichtsreiter als Segmented Control ─────────────────────
   Grauer Trog, das aktive Segment weiß und leicht erhaben — die
   Mac-Bauform. Rechts daneben steht nichts mehr: die ✓/?-Erklärung
   (.viewkey) stritt dort mit dem Dateinamen um den Platz und ist
   seit 22.8.26 weg (siehe renderChrome in js/app.js). */
.views{position:relative;display:flex;flex:0 0 auto;background:var(--shade);border-radius:7px;padding:2px;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:0}
.vtab{background:none;border:0;border-radius:5px;padding:4px 14px;font-size:12px;color:var(--ink-2);
  white-space:nowrap;cursor:pointer}
.vtab:hover{color:var(--ink)}
.vtab[aria-selected="true"]{background:#fff;color:var(--ink);font-weight:600;
  box-shadow:0 1px 2px rgba(0,0,0,.18)}

/* ── Karten und Raster ────────────────────────────────────── */
.grid{display:grid;grid-template-columns:1.55fr 1fr;gap:22px;align-items:start}
@media(max-width:860px){.grid{grid-template-columns:1fr}}
/* Die Mac-Karte: weiß, feine Kante, Radius 8, flacher Schatten.
   **Kein overflow:hidden** — das machte die Karte zum
   Bezugsrahmen ihres klebenden Kopfes (siehe css/mobile.css);
   die Rundung unten übernimmt die letzte Zeile (css/ledger.css). */
.card{background:#fff;border:1px solid var(--rule);border-radius:8px;padding:12px 16px;
  margin-bottom:16px;box-shadow:var(--sh-card)}
.card h2{font-family:var(--font-data);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-2);margin:0 0 10px;font-weight:500}
/* Die drei Bereiche der Monatsansicht: die Karte selbst ist weiß
   und ohne Polster — die Farbe tragen der Kopf (Blockstufe -3 mit
   der Kante als Linie darunter) und die Zeilen (Stufe -1, gesetzt
   in css/ledger.css). 10 px Abstand zwischen den Karten. */
.card.sec-in,.card.sec-flex,.card.sec-out{background:#fff;padding:0;margin-bottom:10px}
/* ── Die Farbe des Kopfes liegt auf einer eigenen Schicht ─────
   Der Kopf klebt beim Scrollen, und die Zeilen ziehen unter ihm
   durch. Trüge er Farbe und Rundung selbst, schienen sie in den
   Ecken **neben** der Rundung durch — die Ecke sähe eckig aus.
   Deshalb trägt der Kopf selbst Papier (deckend und eckig, füllt
   die Ecke zur Seite hin), und die Blockfarbe liegt als gerundetes
   ::before darüber (z-index:-1 hält sie unter Pfeil, Überschrift
   und Summe; position:sticky macht den Kopf zum Stapelrahmen).

   **Das Papier trägt dieselbe Rundung wie die Farbschicht.** Die
   Karte hat kein overflow:hidden (das nähme dem Kopf sein Kleben),
   und ein klebender Kopf wird über die Kante der Karte gemalt: ein
   eckiger Grund deckte deshalb die beiden oberen Ecken der Karte
   zu — die Karte sah oben eckig aus und unten rund. Ein Rest der
   Zeile, die darunter wegläuft, kann dabei nicht durchscheinen:
   sobald der Kopf klebt, ist die Ecke der Karte längst
   hinausgescrollt. */
.card.sec-in>.sechead{border-bottom:1px solid var(--edge-in);--secbg:var(--bg-in-3)}
.card.sec-flex>.sechead{border-bottom:1px solid var(--edge-flex);--secbg:var(--bg-flex-3)}
.card.sec-out>.sechead{border-bottom:1px solid var(--edge-out);--secbg:var(--bg-out-3)}
.card.sec-in>.sechead,.card.sec-flex>.sechead,.card.sec-out>.sechead{background:var(--paper);
  border-radius:8px 8px 0 0}
.card.sec-in>.sechead::before,.card.sec-flex>.sechead::before,.card.sec-out>.sechead::before{
  content:'';position:absolute;inset:0;z-index:-1;
  background:var(--secbg);border-radius:8px 8px 0 0}
/* Zugeklappt trennt die Linie nichts mehr: unter der Überschrift
   steht keine Zeile, der Bereich ist nur noch eine Farbe. Die
   Rundung unten wandert dann an die Farbschicht. */
.card.folded>.sechead{border-bottom:0;border-radius:8px}
.card.folded>.sechead::before{border-radius:8px}
/* ── Der Kopf einer Karte bleibt stehen ───────────────────────
   Wer sich durch die regelmäßigen Kosten scrollt, soll immer
   sehen, in welchem Block er liest und was er zusammen kostet.
   Der Kopf klebt deshalb, solange die Karte im Bild ist — und
   verschwindet mit ihr, weil position:sticky nicht über den
   Rand des Elternteils hinausreicht.

   Das Maß für `top` steht nicht hier: es hängt davon ab, wie hoch
   Kopfzeile und Kennzahlenleiste in der jeweiligen Ansicht sind.
   syncStickyTops() in js/app.js misst und setzt es.

   Zwei Dinge muss ein klebender Kopf mitbringen: einen deckenden
   Grund — sonst schiene die Zeile durch, die darunter wegläuft —
   und die Breite der ganzen Karte. Deshalb ziehen die negativen
   Außenabstände ihn über das Polster der Karte hinaus, und sein
   eigenes Polster stellt den Abstand innen wieder her. */
.card.sec-in>.sechead,.card.sec-flex>.sechead,.card.sec-out>.sechead{
  position:sticky;z-index:20;margin:0;padding:6px 12px}
/* Die Saldokorrektur ist eine einzige, freistehende blaue Zeile —
   Rahmen in der dritten Blaustufe, Radius 7, kein Kopf. */
.card.sec-bal{border:1px solid var(--bg-bal-3);background:var(--bg-bal);padding:1px 6px;
  border-radius:7px;margin-bottom:10px}
.card.sec-in h2,.card.sec-flex h2,.card.sec-out h2{color:var(--ink);font-weight:600}
.sechead{display:flex;align-items:center;gap:9px;flex-wrap:wrap;margin-bottom:10px}
/* Die Summe steht rechts außen; alles zwischen Überschrift und
   Summe (der Weg in die Transactions-Auswertung) rückt zu ihr. */
.sechead h2{flex:1 1 auto;min-width:0}
.sechead .headlink{flex:0 0 auto}
/* ── Der Klapp-Pfeil ──────────────────────────────────────────
   Ganz links in der Kopfzeile und so breit wie die Siegelspalte
   der Tabelle darunter (--markw aus css/ledger.css): dadurch steht
   er senkrecht über den Haken der Positionen. Das Polster rechts
   rückt seine Mitte auf die der Siegel. Seine Farbe ist die Kante
   des Bereichs — ein Wort braucht er nicht. */
/* Das Polster rechts (12 px) schiebt die Pfeilmitte auf die der
   16-px-Siegel darunter: deren Spalte beginnt nach dem
   12-px-Kartenpolster, der Pfeilkasten schon an der Kante. */
.sechead .foldarrow{flex:0 0 auto;width:var(--markw);padding:0 12px 0 0;
  display:grid;place-items:center;background:none;border:0}
/* Klein wie im Mock (▼ bei 10 px): der Pfeil selbst, kein Kreis um
   ihn herum — dieselbe Spalte wie die Siegel darunter, die Farbe
   des Bereichs. */
.sechead .foldarrow{font-size:10px;line-height:1;color:inherit}
.sechead .foldarrow:hover{color:var(--ink)}
/* Bei offener Auswertung gibt es keinen Pfeil — der Platz bleibt
   trotzdem stehen, damit die Überschrift nicht springt. */
.sechead .foldpad{flex:0 0 auto;width:var(--markw)}
.sechead h2{flex:1 1 auto;min-width:0}
.card.sec-in .foldarrow{color:var(--edge-in)}
.card.sec-flex .foldarrow{color:var(--edge-flex)}
.card.sec-out .foldarrow{color:var(--edge-out)}
.sechead .foldarrow:hover{color:var(--ink)}
/* Zweizeilige Überschrift: oben der Name, darunter der Satz, der
   sagt, woher die Zahlen kommen. Beides gehört zusammen und
   bleibt deshalb ein Block — die Knöpfe rechts daneben rücken
   nicht dazwischen. */
.sechead .headstack{display:flex;flex-direction:column;gap:3px;min-width:0}
.sechead .subhead{margin:0;font-size:12px;line-height:1.45;color:var(--ink-2);max-width:78ch}
.sechead .tot{font-family:var(--font-data);font-size:13px;font-weight:600;font-variant-numeric:tabular-nums;margin-left:auto}
/* „(3 ausgeblendet)" steht in der Überschrift, trägt aber deren
   Versalien und Sperrung nicht mit. */
.sechead h2 .note{margin-left:8px;text-transform:none;letter-spacing:0;font-weight:400}

/* ── Leisten, die stehen bleiben ──────────────────────────────
   Alles mit .stickybar klebt unter der Kopfzeile. Deren Höhe
   hängt von der Ansicht ab — nur im Monat gibt es die Reiterzeile
   —, deshalb setzt syncStickyTops() in js/app.js das top-Maß und
   misst es, statt es zu raten. Der Papiergrund und die Polster
   sind kein Zierrat: ohne sie schiene der Inhalt durch, der
   darunter wegscrollt. */
.stickybar{position:sticky;top:0;z-index:30;background:var(--paper);
  padding:8px 0 10px;box-shadow:0 8px 10px -10px rgba(0,0,0,.4)}
/* Der Abstand nach unten kommt aus dem Polster, nicht aus einem
   Rand: ein Rand ist durchsichtig, dort schiene der Inhalt
   durch, der darunter wegscrollt. */
.stickybar.filterbar{margin-bottom:0}

/* ── Die Auswertung der Monatsansicht ─────────────────────────
   Dieselben fünf Zahlen wie die Kennzahlenleiste, aber auf eine
   Zeile gelegt: die Leiste klebt oben und nähme aufgeschlagen
   dauerhaft drei Zeilen weg, die die Liste darunter braucht.
   Aufgeklappt kommt der Zeitstrahl dazu — zusammen doppelt so
   hoch. Beides steckt in derselben .stickybar (js/views/monat.js).

   Die ganze Zeile ist ein Knopf, deshalb hier der Reset auf die
   Schrift der Seite; die 1px-Fugen des Rasters zeichnen wie bei
   .kpi die Trennlinien. Die Überschrift steht klein darüber und
   nicht als Kästchen in der Reihe: sie benennt die Leiste, sie ist
   keine Kennzahl. Einen Pfeil trägt sie nicht — ob die Auswertung
   offen ist, sagt der Zeitstrahl darunter. */
.anahead{display:block;width:100%;background:none;border:0;padding:0;font:inherit;color:inherit;text-align:left;cursor:pointer}
/* Sie ist das letzte Stück der Leiste — über den Karten, die sie
   zusammenfasst. Der Abstand nach oben ist derselbe, den die
   Bereiche voneinander haben. */
.anabar .anahead{margin-top:10px}
/* EIN eingefasster Kasten (Mac-Redesign): Radius 8, flacher
   Schatten, die Kacheln durch 1-px-Linien getrennt — keine
   Überschrift mehr darüber. Wie viele Kacheln es sind, sagt die
   Zeile selbst (grid-auto-flow), nicht eine feste Zahl. */
.anarow{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:1px;
  background:var(--rule);border:1px solid var(--rule);border-radius:8px;overflow:hidden;
  box-shadow:var(--sh-card)}
.anarow .anak{background:var(--paper-2);min-width:0;padding:5px 12px;
  display:flex;align-items:baseline;justify-content:space-between;gap:8px}
/* Die Filterzeile gehört zur Leiste, nicht in eine Karte: sie gilt
   für alle drei Bereiche. Wie sie aussieht, steht ein Stück
   weiter unten — sie und die Zeile der Jahresmatrix tragen
   dieselbe Bahn.

   Weil sie oben klebt, kostet jede umgebrochene Zeile dauerhaft
   Platz — deshalb enger gesetzt als sonst und mit einem Suchfeld,
   das nachgibt. Zehn Knöpfe und das Feld passen so bis hinunter zu
   etwa 1000 px in eine Zeile. */
.anabar .filterbar{margin:0 calc(-1 * var(--pagepad));gap:8px;padding:6px var(--pagepad)}
/* Greift einer der drei Filter, färbt sich die ganze Leiste: sie
   sagt dann, dass hier gerade etwas ausgeblendet wird. Ohne Filter
   bleibt sie grau wie jeder andere Bereich — eine Farbe, die immer
   leuchtet, sagt nichts. Gesetzt wird `.on` in anaBar().

   Leuchtend und nicht als blasse Tönung: die Leiste klebt oben
   unter der Kopfzeile und soll auch dann auffallen, wenn man von
   der Liste darunter kommt. Genommen wird dafür --accent-soft und
   nicht --accent: das satte Orange ist als **Knopf**farbe gedacht
   und wird über eine ganze Leiste hinweg hart. Ihre Knöpfe sind
   von Haus aus durchsichtig — auf dem farbigen Grund bekommen sie
   deshalb Papier unter sich, und der gedrückte bleibt dunkel: die
   Leiste sagt, *dass* gefiltert wird, der Knopf, *was*. Die Linien
   zwischen den Gruppen werden dunkler statt heller, sonst
   verschwänden sie im hellen Orange.

   Ohne Filter bleibt sie hell — eine Farbe, die immer leuchtet,
   sagt nichts. */
/* ── Die Zeile der Jahresmatrix ──────────────────────────────
   Die Knöpfe und das Suchfeld stehen in einer eigenen Zeile
   (.ybrow, gebaut in viewJahr) — **nicht** die ganze Leiste: unter
   ihnen hängt der waagerechte Rollbalken der Matrix, und der
   filtert nichts. Die Zeile trägt dieselbe Bahn wie die
   Filterzeile des Monats — greift der Suchbegriff, färbt ihn .on
   orange, ohne dass etwas springt: Kanten und Polster stehen schon
   da. */
.yearbar .ybrow{flex:1 1 100%;display:flex;justify-content:flex-start;align-items:center;
  gap:8px;flex-wrap:wrap;padding:6px var(--pagepad);margin:0 calc(-1 * var(--pagepad))}
/* ── Die Filterzeile ist eine Bahn über die ganze Seite ───────
   Beide Ansichten tragen dasselbe Bild, und es ist das der
   Monatsleiste: ein flacher Streifen von Rand zu Rand, heller als
   das Papier, mit einer Haarlinie oben und unten — kein
   eingefasster Kasten mehr (bis 22.8.26 grauer Grund, Radius 7,
   Rahmen ringsum). Die negativen Außenmaße heben das Polster von
   .wrap auf, genau wie in der Kopfzeile; --pagepad steht dort und
   ist auf dem Telefon 12 px statt 24.

   Eine Bahn kann keine Ecken haben: border-radius und die beiden
   seitlichen Kanten entfallen, sonst endete die Zeile sichtbar
   einen Pixel vor dem Fensterrand. */
.anabar .filterbar,.yearbar .ybrow{background:var(--paper-2);border:0;border-radius:0;
  border-bottom:1px solid var(--rule);min-height:var(--barh,43px)}
/* **Sie ist genau so hoch wie die Kopfzeile darüber.** Das Maß
   steht nicht hier: die Kopfzeile ist so hoch, wie ihr Inhalt sie
   macht, und das misst syncStickyTops() ohnehin schon für das
   `top` der klebenden Leisten — dasselbe Maß geht als --barh an
   das Wurzelelement. Eine Zahl im Stylesheet liefe beim ersten
   Umbau daneben. Bricht die Zeile um, wächst sie darüber hinaus:
   min-height, keine Höhe. */
/* **Sie dockt oben an der Kopfzeile an, ohne Abstand** — in beiden
   Ansichten das erste, was unter den Reitern kommt. Deshalb hat
   die Leiste, in der sie steckt, kein oberes Polster, und die Bahn
   selbst keine obere Haarlinie: die Kopfzeile bringt ihre eigene
   mit, zwei nebeneinander läsen sich als Doppelstrich. */
.stickybar.anabar{padding-top:0}
.yearbar .ybrow .btn.small{padding:4px 10px;font-size:11.5px}
/* Die beiden Ausblenden-Knöpfe stehen abgesetzt am rechten Rand.
   Sie filtern nicht: sie räumen ab, was fertig ist — der eine die
   Spalten abgerechneter Monate, der andere die Zeilen bezahlter
   Posten. Zwischen ihnen und dem Suchfeld liegt deshalb Luft
   (margin-left:auto) und keine Trennlinie: eine Linie machte aus
   ihnen die nächste Filtergruppe, und genau das sind sie nicht.
   Wird die Zeile zu schmal, rutschen die beiden als Paar in die
   zweite Reihe — dort wieder rechts. */
.yearbar .ybrow .ybhide{margin-left:auto;display:flex;align-items:center;gap:8px}
/* Dieselben Regeln wie im Monat: dort die Filterzeile, hier diese
   Zeile — eine Leiste, die anders aussieht, sähe nach einem
   anderen Werkzeug aus. */
.anabar .filterbar.on,.yearbar .ybrow.on{background:var(--accent-soft);border-color:var(--accent)}
.anabar .filterbar.on .btn,.yearbar .ybrow.on .btn{background:var(--paper-2)}
.anabar .filterbar.on .btn:hover,.yearbar .ybrow.on .btn:hover{background:#fff}
/* ── Angewendet heißt dunkel, immer ─────────────────────────
   Ein gedrückter Knopf trägt Tinte, gleich ob die Zeile gerade
   orange leuchtet oder grau bleibt. Bis 22.8.26 hing das an `.on`:
   die beiden Ausblenden-Knöpfe der Jahresansicht sagten damit nur
   dann sichtbar, dass sie gelten, wenn zufällig auch ein
   Suchbegriff im Feld stand — sie leuchten die Zeile ja
   ausdrücklich nicht an (siehe viewJahr).

   Der :hover-Zwilling ist kein Zierrat: `.on .btn:hover` weiter
   oben ist um eine Klasse spezifischer, und ohne ihn würde ein
   gedrückter Knopf unter der Maus wieder weiß. */
.anabar .filterbar .btn[aria-pressed="true"],.yearbar .ybrow .btn[aria-pressed="true"],
.anabar .filterbar .btn[aria-pressed="true"]:hover,
.yearbar .ybrow .btn[aria-pressed="true"]:hover{background:var(--ink);color:var(--paper-2);
  border-color:var(--ink)}
.anabar .filterbar.on .fbgroup,.yearbar .ybrow.on .fbgroup{border-left-color:rgba(122,53,11,.38)}
.anabar .filterbar .btn.small{padding:4px 10px;font-size:11.5px}
.fltbox.flttop{flex:0 1 230px;width:230px;min-width:140px}

/* ── Die Aufklappmenüs der Filterzeile ────────────────────────
   Der Knopf nennt Gruppe und gewählten Wert, das Menü darunter
   liegt als Overlay über dem Inhalt und verschiebt nie Layout.
   Der gewählte Eintrag steht auf Orange über die volle Zeile —
   dieselbe Farbe, mit der die Leiste sagt, dass gefiltert wird. */
.fltdrop{position:relative;display:inline-flex}
.drophead{display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.drophead .caret{font-size:8px;color:var(--ink-2)}
.drophead[aria-pressed="true"] .caret{color:inherit}
.dropmenu{position:absolute;top:calc(100% + 6px);left:0;z-index:35;display:flex;flex-direction:column;
  min-width:190px;background:#fff;border:1px solid var(--rule);border-radius:8px;
  box-shadow:var(--sh-pop);overflow:hidden;text-align:left}
.dropmenu .mi{display:block;width:100%;background:none;border:0;border-radius:0;text-align:left;
  padding:4px 12px;font-size:12px;color:var(--ink);cursor:pointer;box-shadow:none}
.dropmenu .mi:hover{background:var(--paper-2)}
.dropmenu .mi:disabled{opacity:.45;cursor:not-allowed}
.dropmenu .mi.sel{background:var(--accent-soft);font-weight:600}
.dropmenu .mi.mi-sep{border-bottom:1px solid var(--hairline);padding:6px 12px}
.dropmenu .mi.mi-top{border-top:1px solid var(--hairline);padding:6px 12px}
/* „Gilt gerade" heißt auch im Menü dunkel — der Weg zu den
   Filteroptionen trägt sein aria-pressed wie jeder Filterknopf. */
.dropmenu .mi[aria-pressed="true"]{background:var(--ink);color:var(--paper-2)}
.dropmenu .mghead{padding:5px 12px 2px;font-family:var(--font-data);font-size:8.5px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-2)}
.anahead .anak.t-in{background:var(--bg-in)}
.anahead .anak.t-out{background:var(--bg-out)}
.anahead .anak.t-flex{background:var(--bg-flex)}
.anahead .lab{font-family:var(--font-data);font-size:9px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.anahead .lab b{font-weight:600;color:var(--ink)}
.anahead .val{font-family:var(--font-data);font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;
  white-space:nowrap}

/* ── Der Zeitstrahl ───────────────────────────────────────────
   Fünf Zeilen untereinander: Name mit Tagen, Veränderung,
   Kontostand — und rechts über die ganze übrige Breite der Balken.
   Alle Zeilen haben dasselbe Spaltenmaß, sonst stünden ihre Balken
   nicht übereinander.

   Der Maßstab der Balkenfläche steht nicht hier: er ist der
   Kontostand selbst und wird in js/views/monat.js aus flowScale()
   in Prozent umgerechnet — alle Zeilen teilen ihn sich, sonst
   stünden ihre Balken nicht auf derselben Achse. */
/* Die Maße der Balken stehen an der Fläche, nicht am einzelnen
   Gleis: die Zeile rechnet ihre Höhe daraus (siehe unten), und beide
   müssen dieselben Zahlen nehmen. --nbars ist die Höhe in Balken;
   gesetzt wird sie am Element (TL_MINBARS in js/views/monat.js), der
   Wert hier ist nur der Rückfall.

   **Die Fuge (--bgap) ist breiter als die Fuge zwischen zwei
   Zeilen.** Zwei Balken von 5 px, die nur ein Haar trennt, liest
   man als einen dicken; erst der Abstand macht aus zwei Farben
   zwei Angaben. Er kostet je Zeile so wenig, wie er breit ist —
   deshalb 3 px und nicht mehr: der Zeitstrahl klebt beim Rollen
   oben, und jeder Pixel fehlt der Liste darunter fünfmal. */
/* Der Zeitstrahl als weiße Karte (Mac-Redesign): Radius 8, flacher
   Schatten, die Zeilen durch die Haarlinie getrennt (die 1-px-Fugen
   des Stapels), Balken 4 px. overflow:hidden ist hier erlaubt —
   in der Karte klebt nichts. */
.tline{display:flex;flex-direction:column;gap:1px;background:var(--hairline);
  border:1px solid var(--rule);border-radius:8px;overflow:hidden;margin-top:6px;
  box-shadow:var(--sh-card);
  --bh:4px;--bgap:3px;--bpad:2px;--nbars:3}
.trow{display:grid;grid-template-columns:172px 84px 84px minmax(0,1fr);align-items:center;gap:8px;
  background:#fff;border:0;padding:2px 10px;font:inherit;color:inherit;text-align:left}
.trow:hover{background:var(--chrome-hi)}
/* Alle Zeilen sind gleich hoch, auch die ohne Zahl: gefiltert trägt
   nur der gewählte Abschnitt seine Beträge, die übrigen stehen als
   blasse Balken da. Das Maß ist --nbars, die Höhe in Balken — und
   es gilt für **alle** Zeilen der Fläche, damit nichts springt,
   wenn ein Abschnitt gewechselt wird oder ein Filter greift.

   **Senkrechtes Polster hat die Zeile keins**; die 4 px stecken in
   ihrer Höhe. Sonst säße zwischen zwei Balkenflächen eine Lücke aus
   Polster und Fuge, und die Rasterlinien wären in jeder Zeile ein
   eigener Strich statt einer durchgehenden Linie über die ganze
   Fläche (siehe .tline .ttrack).

   **Die Achszeile bleibt außen vor**: sie trägt keine Balken,
   sondern nur die Beträge des Rasters, und ist so hoch wie diese
   Schrift. */
.tline .trow:not(.taxis){padding-top:0;padding-bottom:0;
  min-height:calc(var(--nbars)*var(--bh) + (var(--nbars) - 1)*var(--bgap) + 2*var(--bpad) + 4px)}
/* Gefiltert heißt hier nicht dunkel: Zahlen und Balken stehen
   darin und müssen lesbar bleiben. Stattdessen ein Rahmen nach
   innen — dieselbe Aussage, ohne etwas zu verdecken. */
.trow[aria-pressed="true"]{box-shadow:inset 0 0 0 2px var(--ink)}
/* Jede Zelle steht in ihrer Spalte, nicht in der nächsten freien:
   in schmalen Fenstern fällt die Veränderung weg (display:none),
   und ohne feste Spalte rückten Kontostand und Balken dann eine
   Spalte nach links. */
.trow .tname{grid-column:1}
.trow .tflow{grid-column:2}
.trow .trun{grid-column:3}
.trow .ttrack{grid-column:4}
/* Die Beschriftung ist keine Nebensache: sie sagt, welcher Teil
   des Monats das ist, und steht deshalb in Schwarz wie die
   Bezeichnungen der Positionen. Nur die Tage daneben treten
   zurück. */
/* Die Beschriftung im Mac-Ton: gewöhnliche Oberflächenschrift,
   12 px, kein Versalsatz — die Tage stehen in ihrer Sprechblase
   (tlLabel in js/views/monat.js). */
.trow .tname{display:flex;align-items:baseline;gap:6px;min-width:0;
  font-family:var(--font-ui);font-size:12px;font-weight:400;color:var(--ink);
  white-space:nowrap;overflow:hidden}
/* Der heutige Tag liegt in dieser Zeile: eine Marke in der
   Hervorhebungsfarbe — nur Rahmen und Schrift, der Grund bleibt
   durchsichtig. Gefüllt und rot wäre sie eine Warnung. */
.trow .tnow{font-size:8.5px;letter-spacing:.08em;color:var(--accent-2);
  border:1px solid var(--accent-2);background:none;padding:0 3px;font-weight:600}
/* Die Veränderung ist ein Betrag wie jeder andere und wird auch so
   gesetzt: dieselbe Größe wie in der Tabelle darunter. Der Stand
   danach steht immer in Tinte — sein Vorzeichen liest man an der
   Veränderung und am Balken, nicht an einer zweiten Farbe. */
.trow .tflow{font-family:var(--font-data);font-size:12px;font-variant-numeric:tabular-nums;
  text-align:right;white-space:nowrap}
.trow .trun{font-family:var(--font-data);font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;
  text-align:right;white-space:nowrap}
.trow .trun.pos,.trow .trun.neg{color:var(--ink)}
/* Was der Monat vorfindet, ist kein Zeitraum, sondern ein Stand.
   Die Zeile sieht aus wie jede andere — nur klicken lässt sie sich
   nicht: es gibt nichts, wonach sie filtern könnte. Deshalb auch
   kein Hinweis beim Überfahren. */
.trow.tp-P{cursor:default}
.trow.tp-P:hover{background:var(--paper-2)}

/* ── Der Wasserfall ───────────────────────────────────────────
   Die Achse ist der Kontostand selbst: 0 % der tiefste Stand des
   Monats (höchstens die Null), 100 % der höchste. Links der Null
   liegt der rote, rechts der grüne Bereich — steht der Monat ganz
   im Plus, ist die ganze Fläche grün.

   Jede Zeile beginnt beim Stand der Zeile davor und endet bei
   ihrem eigenen. Was dazwischen liegt, steht als Block da: der
   Zufluss oben, der Abfluss unten, beide nach Geldart eingefärbt.
   Alles darin ist absolut gesetzt — die Stellen kommen aus der
   Achse, nicht aus der Reihenfolge im Quelltext. */
/* --bpad ist der Rand über und unter den Balken: der schwarze
   Strich des Kontostands reicht über sie hinaus und ist dadurch
   auch dort zu sehen, wo ein Balken endet.

   **Die drei Maße stehen nicht hier**, sondern an der Fläche, die
   sie braucht: .tline für den Zeitstrahl, .ytrack für den Verlauf
   der Prognose. Dort rechnet auch die Zeile ihre Höhe daraus —
   stünden sie am Gleis, hätte die Zeile andere Zahlen als ihre
   Balken. Klein sind sie mit Absicht: der Zeitstrahl steht über der
   Liste, an der gearbeitet wird, und klebt beim Rollen mit; jeder
   Pixel, den er hoch ist, fehlt den Zeilen darunter fünfmal. Ein
   Balken von 5 px trägt seine Farbe immer noch, und die Form des
   Monats liest man an der Länge, nicht an der Dicke. */
.ttrack{position:relative;min-width:0;overflow:hidden;
  height:calc(var(--bh) + 2*var(--bpad))}
/* Die Trennlinie zwischen der Zahlenseite und der Balkenfläche —
   dieselbe Linie wie die Null zwischen Minus und Plus. Sie läuft
   als border, damit Zonen und Balken erst dahinter anfangen, und
   sie gilt auch der Achszeile: so reicht sie von den Beträgen bis
   unter die letzte Zeile. Nur im Zeitstrahl — der Verlauf der
   Prognose (.ytrack) hat seine Trennlinie von der Tabelle.

   **Die Fläche füllt ihre Zeile ganz** (align-self:stretch) — so
   laufen Raster, Null und die farbigen Zonen von Zeilenrand zu
   Zeilenrand und ergeben über alle Zeilen hinweg eine durchgehende
   Linie; unterbrochen wird sie nur von der 1-px-Fuge zwischen zwei
   Zeilen. Wie hoch die Zeile ist, sagt --nbars (siehe oben), nicht
   die Fläche selbst. Die Achszeile (.taxis) behält ihre eigene
   Höhe. */
.tline .ttrack{border-left:1px solid var(--rule);
  align-self:stretch;height:auto}
/* Zwei Balken in einer Zeile brauchen die doppelte Höhe — beide
   sollen gleich hoch sein, keiner gequetscht. Die Klasse trägt nur
   die Zeile, die beide Richtungen hat: im Verlauf der Prognose ist
   jede Zeile so hoch, wie sie sein muss. **Nur dort**: im Zeitstrahl
   sind alle Zeilen gleich hoch (--nbars), und die Fläche füllt ihre
   Zeile — deshalb .ytrack.two und nicht .ttrack.two. */
.ytrack.two{height:calc(var(--bh)*2 + var(--bgap) + 2*var(--bpad))}
.ttrack>*{position:absolute;top:0;height:100%}
.tzone{top:0}
/* Minus und Plus tragen dieselben hellen Gründe wie die Zeilen der
   Bereiche darunter: rot wie ein Posten der regelmäßigen Kosten,
   grün wie eine Einnahme — dieselbe Aussage, dieselbe Farbe. */
.z-neg{left:0;background:var(--bg-out)}
.z-pos{background:var(--zone-in)}
/* Die Null ist dunkler als das Raster (#7A827B, Mac-Redesign 4b) —
   sie ist ein Wert, das Raster nur ein Maß. */
.tzero{width:1px;background:#7A827B}
/* Zufluss oben, Abfluss unten: in einer Zeile, in der erst eine
   Einnahme kommt und danach Kosten abgehen, überdecken sich die
   beiden Strecken auf der Achse. */
.tup,.tdown{display:flex;height:var(--bh);top:var(--bpad);overflow:hidden}
.tdown{flex-direction:row-reverse}
.ytrack.two .tdown{top:calc(var(--bpad) + var(--bh) + var(--bgap))}
/* Der einzige Balken einer zweibalkig hohen Zeile rückt in die
   Mitte — im Verlauf der Prognose ist das die .two-Zeile, der eine
   Richtung fehlt. */
.ytrack.two .solo{top:calc(var(--bpad) + (var(--bh) + var(--bgap))/2)}
/* ── Im Zeitstrahl stehen die Balken mittig in ihrer Zeile ────
   Untereinander, aber als **Gruppe** in der Mitte: nimmt ein Filter
   den zweiten Balken weg, klebte der übrige sonst oben, als fehlte
   darunter noch einer. Gerechnet wird von der Mitte aus (top:50 %),
   nicht vom Polster — die Zeile kann höher sein als ihre Balken
   (mehr Balken in einer anderen Zeile, ein hoher Betrag daneben),
   und mittig soll es in jedem Fall stehen.

   Die Verschiebung ist die halbe Gruppenhöhe nach oben, dann je
   Balken eine Stufe nach unten. Für die beiden festen Fälle steht
   sie hier ausgerechnet; die Balken der gefilterten Fassung
   (.tflat .fbar) bekommen sie aus partLine(), weil dort erst die
   Zahl der Balken feststeht. */
.tline .ttrack .tup,.tline .ttrack .tdown,.tline .ttrack .tsum{top:50%}
.tline .ttrack .solo{transform:translateY(calc(var(--bh)/-2))}
.tline .ttrack.two .tup{transform:translateY(calc(-1*(var(--bh) + var(--bgap)/2)))}
.tline .ttrack.two .tdown{transform:translateY(calc(var(--bgap)/2))}
.ttrack i{display:block;height:100%;flex:0 0 auto;min-width:2px}
/* Eine helle Fuge zwischen zwei Anteilen — ohne sie liefen zwei
   ähnliche Farben ineinander. */
.tup i+i{box-shadow:inset 1px 0 0 rgba(255,255,255,.55)}
.tdown i+i{box-shadow:inset -1px 0 0 rgba(255,255,255,.55)}
.b-in{background:var(--edge-in)}
/* Das Gelb der Flexible Payments hell, nicht als Kantenfarbe: im
   Balken neben Grün und Rot wirkte --edge-flex braun. */
.b-flex{background:var(--bg-flex-3)}
.b-out{background:var(--edge-out)}
.b-bal{background:var(--edge-bal)}
/* Der Stand, mit dem der Monat anfängt: ein voller Balken von der
   Null bis zu seinem Wert — keine Veränderung, sondern ein Stand,
   deshalb die Farbe des Saldos und keine Geldart. */
.tsum{top:var(--bpad);height:var(--bh);background:var(--edge-sal);opacity:.75}
/* Beschnittene Achse: der Balken der Monatseröffnung fängt nicht bei
   null an, sondern kommt von weiter außerhalb. Statt einer Marke an
   seinem Anfang franst er dort aus — die Farbe läuft ins Nichts, und
   damit liest sich der Rand als Fortsetzung und nicht als Ende. Eine
   Marke behauptete dagegen eine Kante, wo der Balken gerade keine
   hat, und sie musste den Balken dafür abdunkeln, um sichtbar zu
   bleiben; er bleibt jetzt so kräftig wie jeder andere.
   Ausgefranst wird an der Seite, an der die Null hinausfällt: bei
   einem Guthaben links, bei einem Minus rechts.
   Die Länge des Verlaufs ist gedeckelt, damit ein kurzer Balken
   nicht ganz darin verschwindet. */
.tsum.cutl{background:linear-gradient(to right,transparent 0,var(--edge-sal) min(38px,60%))}
.tsum.cutr{background:linear-gradient(to left,transparent 0,var(--edge-sal) min(38px,60%))}
/* ── Der gewählte Abschnitt (partLine in js/views/monat.js) ────
   Gefiltert gibt es keinen Wasserfall: die fünf Zeilen bleiben,
   jede mit ihren Balken je Geldart — die gewählte kräftig, die
   übrigen blass (.pale). Die Fläche trägt **denselben Grund und
   dasselbe Raster wie der Wasserfall**: links der Null rot, rechts
   grün (.tzone, gesetzt in partLine), dieselben Linien (.tgrid) —
   zwei Gründe für dieselbe Grafik ließen den Filter nach einer
   anderen Ansicht aussehen. Die Höhe ist die der Zeile (--nbars,
   siehe oben) — für alle Zeilen dieselbe.
   **Die Null steht zwischen Minus und Plus** (.tzero): was
   hereinkommt, wächst nach rechts, was abgeht, nach links — und
   genau das sagen auch die beiden Farben. Lage und Breite jedes
   Balkens rechnet partLine() und setzt sie am Element, senkrecht
   mittig wie überall. */
.tflat .fbar{height:var(--bh);min-width:2px}
.tflat .fbar.pale{opacity:.22}
/* Gewählt sagen die Trennlinien: über und unter der gewählten
   Zeile liegen sie in der Hervorhebungsfarbe — der Schatten malt
   in die 1-px-Fugen des .tline-Stapels. **Nur die Linien**: die
   Zeile behält den Grund aller anderen, denn in ihr stehen Zahlen
   und Balken. Der Rahmen nach innen der übrigen Filter bleibt dem
   Wasserfall (weite Suche). */
.tline.part .trow[aria-pressed="true"]{
  box-shadow:0 -1px 0 var(--accent),0 1px 0 var(--accent)}
/* Die Achszeile über dem Zeitstrahl (tlAxis): an jeder Rasterlinie
   ihr Betrag — eine schmale Zeile, nur in der Spalte der Balken.
   Kein Knopf und keine Sprechblase, nur die Beschriftung des
   Maßes; die Marken kommen mit ihrer Verschiebung aus dem Skript. */
.trow.taxis{padding-top:0;padding-bottom:0;cursor:default}
.trow.taxis:hover{background:#fff}
.taxis .ttrack{height:20px;overflow:visible}
.taxis .tzlab{top:auto;bottom:5px;height:auto;font-family:var(--font-data);font-size:8.5px;
  line-height:1;font-weight:400;color:var(--ink-2)}
/* Derselbe Balken im Verlauf der Prognose (.ytrack) besteht aus
   mehreren Farben — dort franst nicht ein Hintergrund aus, sondern
   der ganze Balken samt seiner Anteile. Deshalb eine Maske und
   kein Verlauf im Hintergrund. */
.ytrack .tup.cutl,.ytrack .tdown.cutl{
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 min(38px,60%));
  mask-image:linear-gradient(to right,transparent 0,#000 min(38px,60%))}
.ytrack .tup.cutr,.ytrack .tdown.cutr{
  -webkit-mask-image:linear-gradient(to left,transparent 0,#000 min(38px,60%));
  mask-image:linear-gradient(to left,transparent 0,#000 min(38px,60%))}
/* Der Verlauf über das Jahr benutzt dieselbe Fläche wie der
   Zeitstrahl — und **dieselbe Balkenhöhe**: es ist dieselbe Grafik,
   nur eine Ebene höher, und zwei Dicken nebeneinander läsen sich
   als zwei verschiedene Maße. Die Zeilenhöhe gibt hier die Tabelle
   daneben vor, nicht --nbars. Ein größeres Polster bleibt: der
   kräftige Strich des Kontostands reicht über die Balken hinaus
   und soll auch dort zu sehen sein, wo einer endet. Die Maße stehen
   als Variablen an .ttrack — hier werden nur sie überschrieben,
   alles andere gilt unverändert. */
.ytrack{--bh:5px;--bgap:3px;--bpad:3px;display:block;width:100%}
/* Der Anfangsbestand in seiner eigenen Zeile über dem Januar:
   derselbe Balken wie die Monatseröffnung im Zeitstrahl, aber in
   demselben kräftigen Violett wie seine Beschriftung und sein
   Betrag — die drei gehören zusammen und sollen zusammen ins Auge
   fallen. Ist er länger als ein Rasterschritt, zeigt die Ansicht
   nur den letzten Schritt davon, und der franst aus. */
/* Der kräftige Strich ist 2 px breit, eine Rasterlinie 1 px. Damit
   beide **dieselbe Mitte** haben — und ein Anfangsbestand, der genau
   auf einer Linie liegt, seinen Strich genau darauf setzt —, rückt
   er hier ein halbes Pixel weiter als im Zeitstrahl, wo es kein
   Raster gibt, gegen das er fluchten müsste. */
.ytrack .tmark{margin-left:-.5px}
.ytrack .yopen{background:var(--ink-sal);opacity:1}
.ytrack .yopen.cutl{background:linear-gradient(to right,transparent 0,var(--ink-sal) min(38px,60%))}
.ytrack .yopen.cutr{background:linear-gradient(to left,transparent 0,var(--ink-sal) min(38px,60%))}
.ytrack .tsum.cutl{background:linear-gradient(to right,transparent 0,var(--edge-sal) min(38px,60%))}
.ytrack .tsum.cutr{background:linear-gradient(to left,transparent 0,var(--edge-sal) min(38px,60%))}
/* Das Raster des Verlaufs: helle senkrechte Linien in festem
   Betragsabstand. Sie stehen in jeder Zeile an derselben Stelle
   und fluchten dadurch über die zwölf Monate — erst dadurch liest
   man an der Treppe ab, **um wie viel** sich etwas ändert, und
   nicht nur, dass es das tut. Heller als die Null (.tzero): die
   ist ein Wert, das Raster ist nur ein Maß. */
.tgrid{width:1px;background:var(--rule);opacity:.85}
.lk i.lgrid{width:1px;height:11px;background:var(--rule);opacity:.85}
/* Die Treppe: feine Linie beim Stand davor, kräftiger Strich beim
   neuen. Der Strich einer Zeile steht genau über der Linie der
   nächsten. */
.tconn{width:1px;background:var(--ink);opacity:.22}
.tmark{width:1.5px;background:var(--ink);margin-left:-1px}

/* Die Farberklärung unter den Zeilen — seit an einem Anteil nur
   noch sein Betrag steht, ist die Farbe das Einzige, was die
   Geldart nennt. Sie ist das Letzte unter der Fläche: der Satz
   darunter, wohin alles ohne Zahltag gerät, ist seit 19.8.26
   gestrichen — dasselbe sagt der Filterknopf „Monatsabschluss". */
.thint{display:flex;flex-wrap:wrap;gap:4px 12px;background:#fff;padding:4px 10px;
  font-size:9.5px;color:var(--ink-2);cursor:help}
.thint .lk{display:flex;align-items:center;gap:4px;white-space:nowrap}
.thint i{display:block;width:8px;height:8px;border-radius:2px}
.thint i.lmark{width:1.5px;height:10px;background:var(--ink);border-radius:0}
/* Der Maßstab steht am Ende der Farberklärung — dort ist Platz,
   und er gehört zur Fläche, nicht zu einer Zeile. */
.thint .lscale{margin-left:auto;font-family:var(--font-data);font-size:9.5px;white-space:nowrap}
/* Wird es eng, weicht zuerst die Veränderung: der Kontostand und
   der Balken sagen dasselbe genauer. */
@media(max-width:900px){
  .trow{grid-template-columns:140px 0 104px minmax(0,1fr)}
  .trow .tflow{display:none}
}

/* ── Die Rollleiste über einer Tabelle ────────────────────────
   Der waagerechte Rollbalken einer Tabelle sitzt von Haus aus in
   ihr: am unteren Rand des Rollrahmens, quer über der letzten
   Zeile — und bei der Jahresmatrix, die in voller Länge im Dokument
   steht, erst nach allen Zeilen. Beides ist der falsche Ort.

   Deshalb verbergen die beiden Tabellen ihren eigenen Balken und
   bekommen einen über sich gesetzt (scrollRail in js/ui.js). Er ist
   ein gewöhnlicher Rollrahmen mit einem Streifen darin, der so
   breit ist wie die Tabelle — mehr braucht ein Rollbalken nicht.

   Er wird **gestaltet**, damit er dauerhaft zu sehen ist: ein
   Balken, der wie unter macOS erst beim Rollen auftaucht, wäre an
   dieser Stelle keine Hilfe, denn er ist hier der Weg zum Rollen
   und nicht dessen Anzeige. */
.scrollrail{overflow-x:auto;overflow-y:hidden;height:10px;margin:0;
  scrollbar-width:thin;scrollbar-color:var(--rule-strong) var(--paper)}
.scrollrail>div{height:1px}
/* Passt die Tabelle ins Fenster, gibt es nichts zu rollen — dann
   steht dort auch keine leere Rille (bindRails setzt die Klasse). */
.scrollrail.off{display:none}
.scrollrail::-webkit-scrollbar{height:10px}
.scrollrail::-webkit-scrollbar-track{background:var(--paper);border:1px solid var(--rule)}
.scrollrail::-webkit-scrollbar-thumb{background:var(--rule-strong);border:1px solid var(--paper)}
.scrollrail::-webkit-scrollbar-thumb:hover{background:var(--ink-2)}
/* In der Knopfleiste der Jahresmatrix steht sie auf einer eigenen
   Zeile, über die ganze Breite: sie gehört zur Tabelle darunter und
   nicht zwischen die Knöpfe — **deshalb sitzt sie an ihr**. Die
   10 px Abstand liegen über der Leiste, das negative Maß darunter
   hebt das Polster der Knopfleiste auf. So bleibt zwischen der
   Filterzeile und dem Spaltenkopf der Matrix genau so viel Luft,
   wie die Bereiche voneinander haben (10 px) — mit Rollbalken wie
   ohne, denn ohne ihn (.off) trägt das Polster der Leiste dieselben
   10 px allein. */
.yearbar .scrollrail{flex:0 0 100%;margin:10px 0 -10px}
/* In der Prognose steht sie in der Karte, direkt über der Tabelle. */
.progscroll+.scrollrail,.scrollrail+.progscroll{margin-top:6px}
/* Und die Tabellen selbst zeigen unten **keinen** waagerechten
   Balken: dafür ist die Leiste oben da, zwei wären einer zu viel.

   Die Prognose rollt nur waagerecht und legt ihren Balken einfach
   ab. Die Jahresmatrix rollt in beiden Richtungen und braucht ihren
   senkrechten; je Achse lässt sich aber keiner abschalten
   (`::-webkit-scrollbar:horizontal` befolgt Chrome nicht). Ihr wird
   der waagerechte deshalb **abgeschnitten** — siehe .yearpane in
   css/matrix.css. Gerollt wird dabei weiter vom Browser selbst, und
   nur das rollt weich. */
.progscroll{scrollbar-width:none}
.progscroll::-webkit-scrollbar{height:0;display:none}
/* Die Matrix liegt seit dem Mac-Redesign nicht mehr in einem
   eigenen Rahmen: die Blöcke tragen ihre Karten selbst, und
   zwischen ihnen scheint das Papier durch (tr.spacer). */
.yearscroll{border:0;background:transparent}
.yearscroll{scrollbar-width:thin}
.yearscroll::-webkit-scrollbar{width:11px}
.yearscroll::-webkit-scrollbar-track{background:var(--paper)}
.yearscroll::-webkit-scrollbar-thumb{background:var(--rule-strong);border:2px solid var(--paper)}
.yearscroll::-webkit-scrollbar-thumb:hover{background:var(--ink-2)}

/* ── Die Jahresansicht füllt den Bildschirm ───────────────────
   Die Matrix rollt senkrecht selbst; die Seite darunter soll es
   dann nicht auch noch tun, sonst schöbe sich die ganze Fläche
   samt ihren klebenden Zeilen aus dem Bild. Das Polster am
   Seitenende, das sonst Luft nach unten lässt, wäre hier nur ein
   Grund zum Rollen. */
body.yearview .wrap{padding-bottom:14px}

/* ── Restliches Gerüst ────────────────────────────────────── */
.scroll{overflow-x:auto;border:1px solid var(--rule);background:var(--paper-2)}
.empty{padding:34px 18px;text-align:center;color:var(--ink-2);border:1px dashed var(--rule-strong);background:var(--paper-2)}
.empty strong{display:block;font-family:var(--font-display);font-size:19px;color:var(--ink);margin-bottom:6px}
.status{font-family:var(--font-data);font-size:11px;color:var(--ink-2);margin-top:14px;border-top:1px solid var(--rule);padding-top:10px}
.status b{color:var(--ink);font-weight:600}

/* ══ Die Begrüßungsseite ══════════════════════════════════════
   Steht vor allem anderen — beim Öffnen der Anwendung und wieder
   nach dem Trennen der Datei (js/views/willkommen.js). Sie ist die
   Tür zwischen der Startseite und dem Buch und trägt deshalb die
   Gestalt der Startseite, nicht die des Kontoblatts: runde Karten,
   weiche Schatten, der orange Akzent — dieselben Maße und
   Schattenwerte wie css/landing.css. Die Werte stehen hier
   ausgeschrieben, denn landing.css lädt der Web-Client nicht. */
.welcome{position:relative;display:grid;place-items:start center;padding:48px 0 80px}
/* Der Hintergrund atmet wie auf der Startseite: drei weiche
   Farbflächen, dieselben Töne (bg der Verkaufsseiten). */
.wbg{position:absolute;inset:-40px 0 0;overflow:hidden;pointer-events:none}
.wbg i{position:absolute;border-radius:50%;filter:blur(70px);opacity:.55}
.wbg i:nth-child(1){width:420px;height:420px;background:var(--bg-in-2);top:-120px;right:6%}
.wbg i:nth-child(2){width:360px;height:360px;background:var(--bg-sal-2);top:30%;left:-140px}
.wbg i:nth-child(3){width:380px;height:380px;background:var(--bg-flex-2);bottom:-160px;right:18%}
.wbox{position:relative;width:min(720px,100%);background:var(--paper-2);
  border:1px solid var(--rule-strong);border-radius:16px;
  box-shadow:0 2px 6px rgba(27,35,32,.08),0 22px 48px rgba(27,35,32,.15);
  padding:38px 44px 36px}
/* Das kleine Wortzeichen oben trägt das Orange der Startseiten-
   Dachzeile (.eyebrow): dieselbe Stimme, dieselbe Farbe. */
.wmark{font:600 11px var(--font-data);letter-spacing:.34em;text-transform:uppercase;
  color:var(--accent-2)}
/* Kopfreihe der Begrüßung: links das Wortzeichen, rechts die
   Sprachwahl — zwei Pillen wie der Sprachschalter der
   Verkaufsseiten (.langsw), die gewählte dunkel. Sie steht **nur**
   hier: sobald ein Buch offen ist, entscheidet die Datei, und
   geändert wird das im Einstellungsfenster. */
.wtop{display:flex;align-items:center;justify-content:space-between;gap:12px}
.wlangs{display:flex;gap:4px}
.wlang{cursor:pointer;padding:6px 11px;border:1px solid var(--rule-strong);border-radius:8px;
  background:var(--paper-2);color:var(--ink-2);
  font:600 11px var(--font-data);letter-spacing:.08em;
  transition:background .18s ease,color .18s ease,border-color .18s ease}
.wlang:hover{border-color:var(--ink);color:var(--ink)}
.wlang[aria-pressed="true"]{background:var(--ink);color:var(--paper-2);border-color:var(--ink)}
.wbox h2{font-family:var(--font-display);font-weight:600;font-size:clamp(28px,5vw,38px);
  line-height:1.15;letter-spacing:-.02em;margin:14px 0 12px;color:var(--ink)}
/* Kein eigenes Zeilenmaß für den Text: er läuft so weit wie die
   Knopfreihe darunter, und die rechte Kante der Seite ist überall
   dieselbe. Ein Deckel in ch endete mitten in der Fläche und ließ
   die Karten daneben wie einen Nachtrag aussehen; die Breite
   begrenzt schon .wbox. */
.wlead{font-size:16px;line-height:1.65;color:var(--ink-2);margin:0 0 14px}
.wlist{margin:0 0 16px;padding-left:20px;font-size:14px;line-height:1.6;color:var(--ink)}
.wlist li{margin-bottom:3px}
.wlist li b{font-weight:600}
/* Zwei Wege, gleich groß nebeneinander — beides sind Angebote, nur
   eines ist das gewöhnliche: es trägt das Orange der Startseite
   (deren .button-primary) und hebt sich beim Überfahren wie die
   Karten dort. */
.wpick{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:24px 0 6px}
.wcard{display:grid;align-content:start;gap:6px;text-align:left;padding:20px 22px;cursor:pointer;
  background:var(--paper);border:1px solid var(--rule-strong);border-radius:14px;color:var(--ink);
  box-shadow:0 1px 2px rgba(27,35,32,.05),0 10px 28px rgba(27,35,32,.08);
  transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease,background .18s ease}
.wcard:hover{transform:translateY(-2px);border-color:var(--ink);
  box-shadow:0 2px 6px rgba(27,35,32,.08),0 22px 48px rgba(27,35,32,.15)}
.wcard .wt{font-family:var(--font-ui);font-size:17px;font-weight:600}
.wcard .wd{font-size:13px;line-height:1.55;color:var(--ink-2)}
.wcard.primary{background:var(--accent);border-color:var(--accent);color:#fff}
.wcard.primary:hover{background:var(--accent-2);border-color:var(--accent-2)}
.wcard.primary .wd{color:rgba(255,255,255,.85)}
.wfoot{font-size:11.5px;line-height:1.55;color:var(--ink-2);margin:8px 0 0}
/* Der Satz, der zur Anleitung schickt, trägt deren Farbe — in der
   Kopfzeile ist der Anleitungsknopf der einzige orange, und hier
   soll man ihn wiedererkennen. Genommen wird die dunklere Stufe
   (--accent-2, die des gedrückten Knopfes): bei 11,5 px braucht
   Text mehr Abstand zum Papier als eine Knopffläche. */
.wfoot.wguide{color:var(--accent-2)}
.wfoot.wguide b{color:var(--accent-2)}
/* Der Weg zur Downloadseite ist der letzte Satz der Seite und der
   einzige, der von ihr wegführt. Er bleibt grau wie der Rest —
   orange trägt hier schon die Anleitung, und zwei Farben nähmen
   sich gegenseitig die Aufmerksamkeit. Eine feine Linie darüber
   setzt ihn ab: er gehört nicht mehr zum Einrichten. */
.wfoot.wapp{border-top:1px solid var(--rule);padding-top:9px;margin-top:13px}
.wfoot.wapp a{color:var(--ink)}
@media(max-width:620px){
  .wbox{padding:26px 20px 24px}
  .wpick{grid-template-columns:1fr}
}
