/* Haushaltskasse - Gestaltung.
   Dunkel als Grundton, weil die App abends am Handy benutzt wird.
   Helles Schema wird respektiert, falls das Geraet danach fragt. */

:root {
  --bg: #0d0f13;
  --karte: #171a21;
  --karte-innen: #1e222b;
  --text: #eceef2;
  --gedaempft: #8b93a1;
  --linie: #272c36;
  --akzent: #2fe0a8;
  --akzent-schwach: #17332b;
  --gut: #2fe0a8;
  --schlecht: #ff6b6b;
  --ki: #6aa8ff;
  --warten: #ffc233;
  --radius: 18px;
  --radius-klein: 12px;
}
@media (prefers-color-scheme: light) {
  :root {
    --bg: #f2f4f7;
    --karte: #ffffff;
    --karte-innen: #f6f8fa;
    --text: #131519;
    --gedaempft: #67707e;
    --linie: #e2e6ec;
    --akzent: #10a37f;
    --akzent-schwach: #dff5ee;
    --gut: #10a37f;
    --schlecht: #d1453b;
    --ki: #2f6fd0;
    --warten: #e8a200;
  }
}

* { box-sizing: border-box; }

/* Das hidden-Attribut muss gewinnen.

   Die Browserregel dafür ist [hidden] { display: none } - ein
   Attributselektor, und der verliert gegen jede Klasse, die selbst ein
   display setzt. Genau das ist passiert: .neue-fassung { display: flex }
   hat die Leiste dauerhaft sichtbar gemacht, auf jeder Seite und jedem
   Gerät, obwohl das Attribut korrekt gesetzt war. Die Logik dahinter war
   nie das Problem - sie konnte nur nichts ausrichten.

   Deshalb hier ein für alle Mal, und mit !important, damit es auch für
   jede künftige Klasse gilt. */
[hidden] { display: none !important; }
html, body { overscroll-behavior-y: contain; }
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  padding-bottom: calc(4.6rem + env(safe-area-inset-bottom));
}
a { color: inherit; text-decoration: none; }

/* ------------------------------------------------------------------ Kopfzeile */

header {
  display: flex; align-items: center; gap: .5rem;
  padding: max(env(safe-area-inset-top), .8rem) .9rem .7rem;
  position: sticky; top: 0; z-index: 20;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: blur(14px);
}
.kopfmitte { flex: 1; text-align: center; }
header h1 { font-size: 1.3rem; font-weight: 700; margin: 0; letter-spacing: -.01em; }
.zeitraum { margin: .1rem 0 0; font-size: .74rem; color: var(--gedaempft); }
.pfeil {
  background: var(--karte); border: 0; color: var(--text); font-size: 1.4rem;
  line-height: 1; width: 2.2rem; height: 2.2rem; border-radius: 50%;
  cursor: pointer; display: grid; place-items: center; flex: none;
}
.pfeil:active { background: var(--linie); }
.pfeil[hidden] { visibility: hidden; display: grid; }

main {
  /* Unten so viel Luft, dass der letzte Knopf einer Seite nicht unter den
     Schwebeknöpfen liegt. Die sitzen bei `bottom: 5.4rem` und sind 3.4rem
     hoch, ihre Oberkante steht also 8.8rem über dem Fensterrand. Mit 1rem
     Polster lag „Ausgewählte anlegen" genau darunter (4619815c, im Browser
     nachgemessen: Knopf 647–691, Plus 671–726). */
  padding: .3rem .9rem calc(9.2rem + env(safe-area-inset-bottom));
  max-width: 44rem; margin: 0 auto;
}

/* --------------------------------------------------------------------- Kacheln */

.kachel {
  background: var(--karte); border-radius: var(--radius);
  padding: 1.1rem; margin-bottom: .8rem;
}
.kachel.flach { padding: 1.1rem .9rem; }
/* Umbrechen statt hinauslaufen. Ein Kopf mit einem einzigen Knopf bleibt, wie
   er war - erst wenn mehrere nicht mehr nebeneinander passen, faellt eine
   Zeile um. Rueckmeldung 032afc9c. */
.kachel-kopf {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: .4rem 1rem;
}
/* Die Knoepfe eines Kopfes als eine Gruppe: so brechen sie gemeinsam um und
   bleiben rechts, statt sich einzeln ueber die Zeile zu verteilen. */
.kopf-knoepfe {
  display: flex; flex-wrap: wrap; justify-content: flex-end;
  gap: .2rem; margin-left: auto; min-width: 0;
}
.label {
  margin: 0 0 .1rem; color: var(--gedaempft); font-size: .72rem;
  text-transform: uppercase; letter-spacing: .09em; font-weight: 600;
}
.mehr { color: var(--akzent); font-size: .82rem; font-weight: 600; }

/* ------------------------------------------------------------------------ Ring */

.ring-kachel { padding-top: 1.4rem; }
.ring-block { display: flex; align-items: center; justify-content: space-between; gap: .4rem; }
.ring-seite { text-align: center; flex: 1; min-width: 0; }
.ring-seite b {
  display: block; font-size: 1.15rem; font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.ring-seite span { display: block; font-size: .72rem; color: var(--gedaempft); margin-top: .15rem; }
.ring-mitte { position: relative; width: 9.5rem; height: 9.5rem; flex: none; }
.ring { width: 100%; height: 100%; display: block; }
.ring circle { fill: none; stroke-width: 10; stroke-linecap: round; }
.ring-spur { stroke: var(--karte-innen); }
.ring-wert { stroke: var(--akzent); transition: stroke-dasharray .5s ease; }
.ring-wert.ueberzogen { stroke: var(--schlecht); }
.ring-text {
  position: absolute; inset: 0; display: grid; place-content: center;
  text-align: center; gap: .1rem;
}
.ring-text b {
  font-size: 1.85rem; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.ring-text b.negativ { color: var(--schlecht); }
.ring-text span { font-size: .78rem; color: var(--gedaempft); }

/* ---------------------------------------------------------------------- Balken */

.balkenliste { list-style: none; margin: 1.3rem 0 0; padding: 0; display: grid; gap: .75rem; }
.balkenliste li { display: grid; grid-template-columns: 1fr auto; gap: .15rem .6rem; }
.balken-name {
  font-size: .82rem; color: var(--text); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.balken-wert {
  font-size: .76rem; color: var(--gedaempft); text-align: right;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.balken {
  grid-column: 1 / -1; height: 6px; border-radius: 3px;
  background: var(--karte-innen); overflow: hidden; display: block;
}
.balken i { display: block; height: 100%; border-radius: 3px; background: var(--akzent); }
.balken i.ueberzogen { background: var(--schlecht); }

/* -------------------------------------------------------------------- Zeilen */

.zeilen { list-style: none; margin: .7rem 0 0; padding: 0; display: grid; gap: .5rem; }
.zeilen li { display: flex; justify-content: space-between; gap: 1rem; font-size: .88rem; }
.zeilen span { color: var(--gedaempft); }
.zeilen b { font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; }
.quelle.art { color: var(--akzent); }
.zeilen li.summe { border-top: 1px solid var(--linie); padding-top: .5rem; margin-top: .15rem; }
.zeilen li.summe span { color: var(--text); font-weight: 600; }
.gut { color: var(--gut); }
.schlecht { color: var(--schlecht); }

/* Antippen statt Hover - auf dem Handy gibt es kein Mouseover. */
.warum { margin-top: 1rem; border-top: 1px solid var(--linie); padding-top: .2rem; }
.warum summary {
  list-style: none; cursor: pointer; padding: .65rem 0 .2rem;
  color: var(--akzent); font-size: .85rem; font-weight: 600;
}
.warum summary::-webkit-details-marker { display: none; }
.warum summary::after { content: ' ⌄'; }
.warum[open] summary::after { content: ' ⌃'; }
.warum-inhalt { padding-bottom: .3rem; }
.teil-titel {
  margin: 1.1rem 0 .1rem; font-size: .72rem; color: var(--gedaempft);
  text-transform: uppercase; letter-spacing: .08em; font-weight: 600;
}
.erklaerung { margin: .8rem 0 0; font-size: .82rem; color: var(--gedaempft); line-height: 1.5; }
.erklaerung.warnung { color: var(--schlecht); }

.hinweis-kachel { display: flex; align-items: center; justify-content: space-between; }
.hinweis-zahl { margin: .2rem 0 0; font-size: 1.3rem; font-weight: 700; }
.pfeil-rund {
  width: 2.1rem; height: 2.1rem; border-radius: 50%; background: var(--akzent-schwach);
  color: var(--akzent); display: grid; place-items: center; font-size: 1rem; flex: none;
}

/* ------------------------------------------------------------------- Listen */

.chips { display: flex; gap: .4rem; margin: .2rem 0 .7rem; overflow-x: auto; }
.chip {
  padding: .45rem .85rem; border-radius: 999px; white-space: nowrap; cursor: pointer;
  border: 1px solid var(--linie); background: var(--karte);
  color: var(--gedaempft); font-size: .82rem; font-weight: 500;
}
.chip.aktiv { background: var(--akzent-schwach); color: var(--akzent); border-color: var(--akzent); }

.liste { background: var(--karte); border-radius: var(--radius); overflow: hidden; }
.buchung, .reihe {
  display: flex; justify-content: space-between; align-items: center; gap: .8rem;
  padding: .75rem .9rem; border-bottom: 1px solid var(--linie); cursor: pointer;
}
.buchung:last-child, .reihe:last-child { border-bottom: 0; }
.buchung:active, .reihe:active { background: var(--karte-innen); }
.wer { min-width: 0; flex: 1; }
.name {
  font-weight: 550; font-size: .9rem; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.meta { color: var(--gedaempft); font-size: .75rem; margin-top: .15rem; }
.meta em { font-style: normal; color: var(--schlecht); }
.betrag {
  font-weight: 650; font-variant-numeric: tabular-nums;
  white-space: nowrap; font-size: .92rem;
}
.leer { color: var(--gedaempft); font-size: .86rem; padding: 1.6rem; text-align: center; }
.leer.fehler { color: var(--schlecht); }

table { width: 100%; border-collapse: collapse; margin-top: .6rem; }
th, td {
  padding: .5rem .35rem; text-align: right; font-size: .84rem;
  border-bottom: 1px solid var(--linie); font-variant-numeric: tabular-nums;
}
th:first-child, td:first-child { text-align: left; font-variant-numeric: normal; }
th { color: var(--gedaempft); font-weight: 500; font-size: .7rem;
     text-transform: uppercase; letter-spacing: .05em; }
tr:last-child td { border-bottom: 0; }

/* ------------------------------------------------------------------ Bedienung */

.feld {
  width: 100%; padding: .7rem .8rem; border-radius: var(--radius-klein);
  font-size: 1rem; border: 1px solid var(--linie); background: var(--karte-innen);
  color: var(--text); font-family: inherit; margin-bottom: .5rem;
}
.feld:focus { outline: 0; border-color: var(--akzent); }
.feld:disabled { opacity: .4; }
select.feld { appearance: none; }

.primaer, .sekundaer {
  padding: .75rem 1rem; border-radius: var(--radius-klein); cursor: pointer;
  font-size: .92rem; font-weight: 600; font-family: inherit; border: 1px solid var(--linie);
}
.primaer { background: var(--akzent); color: #05221a; border-color: var(--akzent); }
.sekundaer { background: var(--karte-innen); color: var(--text); }
.breit { width: 100%; margin-top: .9rem; }
.mini {
  background: none; border: 0; color: var(--gedaempft); font-size: .78rem;
  cursor: pointer; padding: .35rem .5rem; border-radius: 8px; flex: none; font-family: inherit;
}
.mini:active { background: var(--karte-innen); }
.mini.plus { color: var(--akzent); font-weight: 600; }

.formfeld { display: block; margin-bottom: .3rem; }
.formfeld > span {
  display: block; font-size: .76rem; color: var(--gedaempft);
  margin-bottom: .25rem; font-weight: 500;
}
.regel-option {
  display: flex; gap: .55rem; align-items: center;
  font-size: .85rem; color: var(--gedaempft); margin: .3rem 0 .6rem;
}
.regel-option input { width: 1.05rem; height: 1.05rem; accent-color: var(--akzent); }
.hinweis-klein { margin: 0 0 .8rem; font-size: .76rem; color: var(--gedaempft); min-height: 1.1em; }

/* --------------------------------------------------------------------- Dialoge */

dialog {
  border: 0; padding: 1.1rem 1.1rem calc(1.1rem + env(safe-area-inset-bottom));
  border-radius: var(--radius) var(--radius) 0 0;
  background: var(--karte); color: var(--text);
  width: 100%; max-width: 44rem; margin: auto auto 0;
  position: fixed; inset: auto 0 0 0; max-height: 88vh; overflow-y: auto;
}
dialog::backdrop { background: rgba(0, 0, 0, .6); }
.dialog-titel { margin: 0 0 .15rem; font-weight: 700; font-size: 1.05rem; }
.dialog-buchung { margin: 0 0 .9rem; color: var(--gedaempft); font-size: .83rem; }
.dialog-knoepfe { display: flex; gap: .5rem; margin-top: .8rem; }
.dialog-knoepfe button { flex: 1; }
/* Name und Haken in EINER Zeile (Frank, 05.09.2026). Das Feld nimmt, was
   uebrig ist, der Haken nur, was er braucht. Wird es eng, rutscht der Haken
   unter das Feld - nebeneinander waeren beide unlesbar schmal. */
.namenszeile {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: .6rem; margin-bottom: .9rem;
}
.namenszeile .feld { margin: 0; }
/* Kleiner als die uebrigen Hakenzeilen: hier steht sie nicht allein unter
   einem Feld, sondern als drittes Element in einer engen Zeile. */
.namenszeile .regel-option {
  margin: 0; white-space: nowrap; font-size: .76rem; gap: .35rem;
}
.namenszeile .regel-option input { width: .95rem; height: .95rem; }
@media (max-width: 560px) {
  /* Schmal: Feld ueber die ganze Breite, der Haken darunter. */
  .namenszeile { grid-template-columns: 1fr; gap: .35rem; }
  .namenszeile .regel-option { white-space: normal; }
}

.katliste {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  /* Drei Reihen hoch, darin wird gescrollt (Frank, 05.09.2026: "mach den
     Kat block kleiner... 3 zeilen hoch ... darin kann man ja scollen").
     42vh waren auf einem hohen Schirm fast der halbe Dialog - die Suche
     darueber und die Knoepfe darunter rutschten damit aus dem Bild.
     Gerechnet: eine Reihe ist rund 2,5 rem hoch, dazu zwei Abstaende. */
  gap: .45rem; max-height: 8.4rem; overflow-y: auto; margin-bottom: .8rem;
}
.katliste button {
  padding: .65rem .55rem; border-radius: var(--radius-klein); cursor: pointer;
  border: 1px solid var(--linie); background: var(--karte-innen); color: var(--text);
  font-size: .84rem; text-align: left; font-family: inherit;
}
.katliste button:active { border-color: var(--akzent); background: var(--akzent-schwach); }

/* -------------------------------------------------------------------- Tableiste */

.tableiste {
  position: fixed; inset: auto 0 0 0; z-index: 30;
  display: flex; justify-content: space-around;
  padding: .5rem .4rem calc(.5rem + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--karte) 94%, transparent);
  backdrop-filter: blur(14px); border-top: 1px solid var(--linie);
}
.tableiste a {
  flex: 1; display: grid; justify-items: center; gap: .15rem; position: relative;
  color: var(--gedaempft); font-size: .68rem; padding: .25rem 0; border-radius: 10px;
}
.tableiste a.aktiv { color: var(--akzent); }
.tableiste .sym { font-size: 1.15rem; line-height: 1; }
.blase {
  position: absolute; top: -.1rem; right: 22%; min-width: 1.05rem; height: 1.05rem;
  padding: 0 .25rem; border-radius: 999px; background: var(--schlecht); color: #fff;
  font-size: .62rem; font-weight: 700; display: grid; place-items: center;
}

.toast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(5.2rem + env(safe-area-inset-bottom)); z-index: 40;
  background: var(--text); color: var(--bg); padding: .65rem 1rem;
  border-radius: 999px; font-size: .85rem; font-weight: 550;
  max-width: 90vw; text-align: center;
}
.toast.fehler { background: var(--schlecht); color: #fff; }

/* ----------------------------------------------- Erfassen und Datei einlesen */

.schwebeknopf {
  position: fixed; right: 1rem; bottom: calc(5.4rem + env(safe-area-inset-bottom));
  z-index: 25; width: 3.4rem; height: 3.4rem; border-radius: 50%; border: 0;
  background: var(--akzent); color: #05221a; font-size: 1.9rem; line-height: 1;
  cursor: pointer; box-shadow: 0 6px 20px rgba(0, 0, 0, .35);
}
.schwebeknopf:active { transform: scale(.94); }

/* ----------------------------------------------------------------- Melden

   Bewusst leiser als das Plus: gleiche Stelle, halbe Größe, keine Farbe.
   Er soll erreichbar sein, ohne um Aufmerksamkeit zu bitten - beim Testen
   sucht man ihn, im Alltag soll er nicht stören. */

.meldeknopf {
  position: fixed; left: 1rem; bottom: calc(5.6rem + env(safe-area-inset-bottom));
  z-index: 25; width: 2.6rem; height: 2.6rem; border-radius: 50%;
  border: 1px solid var(--linie); background: var(--karte); color: var(--gedaempft);
  font-size: 1.05rem; line-height: 1; cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .28);
  transition: transform .16s ease, color .16s ease;
}
.meldeknopf:active { transform: scale(.9); color: var(--akzent); }

/* Die klebende Kopfleiste jedes Dialogs.

   Ohne eigene Hoehe: sie schiebt nichts weg. Der Dialog ist sein eigenes
   Scrollfeld, deshalb bleibt sie beim Scrollen stehen (c05e872a). Ihr oberer
   Rand liegt dort, wo der Inhalt anfaengt - also 1.1rem unter der Dialogkante,
   genau um die Innenabstand. Die Knoepfe darin rechnen mit dieser Verschiebung
   und stehen deshalb mit negativen Werten wieder an ihrem alten Platz. */
.dialog-ecken { display: contents; }

/* In der Ecke jedes Dialogs. Absolut in der Kopfleiste - die klebt, also
   kleben die Knoepfe mit. */
.melde-ecke {
  /* 1,65 = 0,55 + der negative obere Rand der klebenden Kopfleiste (9a7f0d47) */
  position: absolute; top: 1.65rem; right: 2.75rem; z-index: 2;
  width: 1.9rem; height: 1.9rem; border-radius: 50%;
  border: 1px solid var(--linie); background: var(--karte-innen);
  color: var(--gedaempft); font-size: .85rem; line-height: 1; cursor: pointer;
  padding: 0; font-family: inherit;
}
.melde-ecke:active { color: var(--akzent); border-color: var(--akzent); }
/* Der Titel klebt mit. Ein X ueber fremdem Text sagt nicht mehr, was man da
   schliesst - und der Inhalt soll unter einer Kante weglaufen, nicht gegen die
   Knoepfe stossen. Der negative obere Rand und der gleich grosse Innenabstand
   heben sich auf: die Schrift steht, wo sie stand, aber der Hintergrund reicht
   bis an die Dialogkante. Rechts bleibt Platz fuer die beiden Knoepfe. */
dialog .dialog-titel {
  position: sticky; top: -1.1rem; z-index: 3;
  margin: -1.1rem -1.1rem .15rem; padding: 1.1rem 4.9rem .45rem 1.1rem;
  background: var(--karte);
}
/* Und dasselbe unten (Rueckmeldung c05e872a, 05.09.2026).

   Am 28.08. wurde die Kopfzeile festgeklebt - Titel, Meldeknopf und X. Der
   Knopf, den Frank wirklich meinte, war aber der andere: "eigentlich war
   unten der schliessen button gemeint". Auf halber Hoehe eines langen
   Dialogs stand er bei 708 px, waehrend der Dialog bei 520 endet - also
   ausserhalb, und man musste erst bis ans Ende scrollen, um zu schliessen.

   Spiegelbildlich zur Kopfzeile aufgebaut: negativer unterer Rand und
   gleich grosser Innenabstand heben sich auf, der Hintergrund reicht bis an
   die Dialogkante, und der Inhalt laeuft darunter weg statt dagegen zu
   stossen. Gemessen danach: 468-520 px, buendig mit der Unterkante.

   Gilt fuer die Knopfreihe UND fuer einen einzelnen breiten Schlussknopf -
   die Dialoge der App nutzen beides. `:last-child` ist Absicht: ein
   Zurueck-Knopf mitten im Dialog (etwa #gpname-zurueck) soll mitscrollen. */
dialog > .dialog-knoepfe,
dialog > button.sekundaer.breit:last-child {
  position: sticky; bottom: -1.1rem; z-index: 3;
  margin: .8rem -1.1rem -1.1rem; padding: .8rem 1.1rem 1.1rem;
  background: var(--karte);
}

/* Das X rechts aussen, der Meldeknopf daneben. Ein Dialog ohne sichtbaren
   Ausweg ist auf dem Handy eine Sackgasse - dort gibt es keine Esc-Taste. */
.zu-ecke {
  /* 1,65 = 0,55 + der negative obere Rand der klebenden Kopfleiste (9a7f0d47) */
  position: absolute; top: 1.65rem; right: .6rem; z-index: 2;
  width: 1.9rem; height: 1.9rem; border-radius: 50%;
  border: 1px solid var(--linie); background: var(--karte-innen);
  color: var(--gedaempft); font-size: 1.15rem; line-height: 1; cursor: pointer;
  padding: 0; font-family: inherit;
}
.zu-ecke:active { color: var(--akzent); border-color: var(--akzent); }

/* Vier große Flächen statt vier Chips: ein Tipp ist hier die ganze Meldung,
   und der soll auch im Gehen sitzen. */
.melde-sorten {
  display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin: .4rem 0 .8rem;
}
.melde-sorte {
  padding: .95rem .6rem; border-radius: var(--radius-klein);
  border: 1px solid var(--linie); background: var(--karte-innen); color: var(--text);
  font-family: inherit; font-size: .95rem; font-weight: 600; cursor: pointer;
  transition: transform .14s ease, border-color .14s ease;
}
.melde-sorte:active { transform: scale(.97); }
.melde-sorte.aktiv {
  border-color: var(--akzent); background: var(--akzent-schwach); color: var(--akzent);
}
.melde-sorte:disabled { opacity: .45; }
/* Die fünfte Sorte steht allein in der letzten Reihe - dann lieber über die
   ganze Breite als halb angeschnitten daneben. */
.melde-sorte:nth-child(5):last-child { grid-column: 1 / -1; letter-spacing: .06em; }

#melden textarea { width: 100%; }
.melde-kontext {
  margin: 0; white-space: pre-wrap; word-break: break-word;
  font-size: .7rem; line-height: 1.45; color: var(--gedaempft);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  max-height: 14rem; overflow-y: auto;
}

/* ------------------------------------------------- Meldestand und Einstufung

   Fünf Zahlen und ein Balken. Der Balken zeigt denselben Stand noch einmal
   als Fläche: an "12 von 31" sieht man nicht auf einen Blick, ob man
   vorankommt, an einem zu einem Drittel gefüllten Streifen schon. */

.meldestand {
  display: grid; grid-template-columns: repeat(6, 1fr); gap: .3rem;
  margin: .6rem 0 .4rem; text-align: center;
}
/* Sechs Zustaende gehen auf einem Telefon nicht nebeneinander. Zwei volle
   Dreierreihen statt fuenf und einem Waisenkind darunter. */
@media (max-width: 30rem) { .meldestand { grid-template-columns: repeat(3, 1fr); } }
.ms-davon {
  margin: 0 0 .4rem; text-align: center; font-size: .62rem;
  color: var(--gedaempft); text-transform: uppercase; letter-spacing: .04em;
}
.ms-davon b { font-variant-numeric: tabular-nums; }

/* Die Kennung einer Meldung. Steht in der Kopfzeile hinter der Fassung, sieht
   aus wie Beiwerk und ist doch das Einzige, womit sich eine bestimmte Meldung
   ansprechen laesst. Monospace, damit acht Zeichen abtippbar bleiben. */
.melde-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .92em; letter-spacing: .02em; line-height: inherit;
  background: var(--karte-innen); color: var(--gedaempft);
  border: 0; border-radius: .25rem; padding: 0 .25rem; cursor: pointer;
  vertical-align: baseline;
}
.melde-id:hover, .melde-id:focus-visible { color: var(--akzent); }

/* Die Klammer: ein Bild haengt dran. Gross genug zum Treffen, ohne die
   Kopfzeile auseinanderzuziehen. */
.melde-klammer {
  font-size: 1em; line-height: inherit; vertical-align: baseline;
  background: none; border: 0; padding: 0 .15rem; cursor: pointer;
}
.melde-klammer:hover, .melde-klammer:focus-visible { filter: brightness(1.3); }
/* Die Zahlen fuehren zur jeweiligen Gruppe. Als <button>, damit Tastatur und
   Vorlesen das auch wissen - aber ohne dass man ihnen einen Knopf ansieht.
   "aktiv" heisst hier: diese Gruppe steht gerade aufgeklappt. */
button.ms-zahl {
  background: none; border: 0; padding: .15rem 0; margin: 0;
  font: inherit; color: inherit; text-align: center; cursor: pointer;
  border-radius: .3rem;
}
button.ms-zahl:hover,
button.ms-zahl:focus-visible { background: var(--karte-innen); }
button.ms-zahl.aktiv { background: var(--karte-innen); }

.ms-zahl b {
  display: block; font-size: 1.15rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.ms-zahl span {
  display: block; font-size: .6rem; color: var(--gedaempft);
  text-transform: uppercase; letter-spacing: .04em;
}
.ms-balken {
  display: flex; height: 6px; border-radius: 3px; overflow: hidden;
  background: var(--karte-innen); margin-bottom: .2rem;
}
.ms-balken i,
.ms-balken button { display: block; height: 100%; border: 0; padding: 0; }
.ms-balken button { cursor: pointer; }
/* Die Reihenfolge im Balken ist die des Ablaufs: was noch zu tun ist steht
   links, das Abgehakte rechts. So waechst die gruene Flaeche nach rechts. */
.ms-offen     { background: var(--schlecht); }
.ms-ki        { background: var(--ki); }
.ms-warten    { background: var(--warten); }
.ms-erledigt  { background: var(--akzent); }
.ms-verworfen { background: var(--gedaempft); opacity: .5; }
/* Zusammengefuehrtes ganz rechts und am blassesten: es ist keine Arbeit
   mehr und auch keine Entscheidung, sondern nur noch eine Fundstelle. */
.ms-zusammen  { background: var(--gedaempft); opacity: .3; }

/* Die Einstufung an der einzelnen Meldung. Verworfenes bleibt lesbar, tritt
   aber zurück - gelöscht ist es ausdrücklich nicht. */
.mini.stufe { text-transform: none; }
.mini.stufe.aktiv {
  background: var(--akzent-schwach); color: var(--akzent);
  border-color: var(--akzent);
}
.anfrage.prio-wichtig  { border-left: 3px solid var(--schlecht); padding-left: .65rem; }
/* Drei Stufen, drei Gewichte: wichtig traegt einen roten Rand, normal bleibt
   wie es ist, unwichtig tritt zurueck - aber deutlich weniger als
   verworfenes, das ja gar nicht mehr gebaut wird. */
.anfrage.prio-unwichtig {
  border-left: 3px solid var(--unwichtig); padding-left: .65rem;
}
.anfrage.ablage-verworfen { opacity: .45; }

/* Die Fassung an einer Meldung. Grün heisst: derselbe Stand, der gerade
   läuft - dann ist eine wiederkehrende Meldung eine, die nicht behoben ist.
   Grau mit ⟲ heisst: der Melder hatte einen älteren Stand vor sich. */
.fassung {
  display: inline-block; padding: 0 .35rem; border-radius: 999px;
  font-size: .64rem; font-weight: 700; font-variant-numeric: tabular-nums;
  background: var(--karte-innen); color: var(--gedaempft);
  border: 1px solid var(--linie);
}
.fassung.jetzt { color: var(--akzent); border-color: var(--akzent); }

/* ------------------------------------------------------------- Änderungen */

/* Ein Tag ist eine Version: eine Kachel je Tag, die Änderungen darin
   gesammelt. Lose aneinandergereihte Commits sehen nach Baustelle aus. */
.cl-versionkopf {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: .8rem;
}
.cl-versionnummer {
  margin: 0; font-size: 1.05rem; font-weight: 700; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.cl-versiondatum { margin: .1rem 0 0; font-size: .74rem; color: var(--gedaempft); }
.cl-versionmeta {
  margin: .45rem 0 0; font-size: .72rem; color: var(--gedaempft);
  padding-bottom: .55rem; border-bottom: 1px solid var(--linie);
}
.cl-version + .cl-version { margin-top: .7rem; }

/* Die Änderungen, zweistufig gegliedert - Rückmeldung c5e718a6.

   Aussen wie innen derselbe Kopf, nur mit anderem Gewicht: das Datum trägt
   die fette Zeile, die Sorte die normale. Beide klappen. */
.cl-block > summary { list-style: none; cursor: pointer; }
.cl-block > summary::-webkit-details-marker { display: none; }
.cl-blockkopf {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  padding: .3rem 0;
}
.cl-blockkopf::after { content: '⌄'; color: var(--gedaempft); font-size: .95rem; }
.cl-block[open] > .cl-blockkopf::after { content: '⌃'; }
.cl-blocktitel { font-size: .88rem; font-weight: 600; }
/* Das Datum ist der Anker, an den man sich erinnert ("was kam am 21."). */
.cl-blocktitel.fett {
  font-size: 1.05rem; font-weight: 700; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
/* Schiebt alles Weitere nach rechts - Knopf und Pfeil stehen zusammen. */
.cl-anzahl {
  margin-right: auto; font-style: normal; font-size: .68rem;
  color: var(--gedaempft); background: var(--karte-innen);
  border-radius: 999px; padding: .05rem .4rem;
  font-variant-numeric: tabular-nums;
}
.cl-innen {
  margin-top: .45rem; padding-top: .1rem; border-top: 1px solid var(--linie);
}
/* Die Kennung steht in der Titelzeile statt auf einer eigenen darunter - das
   spart je Eintrag eine Zeile. Sie tritt dabei zurück: sie ist ein Beleg,
   keine Überschrift. */
.cl-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .72rem; font-weight: 400; color: var(--gedaempft);
}
/* Für den Nutzer ist der Titel der ganze Eintrag - und dann braucht er kein
   Fettdruck, um sich abzuheben. Fett bleibt dem Datum vorbehalten. */
.cl-titel.schlicht { font-weight: 400; }
/* Der gepflegte Nutzertext, in der Freigabeliste unter dem Commit-Titel.
   Grün wie alles, was schon draußen ankommt. */
.cl-nutzertext {
  margin-top: .2rem; font-size: .8rem; color: var(--akzent); line-height: 1.35;
}
.cl-nutzertext::before { content: '→ '; }
.cl-ordnung { margin: .2rem 0 .6rem; }
/* Die Nutzeransicht muss sich vom Freigabeteil absetzen, sonst hakt man
   irgendwann in einer Ansicht herum, die gar keine Haken hat. */
.cl-vorschaukachel.an {
  border: 1px solid var(--akzent);
  background: color-mix(in srgb, var(--akzent) 7%, var(--karte));
}
.cl-vorschaukachel.an .label { color: var(--akzent); }

/* Eine schlichte Aufzählung statt gerahmter Kästen. Zwanzig Kästen mit je
   Rahmen, Polster und eigenem Hintergrund kosten zusammen einen halben
   Schirm, und getragen haben sie nichts: eine Liste ist eine Liste.
   Der Punkt übernimmt, was vorher der linke Rand sagte. */
.cl-liste { display: grid; gap: .1rem; margin: .35rem 0 0; padding: 0; list-style: none; }
.cl-eintrag { position: relative; padding: .2rem 0 .2rem .95rem; }
.cl-eintrag::before {
  content: '•'; position: absolute; left: .15rem; top: .18rem;
  color: var(--gedaempft);
}
/* Freigegeben heisst sichtbar fuer alle - das soll man auf einen Blick sehen,
   ohne jeden Haken einzeln zu lesen. */
.cl-eintrag.frei::before { color: var(--akzent); }
.cl-kopf { display: flex; align-items: flex-start; gap: .8rem; }
.cl-wer { flex: 1; min-width: 0; }
.cl-titel { font-size: .9rem; font-weight: 600; line-height: 1.35; }
.cl-meta {
  margin-top: .15rem; font-size: .72rem; color: var(--gedaempft);
  font-variant-numeric: tabular-nums;
}
.cl-haken {
  display: flex; align-items: center; gap: .35rem; flex-shrink: 0;
  font-size: .68rem; color: var(--gedaempft); max-width: 6.5rem;
  line-height: 1.2; cursor: pointer;
}
.cl-haken input { width: 1.1rem; height: 1.1rem; accent-color: var(--akzent); }
.cl-eintrag .warum { margin-top: .5rem; }
.meta.warnung { color: var(--schlecht); }

.marke {
  display: inline-block; margin-left: .4rem; padding: .05rem .4rem;
  border-radius: 999px; background: var(--akzent-schwach); color: var(--akzent);
  font-size: .64rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; vertical-align: middle;
}

.dateiwahl {
  display: block; margin-top: .7rem; padding: 1.1rem; text-align: center;
  border: 1.5px dashed var(--linie); border-radius: var(--radius-klein);
  color: var(--akzent); font-size: .9rem; font-weight: 600; cursor: pointer;
}
.dateiwahl:active { background: var(--karte-innen); }
.dateiwahl.laeuft { color: var(--gedaempft); border-style: solid; }

/* Kategorie-Auswahl: Suche, Zaehler, Neuanlage direkt aus dem Suchtext */
.katliste button { position: relative; display: flex; justify-content: space-between;
  align-items: center; gap: .4rem; }
.kat-zahl { color: var(--gedaempft); font-size: .7rem; font-variant-numeric: tabular-nums; }
.kat-neu {
  grid-column: 1 / -1; background: var(--akzent-schwach) !important;
  border-color: var(--akzent) !important; color: var(--akzent) !important;
  font-weight: 650; justify-content: center !important;
}

.gross-feld { font-size: 1.35rem; font-weight: 650; text-align: center;
  font-variant-numeric: tabular-nums; padding: .85rem; }

.toast-aktion {
  margin-left: .7rem; padding: .25rem .7rem; border-radius: 999px;
  border: 0; background: var(--akzent); color: #05221a;
  font-size: .8rem; font-weight: 700; cursor: pointer; font-family: inherit;
}

/* Erkannte Vertraege zur Auswahl */
.vorschlaege { display: grid; gap: .35rem; margin-top: .5rem; }
.vorschlag {
  display: flex; align-items: center; gap: .65rem; padding: .6rem .7rem;
  border: 1px solid var(--linie); border-radius: var(--radius-klein);
  background: var(--karte-innen); cursor: pointer;
}
.vorschlag input { width: 1.15rem; height: 1.15rem; accent-color: var(--akzent); flex: none; }
.vorschlag .wer { display: grid; min-width: 0; }
.vorschlag.niedrig { opacity: .6; }
.siegel {
  font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: .12rem .45rem; border-radius: 999px; flex: none;
  background: var(--linie); color: var(--gedaempft);
}
.siegel.hoch { background: var(--akzent-schwach); color: var(--akzent); }

.balken-zeile { display: grid; grid-template-columns: 1fr auto; gap: .15rem .6rem; }
.balken-zeile:active { opacity: .6; }
.quelle { font-style: normal; font-size: .64rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--gedaempft); margin-left: .3rem; }
.legende { margin-top: 1rem; }

.dialog-text { margin: 0 0 1rem; color: var(--gedaempft); font-size: .88rem; line-height: 1.5; }
.vorschlag { display: grid; gap: .4rem; }
.vorschlag-kopf { display: flex; align-items: center; gap: .55rem; }
.vorschlag-fuss { display: grid; gap: .3rem; padding-left: 1.7rem; }
.feld.schmal { margin: 0; padding: .45rem .55rem; font-size: .85rem; }
.vorschlag-kopf .feld.schmal { flex: 1; min-width: 0; }

.warnzeile { color: var(--text); background: var(--akzent-schwach);
  padding: .55rem .7rem; border-radius: var(--radius-klein); margin-top: .1rem; }


/* --------------------------------------------------------- Schnellerfassung */

.betrag-eingabe {
  display: flex; align-items: center; gap: .5rem; margin: .3rem 0 .8rem;
  background: var(--karte-innen); border: 1px solid var(--linie);
  border-radius: var(--radius-klein); padding: .5rem .7rem;
}
.betrag-eingabe input {
  flex: 1; min-width: 0; border: 0; background: none; color: var(--text);
  font-size: 2rem; font-weight: 700; font-family: inherit; text-align: right;
  font-variant-numeric: tabular-nums; padding: 0;
}
.betrag-eingabe input:focus { outline: 0; }
.vorzeichen {
  width: 2.4rem; height: 2.4rem; border-radius: 50%; border: 0; flex: none;
  background: var(--schlecht); color: #fff; font-size: 1.4rem; font-weight: 700;
  cursor: pointer; font-family: inherit;
}
.vorzeichen.plus { background: var(--gut); color: #05221a; }
.waehrung { font-size: 1.4rem; font-weight: 600; color: var(--gedaempft); flex: none; }
.datumchip { width: 8.5rem; padding: .4rem .6rem; font-family: inherit; }

/* Kopf: Ruecksprung in den laufenden Monat */
.kopfmitte { background: none; border: 0; color: inherit; font: inherit;
  cursor: pointer; padding: 0; }
.heute-marke { display: block; font-size: .68rem; color: var(--akzent);
  font-weight: 600; margin-top: .1rem; }

/* ------------------------------------------------------------- Platzhalter */

.sk {
  display: block; border-radius: 6px; background: var(--karte-innen);
  position: relative; overflow: hidden;
}
.sk::after {
  content: ''; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent,
    color-mix(in srgb, var(--text) 7%, transparent), transparent);
  animation: wandern 1.4s infinite;
}
@keyframes wandern { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .sk::after { animation: none; } }

.sk-zahl   { height: 1.2rem; width: 4.2rem; margin: 0 auto .35rem; }
.sk-klein  { height: .7rem;  width: 5rem;   margin: .2rem 0; }
.sk-text   { height: .9rem;  width: 60%; }
.sk-wert   { height: .9rem;  width: 3.5rem; margin-left: auto; }
.sk-label  { height: .7rem;  width: 6rem; margin-bottom: .8rem; }
.sk-ring   { height: 9.5rem; width: 9.5rem; border-radius: 50%; }
.sk-balken { height: 6px; width: 55%; border-radius: 3px; }
.sk-chip   { height: 2rem; width: 6.5rem; border-radius: 999px; }
.sk-feld   { height: 2.7rem; width: 100%; border-radius: var(--radius-klein); margin-bottom: .7rem; }
.sk-knopf  { height: 2.8rem; width: 100%; border-radius: var(--radius-klein); margin-top: .6rem; }
.balkenliste .sk-text { margin-bottom: .3rem; }


/* Ampel: gruen solange Luft ist, orange kurz vor der Grenze, rot erst darueber.
   Ein Balken, auf dem zweimal dieselbe Zahl steht, darf nie rot sein. */
:root { --knapp: #f0a53a; }
@media (prefers-color-scheme: light) { :root { --knapp: #b8730a; } }
.balken i.knapp { background: var(--knapp); }
.balken-wert.knapp { color: var(--knapp); }
.balken-wert.ueberzogen { color: var(--schlecht); }


.fehlerzeile .name { white-space: normal; color: var(--schlecht); font-size: .85rem; }
.fehler-details { margin-top: .35rem; }
.fehler-details summary { font-size: .72rem; color: var(--gedaempft); cursor: pointer; }
.fehler-details pre {
  margin: .35rem 0 0; padding: .5rem; background: var(--bg); border-radius: 8px;
  font-size: .68rem; overflow-x: auto; white-space: pre-wrap; word-break: break-word;
  color: var(--gedaempft); max-height: 12rem;
}


/* Plan/Ist: Spalte fuer das Uebernehmen der Abweichung */
th.tat, td.tat { width: 2.2rem; padding-left: 0; padding-right: 0; text-align: center; }
.mini.uebernehmen {
  font-size: 1.05rem; line-height: 1; padding: .25rem .4rem;
  color: var(--akzent); font-weight: 700;
}
.mini.uebernehmen:active { background: var(--akzent-schwach); }
#alle-uebernehmen { margin-top: .8rem; }


/* Kategorienamen sind ueberall ein Weg zur Kategorie, nicht nur Text. */
.kat-link { color: var(--text); border-bottom: 1px dotted var(--linie); }
.kat-link:active { color: var(--akzent); border-bottom-color: var(--akzent); }
.zeilen .kat-link { color: var(--gedaempft); }


/* Jahresraster: zwoelf Monate zum direkten Aendern */
.monatsraster {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; margin-top: .5rem;
}
.monatsfeld {
  display: grid; gap: .1rem; background: var(--karte-innen);
  border: 1px solid var(--linie); border-radius: var(--radius-klein); padding: .4rem .3rem;
}
.monatsfeld.aktuell { border-color: var(--akzent); }
.monatsfeld > span {
  font-size: .62rem; color: var(--gedaempft); text-align: center; font-weight: 600;
}
.monatsfeld input {
  border: 0; background: none; color: var(--text); font-family: inherit;
  font-size: .82rem; font-weight: 600; text-align: center; width: 100%;
  font-variant-numeric: tabular-nums; padding: 0;
}
.monatsfeld input:focus { outline: 0; color: var(--akzent); }
.zeilen .erledigt { color: var(--gedaempft); text-decoration: line-through; }


/* Herkunft direkt unter dem Summenposten - eingerueckt und leiser */
.kernzahlen { margin-top: 1.2rem; padding-top: 1rem; border-top: 1px solid var(--linie); }
.zeilen li.unterposten {
  font-size: .78rem; padding-left: .9rem; margin-top: -.15rem;
  border-left: 2px solid var(--linie); margin-left: .2rem;
}
.zeilen li.unterposten span, .zeilen li.unterposten b {
  color: var(--gedaempft); font-weight: 500;
}


/* Einrichtungsassistent */
.schritt .schrittnr {
  display: inline-grid; place-items: center; width: 1.3rem; height: 1.3rem;
  border-radius: 50%; background: var(--linie); color: var(--gedaempft);
  font-size: .72rem; font-weight: 700; margin-right: .35rem; vertical-align: middle;
}
.schritt.fertig .schrittnr { background: var(--akzent); color: #05221a; }
.schritt.fertig { opacity: .75; }
.sekundaer.mitte { display: block; text-align: center; }


.unterposten.anklickbar { cursor: pointer; }
.unterposten.anklickbar:active { background: var(--karte-innen); }
.unterposten.anklickbar b { color: var(--akzent); }


/* ==========================================================================
   Gestaltungsdurchgang. Ziel: die ersten Sekunden.
   Was hier passiert - Tiefe statt Flaeche, ruhigere Typografie, ein Ring der
   traegt, und ein Aufbau der sanft erscheint statt zu springen.
   ========================================================================== */

:root {
  --bg: #0b0e13;
  --karte: #141922;
  --karte-innen: #1b212c;
  --linie: #232b38;
  --akzent: #3ff0b8;
  --akzent-tief: #16a37a;
  --akzent-schwach: #122e28;
  --schatten: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
}
@media (prefers-color-scheme: light) {
  :root {
    --bg: #f4f6f9;
    --karte: #ffffff;
    --karte-innen: #f7f9fb;
    --linie: #e6eaf0;
    --akzent: #0f9b74;
    --akzent-tief: #0b7a5b;
    --akzent-schwach: #e2f6ef;
    --schatten: 0 1px 2px rgba(16,24,40,.05), 0 12px 28px -16px rgba(16,24,40,.22);
  }
}

body {
  background:
    radial-gradient(120% 60% at 50% -10%,
      color-mix(in srgb, var(--akzent) 7%, transparent), transparent 60%),
    var(--bg);
  background-attachment: fixed;
  font-feature-settings: 'tnum' 0;
}

/* Wortmarke ueber allem - ohne sie sieht jede App nach Werkzeug aus */
/* Die Zeile darf nie breiter werden als der Schirm.

   Rueckmeldung 1bceeefd, und Franks Frage dazu: "warum wird die kopfzeile
   beim scollen groesser?? wann hab ich das denn gesagt?" - gesagt hat er es
   nie, es war eine Nebenwirkung. Beim Scrollen blenden sich Rueckweg und
   Seitenname ein ("< Einstellungen Haushalt"). Diese Zeile ist Flex OHNE
   Umbruch: die neuen Teile passen auf einem Telefon nicht mehr daneben, also
   bricht nichts um, sondern die Zeile wird laenger als das Fenster - und
   zieht die ganze Seite mit in die Breite. Auf dem Bild war deshalb bis
   hinunter zur Tableiste alles rechts abgeschnitten.

   Dieselbe Falle wie bei den Listen (siehe .zeilen > li): eine zu breite
   Zeile schiebt alle anderen. Die Teile bekommen darum min-width: 0 und
   duerfen sich kuerzen; der Block rechts behaelt seine Groesse. */
.markenzeile {
  display: flex; align-items: center; gap: .45rem;
  padding: max(env(safe-area-inset-top), .7rem) 1rem .1rem;
  max-width: 44rem; margin: 0 auto; min-width: 0;
}
.markenzeile > * { min-width: 0; }
.marke-name, .marke-zurueck, .marke-seite {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.markenzeile .kopf-rechts, .markenzeile .marke-zeichen { flex: none; }
.marke-zeichen { color: var(--akzent); display: block; }
.marke-name {
  font-size: .84rem; font-weight: 700; letter-spacing: .01em;
  color: var(--text);
}
header { padding-top: .35rem; }

.kachel {
  border: 1px solid var(--linie);
  box-shadow: var(--schatten);
}

/* Der Ring traegt die Seite: groesser, mit Verlauf und weichem Schein */
.ring-kachel {
  background:
    radial-gradient(90% 70% at 50% 0%,
      color-mix(in srgb, var(--akzent) 9%, transparent), transparent 70%),
    var(--karte);
  padding-top: 1.7rem;
}
.ring-mitte { width: 10.6rem; height: 10.6rem; }
.ring circle { stroke-width: 11; }
.ring-wert {
  stroke: url(#ringverlauf);
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--akzent) 45%, transparent));
  transition: stroke-dasharray .7s cubic-bezier(.22,.61,.36,1);
}
.ring-wert.ueberzogen {
  stroke: var(--schlecht);
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--schlecht) 45%, transparent));
}
.ring-text b {
  font-size: 2.05rem; font-weight: 700; letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
}
.ring-text span {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .12em;
  color: var(--gedaempft); font-weight: 600;
}
.ring-seite b { font-size: 1.05rem; letter-spacing: -.02em; }
.ring-seite span {
  font-size: .66rem; text-transform: uppercase; letter-spacing: .08em; font-weight: 600;
}

/* Zahlen ruhiger setzen */
.zahl, .betrag, .zeilen b, .balken-wert, th, td { font-variant-numeric: tabular-nums; }
.zeilen li { align-items: baseline; }

/* Der Aufbau soll erscheinen, nicht springen.

   `backwards` statt `both` (Frank, 04.09.2026: "kommen zwar vorschlaege
   diese sind aber nicht auswaehlbar"). Mit `both` bleibt die Endstellung
   der Animation als Stil stehen - und das ist ein `transform`, auch wenn
   es die Identitaetsmatrix ist. Ein transform macht aus dem Element einen
   eigenen STAPELKONTEXT, dauerhaft. Damit war das `z-index: 15` der
   Vorschlagsliste im .suchfeld-halter eingesperrt: draussen zaehlte nur
   noch der Halter selbst, der steht auf `auto` wie die Auswahlleiste
   darunter, und bei Gleichstand gewinnt das spaetere Element. Die Leiste
   lag also ueber der Liste und fing die Klicks ab.

   `backwards` blendet genauso ein, laesst danach aber nichts stehen: die
   Endwerte (`opacity: 1`, kein transform) sind ohnehin die Vorgabe. Damit
   faellt die Falle fuer JEDEN kuenftigen Aufklapper weg, nicht nur fuer
   diesen einen. */
main > * { animation: auftauchen .32s cubic-bezier(.22,.61,.36,1) backwards; }
main > *:nth-child(2) { animation-delay: .04s; }
main > *:nth-child(3) { animation-delay: .08s; }
main > *:nth-child(4) { animation-delay: .12s; }
@keyframes auftauchen {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  main > * { animation: none; }
  .ring-wert { transition: none; }
}

/* Tableiste: klarer aktiver Zustand */
.tableiste a.aktiv .sym { transform: translateY(-1px); }
.tableiste .sym { transition: transform .18s ease; }
.tableiste a.aktiv::before {
  content: ''; position: absolute; top: -.5rem; width: 1.6rem; height: 2px;
  border-radius: 2px; background: var(--akzent);
}

/* Knoepfe bekommen Gewicht */
.primaer {
  background: linear-gradient(180deg, var(--akzent), var(--akzent-tief));
  color: #04241b; border: 0;
  box-shadow: 0 1px 2px rgba(0,0,0,.25), 0 8px 18px -10px color-mix(in srgb, var(--akzent) 70%, transparent);
}
.schwebeknopf {
  background: linear-gradient(180deg, var(--akzent), var(--akzent-tief));
  color: #04241b;
  box-shadow: 0 2px 6px rgba(0,0,0,.35), 0 14px 28px -12px color-mix(in srgb, var(--akzent) 65%, transparent);
  transition: transform .16s ease;
}
.schwebeknopf:active { transform: scale(.92); }

.balken { height: 7px; border-radius: 4px; }
.balken i {
  border-radius: 4px;
  background: linear-gradient(90deg, var(--akzent-tief), var(--akzent));
  transition: width .5s cubic-bezier(.22,.61,.36,1);
}
.balken i.knapp { background: linear-gradient(90deg, #c9791f, var(--knapp)); }
.balken i.ueberzogen { background: linear-gradient(90deg, #c0392b, var(--schlecht)); }

.label { font-size: .68rem; letter-spacing: .11em; }
header h1 { font-size: 1.22rem; letter-spacing: -.015em; }




/* ==========================================================================
   Das Plus am Ring.
   Gruen auf Gruen verschwindet - der Knopf braucht den Gegenpol. Koralle und
   Bernstein liegen dem Tuerkis des Rings gegenueber, das zieht den Blick
   sofort. Dazu drei Schichten Tiefe: farbiger Schein nach aussen, harter
   Schlagschatten darunter, heller Innenrand oben. Der Halo atmet langsam,
   damit der Knopf lebt, ohne zu zappeln.
   ========================================================================== */

:root {
  --plus-hell: #ffb057;
  --plus-tief: #ff5f5a;
}

.ring-plus {
  position: absolute;
  /* Ring: viewBox 140, Radius 58 -> 41,4 % der Kachel.
     4:30 auf dem Zifferblatt sind 135 Grad, also 41,4 % * cos 45 = 29,3 %. */
  left: 79.3%; top: 79.3%;
  transform: translate(-50%, -50%);
  width: 3rem; height: 3rem; border-radius: 50%;
  border: 0; padding: 0; cursor: pointer;
  display: grid; place-items: center;
  font-family: inherit; font-size: 1.7rem; line-height: 0; font-weight: 400;
  color: #3a1206;
  background:
    radial-gradient(120% 120% at 30% 22%,
      color-mix(in srgb, var(--plus-hell) 92%, white), var(--plus-hell) 38%, var(--plus-tief));
  /* Keine harte Aussparung. Ein weich auslaufender Schein in Kachelfarbe
     loescht den Ring darunter allmaehlich weg - dadurch sitzt der Knopf auf
     dem Ring statt darauf zu kleben. Scharfe Kreisringe sehen immer nach
     Ausschneiden aus. */
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--karte) 88%, transparent),
    0 0 14px 7px var(--karte),
    0 4px 10px -2px rgba(0, 0, 0, .32),
    0 16px 34px -14px color-mix(in srgb, var(--plus-tief) 80%, transparent),
    inset 0 1px 1.5px rgba(255, 255, 255, .6),
    inset 0 -2px 4px -1px color-mix(in srgb, var(--plus-tief) 55%, transparent);
  transition: transform .18s cubic-bezier(.34, 1.56, .64, 1), box-shadow .18s ease;
  z-index: 2;
}

/* Der atmende Halo. Liegt hinter dem Knopf und laeuft langsam auf und ab. */
.ring-plus::after {
  content: '';
  position: absolute; inset: -6px;
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--plus-tief) 45%, transparent), transparent 68%);
  animation: atmen 3.2s ease-in-out infinite;
  pointer-events: none;
  z-index: -1;
}

@keyframes atmen {
  0%, 100% { transform: scale(1);    opacity: .45; }
  50%      { transform: scale(1.28); opacity: .05; }
}

/* Das Zeichen selbst dreht beim Druecken leicht mit - kleine Belohnung. */
.ring-plus > span { display: block; transition: transform .18s ease; }
.ring-plus:active { transform: translate(-50%, -50%) scale(.88); }
.ring-plus:active > span { transform: rotate(90deg); }
.ring-plus:focus-visible {
  outline: 0;
  box-shadow:
    0 0 14px 7px var(--karte),
    0 0 0 3px color-mix(in srgb, var(--akzent) 70%, transparent),
    0 0 16px 2px color-mix(in srgb, var(--akzent) 55%, transparent),
    0 4px 10px -2px rgba(0, 0, 0, .32);
}

@media (prefers-reduced-motion: reduce) {
  .ring-plus::after { animation: none; opacity: .3; }
  .ring-plus, .ring-plus > span { transition: none; }
}

@media (prefers-color-scheme: light) {
  .ring-plus { color: #4a1a08; }
}


/* Der Ring selbst: der Verlauf lief bisher diagonal ueber die Bounding-Box und
   war dadurch kaum zu sehen. Entlang der Bahn gefuehrt traegt er sichtbar. */
.ring-spur { stroke: color-mix(in srgb, var(--linie) 70%, transparent); }
.ring { overflow: visible; }

/* Weicher Schein hinter der ganzen Ringkachel - nimmt der Flaeche die Haerte */
.ring-kachel::before {
  content: '';
  position: absolute; left: 50%; top: 2.2rem;
  width: 12rem; height: 12rem; transform: translateX(-50%);
  border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--akzent) 16%, transparent), transparent 62%);
  filter: blur(14px);
  z-index: 0;
}
.ring-kachel { position: relative; overflow: hidden; }
.ring-kachel > * { position: relative; z-index: 1; }


/* ==========================================================================
   Kopfbereich klebt vollstaendig.
   Der Name darf beim Scrollen nicht verschwinden - er ist das Einzige, was
   die App als Produkt kenntlich macht. Marke und Monatszeile bilden deshalb
   einen gemeinsamen Block, der oben stehen bleibt.
   ========================================================================== */

.kopfbereich {
  position: sticky; top: 0; z-index: 30;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease, box-shadow .2s ease;
}
/* Sobald darunter Inhalt weglaeuft, setzt sich der Kopf sichtbar ab. */
.kopfbereich.geloest {
  border-bottom-color: var(--linie);
  box-shadow: 0 8px 24px -18px rgba(0, 0, 0, .8);
}
.kopfbereich header { position: static; background: none; backdrop-filter: none; }
.markenzeile { padding-bottom: .15rem; }

/* Die Ueberschrift behaelt ihre Groesse.

   Hier wurde sie beim Scrollen von selbst kleiner - eine Bewegung, die
   niemand bestellt hat und die zusammen mit dem Einblenden des Seitennamens
   den Eindruck machte, die Leiste veraendere staendig ihre Groesse. Der
   Kopf klappt beim Scrollen ohnehin ganz weg (max-height: 0 weiter unten);
   dass die Schrift auf dem Weg dorthin auch noch schrumpft, sieht niemand
   ausser als Unruhe. */


/* ==========================================================================
   Kopf schrumpft beim Scrollen.
   Zwei Zeilen kosten oben zu viel Platz. Sobald man scrollt, klappt die
   Monatszeile weg und der Seitentitel wandert in die Markenzeile - der Name
   bleibt, der Rest macht Platz fuer den Inhalt.
   ========================================================================== */

.marke-trenner, .marke-seite {
  opacity: 0; max-width: 0; overflow: hidden; white-space: nowrap;
  transition: opacity .18s ease, max-width .24s ease;
}
.marke-trenner { color: var(--gedaempft); }
.marke-seite { font-size: .84rem; font-weight: 600; color: var(--gedaempft); }

.kopfbereich.geloest .marke-trenner,
.kopfbereich.geloest .marke-seite { opacity: 1; max-width: 12rem; }

.kopfbereich header {
  overflow: hidden;
  transition: max-height .24s ease, opacity .18s ease, padding .24s ease;
  max-height: 4rem; opacity: 1;
}
.kopfbereich.geloest header {
  max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0;
}
.markenzeile { padding-bottom: .5rem; }
.kopfbereich.geloest .markenzeile { padding-bottom: .55rem; }

@media (prefers-reduced-motion: reduce) {
  .marke-trenner, .marke-seite, .kopfbereich header { transition: none; }
}


/* ==========================================================================
   Kennwerte unter dem Ring.
   Die grosse Zahl allein sagt nicht, ob sie reicht. Drei schmale Felder
   beantworten das ohne einen weiteren Blick: verbleibende Tage, Betrag pro
   Tag, naechste Abbuchung.
   ========================================================================== */

.kennwerte {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: .5rem; margin-top: 1.3rem;
}

/* Die Tageszahl als Marke auf der Prognosekachel — derselbe Körper wie das
   Plus am Ring, nur kleiner und ohne Funktion. Sie sitzt bewusst halb über der
   Kante: so gehört sie sichtbar zu dieser Kachel und nimmt ihr trotzdem keinen
   Platz weg, den die Kachel für ihre Zahl braucht.

   Kein Halo. Der atmet am Ring, weil er dort zum Antippen einlädt — hier wäre
   das eine Aufforderung, der nichts folgt. */
.kennwert { position: relative; overflow: visible; }
.tagesmarke {
  position: absolute; bottom: -.6rem; right: -.4rem;
  width: 1.85rem; height: 1.85rem; border-radius: 50%;
  /* .kennwert span setzt margin-top, uppercase, letter-spacing und
     line-height 1.25 — alles davon schiebt die Ziffer aus der Mitte. Hier
     steht deshalb jede dieser Eigenschaften noch einmal ausdrücklich. */
  display: grid; place-items: center; place-content: center;
  margin: 0; padding: 0;
  font-size: .82rem; font-weight: 700; line-height: 1;
  text-transform: none; letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  color: #3a1206;
  background:
    radial-gradient(120% 120% at 30% 22%,
      color-mix(in srgb, var(--plus-hell) 92%, white), var(--plus-hell) 38%, var(--plus-tief));
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--karte) 88%, transparent),
    0 0 10px 5px var(--karte),
    0 3px 8px -2px rgba(0, 0, 0, .32),
    inset 0 1px 1.5px rgba(255, 255, 255, .6),
    inset 0 -2px 4px -1px color-mix(in srgb, var(--plus-tief) 55%, transparent);
  pointer-events: none;
  z-index: 2;
}
@media (prefers-color-scheme: light) { .tagesmarke { color: #4a1a08; } }

/* Nur für Vorlesegeräte. Nicht [hidden] und nicht display:none — beides nähme
   sie auch dem Screenreader weg. */
.nur-vorlesen {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; white-space: nowrap;
  clip-path: inset(50%);
}

/* Der Betrag im Wichtigkeits-Dialog führt eine Ebene tiefer. */
.wi-betrag {
  background: none; border: 0; padding: .2rem 0; color: var(--text);
  font: inherit; font-weight: 650; font-variant-numeric: tabular-nums;
  cursor: pointer; text-align: right;
}
.wi-betrag[disabled] { cursor: default; color: var(--gedaempft); }
.wi-betrag .quelle { color: var(--akzent); font-style: normal; font-size: .7rem; }
.wi-kat > summary { display: flex; align-items: baseline; gap: .5rem; }
/* Verwendungszwecke der HVB sind lang ("VW Leasing GmbH 01.08.2026 RATE08/26
   RE1027") und haben keine Stelle, an der ein Umbruch von selbst passiert.
   Die Zeile stand dadurch 26 px über dem Rand — gemessen, nicht vermutet.

   Der Grund saß eine Ebene höher als gedacht: .zeilen ist ein Grid, und ein
   Grid-Element hat min-width:auto, schrumpft also nicht unter seinen Inhalt.
   min-width am <span> nützt dagegen nichts. Und weil hier das Lesen der Zweck
   ist, bricht der Text um, statt in „…" zu enden wie auf der Übersicht. */
.zeilen li.wi-buchung { min-width: 0; align-items: baseline; gap: .6rem; }
/* Eine Klasse mehr als .zeilen li.unterposten > span, und das ist Absicht:
   bei gleicher Spezifität entscheidet die Reihenfolge in der Datei, und diese
   Regel steht weiter oben als jene. Wer sich hier auf die Reihenfolge verlässt,
   verliert beim nächsten Verschieben — schon zweimal an einem Tag passiert
   (siehe .balkenliste li gegen .planzeile). */
.zeilen li.unterposten.wi-buchung > span {
  min-width: 0; white-space: normal; overflow: visible;
  text-overflow: clip; overflow-wrap: anywhere;
}
.wi-kat > summary > span:first-child { min-width: 0; overflow-wrap: break-word; }
.wi-kat > summary > b { margin-left: auto; font-variant-numeric: tabular-nums; }
.wi-kat > summary > em {
  font-style: normal; font-size: .68rem; color: var(--gedaempft); flex: none;
}
/* Ein Monat ohne Buchungen im Kategoriedialog. Dieselbe Zeile wie ein
   aufklappbarer Monat, aber ohne Pfeil und ohne Zeiger - es gibt nichts
   darunter, und ein Pfeil, der Leeres verspricht, ist ein gebrochenes
   Versprechen. */
.kv-leer {
  display: flex; align-items: baseline; gap: .5rem;
  padding: .65rem 0 .2rem; font-size: .85rem; font-weight: 600;
  color: var(--gedaempft); border-top: 1px solid var(--linie); margin-top: 1rem;
}
.kv-leer > b { margin-left: auto; font-variant-numeric: tabular-nums; }
.kennwert {
  background: color-mix(in srgb, var(--karte-innen) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--linie) 60%, transparent);
  border-radius: var(--radius-klein);
  padding: .55rem .4rem; text-align: center;
}
.kennwert b {
  display: block; font-size: 1.02rem; font-weight: 700;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.kennwert span {
  display: block; margin-top: .1rem; font-size: .62rem; color: var(--gedaempft);
  text-transform: uppercase; letter-spacing: .06em; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Die Überschrift der Kennwert-Kachel (Rückmeldung 25b416ac).

   `.kennwert span` setzt margin-top für die Zeile UNTER der Zahl — als
   erstes Kind schiebt das die Überschrift von der Oberkante weg. Hier steht
   der Abstand deshalb andersherum. `.quelle` bringt ein margin-left mit,
   das es braucht, solange es hinter einem Wort steht; allein in der Zeile
   schiebt es aus der Mitte. */
.kennwert .kennwert-titel { margin-top: 0; margin-bottom: .3rem; }
.kennwert .quelle { display: block; margin-left: 0; margin-top: .25rem; }

/* --------------------------------------- Zweite Ansichten der Auswertung */

/* Das Jahr-mal-Monat-Raster. Dreizehn Spalten passen auf ein Telefon nur,
   wenn sie schmal sein duerfen - deshalb scrollt der Kasten waagerecht statt
   die Seite zu sprengen. */
/* Kein waagerechtes Scrollen mehr: die Spalten duerfen schrumpfen, und die
   Schrift geht mit. Dreizehn Spalten auf einem Telefon sind eng, aber eng ist
   besser als ein Kasten, den man erst schieben muss. */
.bilanzraster { margin: .4rem 0 .8rem; }
.bilanzraster-zeile {
  display: grid; grid-template-columns: 2.2rem repeat(12, minmax(0, 1fr));
  gap: 2px;
}
.bilanzraster-zeile + .bilanzraster-zeile { margin-top: 2px; }
.bilanzraster-zeile.kopf span {
  text-align: center; font-size: clamp(.5rem, 1.4vw, .7rem); color: var(--gedaempft);
  text-transform: uppercase; letter-spacing: .04em; padding: .2rem 0;
}
.bilanzraster-jahr {
  display: flex; align-items: center; font-size: clamp(.58rem, 1.5vw, .78rem);
  font-weight: 600;
  color: var(--gedaempft); font-variant-numeric: tabular-nums;
}
.bilanzzelle {
  border: 0; border-radius: var(--radius-klein); padding: .42rem .1rem;
  font-size: clamp(.5rem, 1.55vw, .72rem);
  font-weight: 600; font-variant-numeric: tabular-nums;
  /* Dunkle Schrift auf gesaettigtem Grund - in beiden Themes lesbar, weil
     die Zellenfarbe selbst der Hintergrund ist und nicht die Seite. */
  color: #1c1c1c; cursor: pointer; text-align: center;
}
.bilanzzelle.leer { background: color-mix(in srgb, var(--linie) 35%, transparent); cursor: default; }

/* Der Ring. Bild und Legende nebeneinander, auf schmalen Schirmen
   untereinander - eine Legende in einer 40-Pixel-Spalte liest niemand. */
/* Der Ring nimmt die ganze Breite - die Namen stehen jetzt im Bild und
   brauchen keine Spalte daneben mehr. */
.katring { margin: .4rem 0 .8rem; }
.ringbild { width: 100%; height: auto; display: block; }
/* Namen stehen jetzt auf dem farbigen Band: dunkle Schrift mit heller
   Kontur, damit sie auf jedem der sechzehn Toene lesbar bleibt. */
.ringname {
  font-size: 14px; font-weight: 500; fill: #14161a;
  paint-order: stroke; stroke: rgba(255,255,255,.5); stroke-width: 2.4px;
}
text.ringname.anklickbar { cursor: pointer; }
text.ringname.anklickbar:hover { text-decoration: underline; }
/* Der Anteil sitzt auf dem farbigen Band - dunkle Schrift, weil die Bandfarbe
   der Hintergrund ist und nicht die Seite. */
/* Die Anteile stehen in der weissen Mitte, also auf dem Kartengrund -
   dort braucht es keine Kontur, aber die Schriftfarbe der Seite. */
.ringprozent.klein { font-size: 11px; }
.ringprozent {
  font-size: 13px; font-weight: 500; fill: var(--gedaempft);
  font-variant-numeric: tabular-nums;
}
/* Duenne Trennlinie zwischen den Stuecken, wie im Vorbild. Sie hat die
   Farbe der Karte, liegt also optisch nicht auf dem Ring, sondern schneidet
   ihn. */
.ringstueck { stroke: var(--karte); stroke-width: 1.5; }

/* Umschalter links, Vorgabehaken unten rechts in der Kachel. */
.ansichtszeile {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; flex-wrap: wrap; margin: .5rem 0 .2rem;
}
.ansicht-vorgabe {
  display: flex; align-items: center; gap: .35rem; margin-left: auto;
  font-size: .72rem; color: var(--gedaempft); cursor: pointer;
}
.ansicht-vorgabe input { margin: 0; }

.kernzahlen { margin-top: 1rem; padding-top: .9rem; }


/* Die Monatssteuerung wandert beim Scrollen in die Markenzeile mit.
   Ein Kopf, der die Bedienung wegnimmt, spart Platz am falschen Ende. */
.markenzeile { position: relative; }
.marke-monat {
  margin-left: auto; display: flex; align-items: center; gap: .1rem;
  opacity: 0; max-width: 0; overflow: hidden;
  transition: opacity .18s ease, max-width .24s ease;
}
.kopfbereich.geloest .marke-monat { opacity: 1; max-width: 10rem; }
.marke-monat[hidden] { display: none; }
.pfeil.klein {
  width: 1.7rem; height: 1.7rem; font-size: 1.05rem; background: none;
}
.pfeil.klein:active { background: var(--linie); }
#monat-klein {
  font-size: .78rem; font-weight: 700; min-width: 3.6rem; text-align: center;
  font-variant-numeric: tabular-nums;
}
.zeitraum { font-size: .7rem; }


.rechtstext {
  margin: 0; white-space: pre-wrap; word-break: break-word;
  font-family: inherit; font-size: .85rem; line-height: 1.65; color: var(--text);
}
.pfeil-rund.klein {
  width: 1.6rem; height: 1.6rem; font-size: .9rem;
  background: none; color: var(--gedaempft);
}


/* ==========================================================================
   Eine Leiste, dauerhaft schmal.
   Die grosse Ueberschrift kostete oben ein Drittel der Hoehe und wiederholte
   nur, was Marke und Reiter ohnehin sagen. Sie ist weg; der Monat und der
   Abrechnungszeitraum stehen dort, wo sie gebraucht werden.
   ========================================================================== */

.kopfbereich header { max-height: 0; opacity: 0; padding: 0; overflow: hidden; }
.markenzeile { padding: max(env(safe-area-inset-top), .6rem) 1rem .55rem; }
.marke-trenner, .marke-seite { opacity: 1; max-width: 12rem; }
.marke-monat { opacity: 1; max-width: 10rem; }
.kopfbereich { border-bottom-color: transparent; box-shadow: none; }
.kopfbereich.abgesetzt {
  border-bottom-color: var(--linie);
  box-shadow: 0 8px 24px -18px rgba(0, 0, 0, .8);
}

/* Der Monat ist zugleich der Weg zurueck ins Jetzt. */
#monat-klein { cursor: pointer; border-radius: 8px; padding: .15rem .3rem; }
#monat-klein.fremd { color: var(--akzent); }
#monat-klein.fremd::after { content: ' ↩'; font-size: .7em; }
#monat-klein:active { background: var(--linie); }

/* Abrechnungszeitraum sitzt im Ring, klein und unaufdringlich. */
.ring-zeitraum {
  display: block; margin-top: .15rem; font-style: normal;
  font-size: .6rem; letter-spacing: .04em; color: var(--gedaempft);
  font-variant-numeric: tabular-nums;
}


/* Die Marke ist der Weg nach Hause - jede App macht das so. */
a.marke-name { cursor: pointer; }
a.marke-name:active { color: var(--akzent); }
.marke-zeichen { flex: none; }


.sekundaer.gefahr { color: var(--schlecht); }
.sekundaer.gefahr:active { background: color-mix(in srgb, var(--schlecht) 12%, transparent); }


/* Hinweis, dass aus der Eingabe ein Vorhaben wird */
.planhinweis {
  margin: .2rem 0 .6rem; padding: .55rem .7rem; border-radius: var(--radius-klein);
  background: var(--akzent-schwach); color: var(--akzent);
  font-size: .78rem; line-height: 1.45;
}


/* Das Logo als kleine Kachel vor dem Namen.
   Bewusst das vollstaendige Symbol statt einer Strichfassung: ein per <img>
   eingebundenes SVG erbt keine Seitenfarben, currentColor bliebe schwarz.
   Mit eigenen Farben im SVG stimmt die Darstellung in jedem Farbschema. */
.marke-zeichen {
  width: 26px; height: 26px; border-radius: 7px; flex: none;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .3),
              0 0 0 1px color-mix(in srgb, var(--linie) 60%, transparent);
}
.marke-name { font-size: .92rem; letter-spacing: -.01em; }


/* Der Loeschknopf steht links aussen, deutlich weg vom Speichern. */
#formular-zusatz { flex: 0 0 auto; padding-left: .9rem; padding-right: .9rem; }
#formular-zusatz[hidden] { display: none; }


/* ==========================================================================
   Farben nachgezogen.
   - Gruen leuchtender, damit es auf hellem Grund nicht absaeuft
   - Gelb warm und golden statt braun
   - Das Schema laesst sich von Hand setzen; ohne Wahl entscheidet das Geraet
   ========================================================================== */

:root {
  --akzent: #3df5bd;
  --akzent-tief: #10b184;
  --gut: #3df5bd;
  --knapp: #ffc233;
}

/* Helles Schema: greift, solange nicht ausdruecklich dunkel gewaehlt wurde */
@media (prefers-color-scheme: light) {
  html:not([data-theme="dark"]) {
    --bg: #f4f6f9;
    --karte: #ffffff;
    --karte-innen: #f7f9fb;
    --text: #131519;
    --gedaempft: #67707e;
    --linie: #e6eaf0;
    --akzent: #0fc38f;
    --akzent-tief: #0a9b71;
    --akzent-schwach: #dcfaf0;
    --gut: #0fc38f;
    --schlecht: #e05545;
    --ki: #2f6fd0;
    --warten: #e8a200;
    --knapp: #e8a200;
    --schatten: 0 1px 2px rgba(16,24,40,.05), 0 12px 28px -16px rgba(16,24,40,.22);
  }
}

/* Ausdrueckliche Wahl schlaegt die Geraeteeinstellung - in beide Richtungen */
html[data-theme="light"] {
  --bg: #f4f6f9;
  --karte: #ffffff;
  --karte-innen: #f7f9fb;
  --text: #131519;
  --gedaempft: #67707e;
  --linie: #e6eaf0;
  --akzent: #0fc38f;
  --akzent-tief: #0a9b71;
  --akzent-schwach: #dcfaf0;
  --gut: #0fc38f;
  --schlecht: #e05545;
  --ki: #2f6fd0;
  --warten: #e8a200;
  --knapp: #e8a200;
  --schatten: 0 1px 2px rgba(16,24,40,.05), 0 12px 28px -16px rgba(16,24,40,.22);
}

html[data-theme="dark"] {
  --bg: #0b0e13;
  --karte: #141922;
  --karte-innen: #1b212c;
  --text: #eceef2;
  --gedaempft: #8b93a1;
  --linie: #232b38;
  --akzent: #3df5bd;
  --akzent-tief: #10b184;
  --akzent-schwach: #123029;
  --gut: #3df5bd;
  --schlecht: #ff6b6b;
  --ki: #6aa8ff;
  --warten: #ffc233;
  --knapp: #ffc233;
  --schatten: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.6);
}

/* Das Logo braucht keinen Kasten mehr, es steht frei */
.marke-zeichen { box-shadow: none; border-radius: 0; width: 28px; height: 28px; }

/* Umschalter */
.schemawahl { display: flex; gap: .35rem; margin-top: .6rem; }
.schemawahl button {
  flex: 1; padding: .55rem .4rem; border-radius: var(--radius-klein);
  border: 1px solid var(--linie); background: var(--karte-innen);
  color: var(--gedaempft); font-family: inherit; font-size: .84rem; cursor: pointer;
}
.schemawahl button.aktiv {
  border-color: var(--akzent); color: var(--akzent);
  background: var(--akzent-schwach);
}


/* Der Inhalt laeuft aus der Richtung herein, in die geblaettert wurde.
   Ohne diese Bewegung wirkt der Monatswechsel wie ein Sprung. */
@keyframes auftauchen {
  from { opacity: 0; transform: translate(var(--wisch, 0), 6px); }
  to   { opacity: 1; transform: none; }
}

/* Waagerechtes Wischen soll die Seite nicht mitziehen */
main { touch-action: pan-y; }


/* ==========================================================================
   Leuchtendes Gelb statt Gold, und der Verlauf kraeftiger.
   Der Balken laeuft von dunkel nach hell - das gibt ihm Koerper und laesst
   die Fuellung wirken, als komme sie von links herein. Die linke Seite wird
   deshalb um rund ein Fuenftel weiter abgedunkelt.
   Fuer Text braucht es einen eigenen Ton: reines Gelb ist auf Weiss nicht
   lesbar, als Flaeche dagegen genau richtig.
   ========================================================================== */

:root {
  --knapp: #ffe21a;        /* Flaeche: leuchtendes Gelb */
  --knapp-text: #ffe21a;   /* Schrift im dunklen Schema */
}
@media (prefers-color-scheme: light) {
  html:not([data-theme="dark"]) { --knapp: #ffdc00; --knapp-text: #a86a00; }
}
html[data-theme="light"] { --knapp: #ffdc00; --knapp-text: #a86a00; }
html[data-theme="dark"]  { --knapp: #ffe21a; --knapp-text: #ffe21a; }

/* Verlauf: links deutlich tiefer als rechts */
.balken i {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--akzent-tief) 74%, #000 26%) 0%,
    var(--akzent-tief) 38%,
    var(--akzent) 100%);
}
.balken i.knapp {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--knapp) 48%, #8a4b00 52%) 0%,
    color-mix(in srgb, var(--knapp) 78%, #c58a00 22%) 42%,
    var(--knapp) 100%);
}
.balken i.ueberzogen {
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--schlecht) 55%, #000 45%) 0%,
    var(--schlecht) 100%);
}

.balken-wert.knapp { color: var(--knapp-text); }


/* Der Monat in der Leiste zeigt das Ergebnis mit: gruen nur bei Guthaben. */
#monat-klein.minus, #monat-klein.fremd.minus { color: var(--schlecht); }
#monat-klein.minus::after { content: ' ↩'; }




/* Gruppen in der Verpflichtungsliste */
.zeilen li.gruppenkopf {
  margin-top: .55rem; padding-top: .45rem; border-top: 1px solid var(--linie);
  font-size: .7rem; text-transform: uppercase; letter-spacing: .08em;
}
.zeilen li.gruppenkopf:first-child { margin-top: .2rem; border-top: 0; padding-top: 0; }
.zeilen li.gruppenkopf span { color: var(--gedaempft); font-weight: 700; }
.zeilen li.gruppenkopf b { color: var(--gedaempft); font-weight: 700; font-size: .78rem; }

/* Das Datum steht vorn und in Ziffernbreite, damit die Spalte ruhig bleibt */
.datum {
  font-style: normal; display: inline-block; min-width: 3.4rem;
  color: var(--gedaempft); font-variant-numeric: tabular-nums; font-size: .95em;
}


/* Balken direkt unter dem Gruppenkopf - zeigt die Verpflichtungen der
   Kategorie im Verhaeltnis zu ihrem Planwert. */
.zeilen li.gruppenkopf.mitplan { padding-bottom: .1rem; }
.zeilen li.gruppenbalken {
  display: block; margin: 0 0 .3rem; padding: 0;
}
.zeilen li.gruppenbalken .balken { height: 5px; width: 100%; }


.kat-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kat-zahl { flex: none; opacity: .7; }


/* ==========================================================================
   Handy-Ansicht: nichts darf abgeschnitten werden.
   Der Fehler lag an den Versalien mit Sperrung - die standen auch auf den
   Betraegen und fressen dort Breite, die die Zahl braucht. Jetzt traegt nur
   noch der Kategoriename die Auszeichnung, der Betrag steht normal.
   ========================================================================== */

.zeilen li.gruppenkopf { align-items: baseline; gap: .6rem; }
.zeilen li.gruppenkopf > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.zeilen li.gruppenkopf b {
  text-transform: none; letter-spacing: 0; font-size: .82rem;
  white-space: nowrap; flex: none;
}
.zeilen li.gruppenkopf b .quelle { margin-left: .3rem; }
/* Der Gruppenkopf faerbt sein "Ist / Plan" wie die Balkenliste ihres -
   sonst steht dieselbe Aussage zweimal da und einmal davon in Grau.
   Eine Klasse mehr als die Regel darueber, sonst schlaegt deren Grau. */
.zeilen li.gruppenkopf b.knapp { color: var(--knapp-text); }
.zeilen li.gruppenkopf b.ueberzogen { color: var(--schlecht); }

/* Auch die Einzelposten duerfen den Betrag nicht verlieren.

   Rueckmeldung 96d9c419 ("unschoene formatierung"): die Zeile war ein Flex
   mit space-between. Bei zwei Kindern steht der Betrag damit rechts - bei
   dreien, Text und Betrag und Haekchen, schwimmt er in der Mitte und wandert
   mit der Laenge des Namens. Untereinander stand er dadurch mal hier, mal
   dort. Ein Raster haelt ihn in der Spur: der Text nimmt den Rest, der
   Betrag steht rechts.

   Wo abgehakt werden kann, steht die Haekchenspalte in JEDER Zeile der
   Liste, auch in denen ohne Haekchen - sonst richtet sich der eine Betrag am
   Rand aus und der naechste am Kreis daneben. */
.zeilen li.unterposten {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline; gap: .5rem;
}
.zeilen li.unterposten > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.zeilen li.unterposten > b { justify-self: end; white-space: nowrap; }
.kernzahlen li.unterposten, .zeilen li.unterposten.mit-haken {
  grid-template-columns: minmax(0, 1fr) auto 2rem;
}
.zeilen li.unterposten > .haken-buchen { justify-self: end; margin-left: 0; }

/* Die Balkenbahn steht immer - ein leerer Balken ist eine Aussage:
   in dieser Kategorie ist noch nichts geflossen. */
.zeilen li.gruppenbalken .balken { background: var(--karte-innen); }
.zeilen li.gruppenbalken .balken i { min-width: 0; }

@media (max-width: 420px) {
  .zeilen li.gruppenkopf { font-size: .68rem; }
  .zeilen li.gruppenkopf b { font-size: .78rem; }
  .datum { min-width: 3rem; font-size: .9em; }
  .zeilen li.unterposten { font-size: .75rem; }
}


#aufnehmen-liste { max-height: 46vh; overflow-y: auto; margin-bottom: .8rem; }
#aufnehmen-liste .vorschlag { padding: .5rem .6rem; }
#aufnehmen-liste .siegel { margin-left: auto; }


#mehr-buchungen { margin-top: .6rem; }


/* `z-index` dazu, damit der Halter mitsamt seiner Vorschlagsliste ueber
   dem steht, was in der Seite NACH ihm kommt - auf der Buchungsseite die
   Auswahlleiste. Waehrend die Einblendanimation laeuft, ist der Halter
   ohnehin ein Stapelkontext; ohne eigene Stufe stuende er auf 0 und damit
   gleichauf mit allem anderen. 15 bleibt bewusst unter den 30 von
   .kopfbereich und .tableiste: die decken das Suchfeld weiter zu. */
.suchfeld-halter { position: relative; z-index: 15; }
.vorschlagsliste {
  position: absolute; left: 0; right: 0; top: calc(100% - .3rem); z-index: 15;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-klein); overflow: hidden; box-shadow: var(--schatten);
}
.vorschlagsliste[hidden] { display: none; }
.vorschlagsliste button {
  display: flex; width: 100%; align-items: center; gap: .6rem;
  padding: .6rem .7rem; border: 0; border-bottom: 1px solid var(--linie);
  background: none; color: var(--text); font-family: inherit; font-size: .85rem;
  text-align: left; cursor: pointer;
}
.vorschlagsliste button:last-child { border-bottom: 0; }
.vorschlagsliste button:active { background: var(--karte-innen); }
.vorschlagsliste .name {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}


/* Platzhalter: sichtbar als Leerstelle, nicht als Zahl die etwas bedeutet.
   "Tage bis Monatsende" ergibt nur im laufenden Monat einen Sinn. */
.kennwert.platzhalter b { color: var(--linie); letter-spacing: .08em; }
.kennwert.platzhalter span { opacity: .55; }


/* Die Prognosekachel ist ein Knopf - das muss man ihr ansehen. */
.kennwert.anklickbar {
  border: 1px solid var(--linie); font-family: inherit; cursor: pointer;
  text-align: center; width: 100%;
}
.kennwert.anklickbar:active { background: var(--karte-innen); }
.kennwert.anklickbar .quelle { display: block; margin-top: .1rem; color: var(--akzent); }
/* Der Ueberzug ueber die Ziele steht unter der Zahl, nicht an ihrer Stelle
   (Rueckmeldung 5c51552b). Klein genug, um die Kachel nicht zu sprengen,
   rot genug, um gelesen zu werden. */
.kennwert .ueberzug {
  display: block; font-style: normal; font-size: .62rem; font-weight: 700;
  color: var(--schlecht); font-variant-numeric: tabular-nums; line-height: 1.25;
}
#erklaerung-inhalt .zeilen { margin-bottom: .4rem; }


/* Eine Gutschrift soll man sehen, ohne den Betrag zu lesen - aber leise,
   sonst leuchtet eine Liste voller Gehaelter wie ein Weihnachtsbaum. */
.buchung.einnahme {
  background: color-mix(in srgb, var(--gut) 7%, transparent);
  box-shadow: inset 3px 0 0 color-mix(in srgb, var(--gut) 55%, transparent);
}
.buchung.einnahme:active { background: color-mix(in srgb, var(--gut) 13%, transparent); }

/* Die Prognosezeile unten ist ebenfalls ein Weg in die Herleitung */
.zeilen li.summe.anklickbar { cursor: pointer; }
.zeilen li.summe.anklickbar:active { opacity: .6; }
.zeilen li.summe.anklickbar .quelle { color: var(--akzent); margin-left: .3rem; }


/* Ein Einnahmevertrag läuft in die andere Richtung. Das gilt der ganzen Zeile,
   nicht nur der Zahl - sonst liest man erst das Vorzeichen und versteht dann.
   Leise gehalten wie bei den Buchungen: eine Ahnung von Grün, kein Leuchten. */
.zeilen li.unterposten.einnahme {
  background: color-mix(in srgb, var(--gut) 7%, transparent);
  border-left-color: color-mix(in srgb, var(--gut) 55%, transparent);
  padding-right: .4rem; border-radius: 0 4px 4px 0;
}
.zeilen li.unterposten.einnahme span,
.zeilen li.unterposten.einnahme b,
.zeilen li.unterposten.einnahme .datum,
.unterposten.anklickbar.einnahme b {
  color: color-mix(in srgb, var(--gut) 75%, var(--text));
}


/* Nachladen: erst in Zwanzigerschritten, nach dem ersten Mal auch am Stueck. */
.mehr-knoepfe { display: flex; gap: .5rem; margin-top: .6rem; }
.mehr-knoepfe button { flex: 1; }

/* Mehrfachauswahl in einer Kategorie. Der Haken sitzt vorn, weil die Zeile
   von links gelesen wird - und weil der Daumen dort ohnehin liegt. */
.auswahlleiste {
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  padding: .5rem .2rem .55rem; border-bottom: 1px solid var(--linie);
  margin-bottom: .4rem;
}
.auswahlleiste span { flex: 1; font-size: .8rem; color: var(--gedaempft); }
.auswahlleiste button[disabled] { opacity: .4; }
.buchung .haken {
  flex: none; display: grid; place-items: center;
  width: 1.15rem; height: 1.15rem; border-radius: 6px;
  border: 1px solid var(--linie); color: var(--akzent);
  font-size: .72rem; line-height: 1;
}
.buchung.gewaehlt .haken { border-color: var(--akzent); }
.buchung.gewaehlt { background: var(--karte-innen); }

/* Mehrfachauswahl im Verlaufsdialog (63cd29fa). Die Haekchenspalte entsteht
   erst im Waehlmodus: sie dauerhaft freizuhalten hiesse, in jeder Zeile Leere
   zu zeigen fuer etwas, das die meisten nie einschalten. Umgeschaltet wird per
   Klasse und ohne Neuzeichnen - sonst klappt jede offene Monatszeile zu. */
#erklaerung-inhalt .haken-wahl { display: none; }
#erklaerung-inhalt.waehlmodus .zeilen li.unterposten[data-buchung] {
  grid-template-columns: minmax(0, 1fr) auto 1.6rem;
}
#erklaerung-inhalt.waehlmodus .haken-wahl {
  display: block; justify-self: end; align-self: center;
  width: 1.15rem; height: 1.15rem; border-radius: 6px;
  border: 1px solid var(--linie);
}
#erklaerung-inhalt.waehlmodus li.gewaehlt { background: var(--karte-innen); }
#erklaerung-inhalt.waehlmodus li.gewaehlt .haken-wahl {
  border-color: var(--akzent); background: var(--akzent);
}


/* Eine angekuendigte Preisaenderung: sichtbar, aber nicht laut. */
.preisstufe { color: var(--akzent); white-space: nowrap; }

/* ===================================================== Zugang, Rollen, Einladung */

/* Solange das Geraet nicht angemeldet ist, gibt es nichts zu navigieren:
   Kopfleiste, Tableiste und Schnellknopf bleiben weg. */
body.zugang-offen .kopfbereich,
body.zugang-offen .tableiste,
body.zugang-offen .schwebeknopf { display: none; }
/* Der Melde-Knopf bleibt: gerade beim ersten Kontakt klemmt es am ehesten,
   und dann steht sonst kein Weg offen, das jemandem zu sagen. Ohne Tableiste
   darunter rutscht er tiefer. */
/* Von aussen wird nicht gemeldet - eine Meldung ohne Absender und ohne
   Haushalt laesst sich nicht beantworten (Rueckmeldung b392eac7).
   Was auf der Startseite schiefgeht, steht im Fehlerprotokoll. */
body.zugang-offen .meldeknopf { display: none; }
body.zugang-offen main { padding-top: 3rem; min-height: 100dvh; }

.kachel.zugang { max-width: 26rem; margin-inline: auto; }
.zugang-titel {
  margin: .3rem 0 1.2rem; font-size: 1.25rem; font-weight: 650; line-height: 1.3;
}
.kachel.zugang .feld { margin-bottom: .6rem; }

/* Der Einladungscode wird abgetippt - also weite Zeichen, gleiche Breite,
   und keine Ligaturen, die 0 und O aneinander angleichen. */
.einladungsfeld, .einladungscode, .haushaltscode {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: .12em; font-variant-ligatures: none;
}
.haushaltscode {
  margin: .5rem 0 0; font-size: 1.3rem; font-weight: 650; color: var(--akzent);
}
.einladungscode {
  margin: .8rem 0 .2rem; font-size: 1.15rem; font-weight: 650; text-align: center;
}

/* Ein QR muss dunkel auf hell bleiben, sonst lesen ihn manche Scanner nicht.
   Deshalb liegt er auch im Dunkelmodus auf einer weissen Karte. */
.qr-karte {
  background: #fff; border-radius: var(--radius-klein); padding: .7rem;
  width: min(15rem, 70%); margin: .9rem auto 0; line-height: 0;
}
.qr-karte svg { width: 100%; height: auto; display: block; }

.einladung {
  border-top: 1px solid var(--linie); padding-top: 1rem; margin-top: 1rem;
}
.einladung:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.einladungen { display: grid; gap: .4rem; }

.teilen {
  display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .9rem;
}
.teilen > * { flex: 1 1 auto; }
.teilen a.sekundaer {
  display: inline-flex; align-items: center; justify-content: center;
  text-decoration: none;
}

/* Rollenwahl vor dem Erzeugen der Einladung */
/* Zwei Knoepfe am rechten Ende einer Reihe bleiben zusammen, statt sich
   den Platz mit dem Namen zu teilen (Geraeteliste, 4d027931). */
.reihe-knoepfe { display: flex; gap: .4rem; flex: none; }

.rollenknoepfe { display: flex; gap: .4rem; margin-top: .7rem; }
.rollenknoepfe button {
  flex: 1; padding: .55rem .3rem; font-size: .85rem; border-radius: var(--radius-klein);
  background: var(--karte-innen); color: var(--gedaempft);
  border: 1px solid transparent;
}
.rollenknoepfe button.aktiv {
  color: var(--text); border-color: var(--akzent); background: var(--akzent-schwach);
}

.rollenwahl {
  background: var(--karte-innen); color: var(--text); border: 1px solid var(--linie);
  border-radius: var(--radius-klein); padding: .35rem .5rem; font-size: .8rem;
}
.rollenschild {
  font-size: .78rem; color: var(--gedaempft); white-space: nowrap;
  padding: .35rem .5rem;
}

/* Wer nicht verwalten darf, bekommt die Knoepfe gar nicht erst zu sehen -
   der Server weist sie ohnehin ab, aber eine Schaltflaeche, die immer
   scheitert, ist schlechter als keine.
   ACHTUNG: das ist Anzeige, keine Sicherung. Die liegt in rechte.js. */
body.rolle-leser :is(.mini.plus, [data-loeschen], [data-neu], .dateiwahl, #kontostand-setzen,
                     [data-korb-zurueck], [data-korb-weg], [data-korb-leeren],
                     #vertraege-alle-weg),
body.rolle-mitglied :is(.mini.plus, [data-loeschen], [data-neu], .dateiwahl, #kontostand-setzen,
                     [data-korb-zurueck], [data-korb-weg], [data-korb-leeren],
                     #vertraege-alle-weg) {
  display: none;
}
/* Auf der Haushaltsseite darf das eigene Geraet trotzdem abgemeldet werden. */
body.rolle-leser .kachel [data-geraet-weg],
body.rolle-mitglied .kachel [data-geraet-weg] { display: inline-flex; }

/* Ein Leser darf nicht buchen, also braucht er auch keinen Buchen-Knopf -
   weder den am Ring noch den schwebenden. Fuer Mitglieder bleiben beide:
   buchen und zuordnen ist genau ihr Alltag. */
body.rolle-leser .ring-plus,
body.rolle-leser .schwebeknopf { display: none; }

/* ============================================================== Aussenhaut

   Die Startseite ist das Erste, was ein Fremder sieht. Sie benutzt dieselben
   Farbtoken wie die App - wer sich anmeldet, soll nicht das Gefuehl haben, in
   ein anderes Produkt zu geraten. */

.landing { max-width: 30rem; margin-inline: auto; }

.landing-marke {
  display: flex; align-items: center; gap: .8rem;
  margin: .5rem 0 1.4rem; padding: 0 .2rem;
}
.landing-zeichen { width: 2.9rem; height: 2.9rem; flex: none; }
.landing-name {
  margin: 0; font-size: 1.35rem; font-weight: 680; letter-spacing: -.02em;
}
.landing-unter { margin: .1rem 0 0; font-size: .84rem; color: var(--gedaempft); }

.landing-titel {
  margin: 0 0 .6rem; font-size: 1.5rem; font-weight: 680;
  letter-spacing: -.02em; line-height: 1.25;
}
.landing-text { margin: 0; font-size: .95rem; line-height: 1.6; color: var(--text); }

.landing-schritte {
  margin: .9rem 0 0; padding-left: 1.2rem; display: grid; gap: .55rem;
  font-size: .89rem; line-height: 1.5;
}
.landing-schritte li { padding-left: .2rem; }
.landing-schritte li::marker { color: var(--akzent); font-weight: 650; }

.landing .kachel { margin-bottom: .8rem; }
.landing .feld { margin-bottom: .55rem; }
.landing textarea.feld { resize: vertical; font: inherit; line-height: 1.45; }

.landing-fuss {
  margin: 1.6rem 0 2.5rem; text-align: center;
  font-size: .8rem; color: var(--gedaempft);
}
.landing-fuss a { color: var(--gedaempft); text-decoration: underline;
  text-underline-offset: 2px; }
.landing-fuss a:hover { color: var(--text); }

.imp-name { font-weight: 650; margin-bottom: .4rem; }
#impressumsfeld p { margin: .15rem 0; font-size: .9rem; }

.fliesstext p { margin: 0 0 .8rem; font-size: .89rem; line-height: 1.6; }
.fliesstext p:last-child { margin-bottom: 0; }

/* ================================================================== Panel

   Der Betreiberbereich sitzt bewusst nicht in der Tableiste: er gehoert nicht
   zum Haushalt, sondern zur Anlage. */

.panel-marke {
  display: inline-block; font-size: .68rem; font-weight: 650; letter-spacing: .08em;
  text-transform: uppercase; color: var(--akzent);
  background: var(--akzent-schwach); border-radius: 999px; padding: .2rem .55rem;
  margin-bottom: .6rem;
}
.anfrage { border-top: 1px solid var(--linie); padding-top: .9rem; margin-top: .9rem; }
.anfrage:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.anfrage-kopf { display: flex; justify-content: space-between; gap: .8rem; align-items: baseline; }
.anfrage-name { font-weight: 620; }
.anfrage-mail { font-size: .78rem; color: var(--gedaempft); word-break: break-all; }
.anfrage-text {
  margin: .5rem 0 0; font-size: .85rem; line-height: 1.5; color: var(--gedaempft);
  border-left: 2px solid var(--linie); padding-left: .6rem;
}
.anfrage-knoepfe { display: flex; gap: .5rem; margin-top: .7rem; }
.anfrage-knoepfe > * { flex: 1; }

.stand { font-size: .7rem; font-weight: 650; letter-spacing: .04em;
  text-transform: uppercase; white-space: nowrap; }
.stand.offen     { color: var(--knapp); }
.stand.wartet    { color: var(--knapp); }
/* Eine Zahl ueber der Grenze muss man sehen, ohne sie zu suchen. */
.ms-ueber { color: var(--schlecht); font-weight: 650; }
.stand.frei      { color: var(--gut); }
.stand.abgelehnt { color: var(--gedaempft); }

.panel-feld { display: grid; gap: .3rem; margin-bottom: .8rem; }
.panel-feld > span { font-size: .78rem; color: var(--gedaempft); }
.panel-feld .feld { margin: 0; }
.panel-zwei { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
@media (max-width: 30rem) { .panel-zwei { grid-template-columns: 1fr; } }

.schalter { display: flex; align-items: center; gap: .6rem; margin: .3rem 0 .9rem;
  font-size: .88rem; }
.schalter input { width: 1.1rem; height: 1.1rem; accent-color: var(--akzent); }

/* Rückmeldung: die Art wählt man an ganzen Kacheln, nicht an einem Wort -
   auf dem Handy trifft der Daumen sonst daneben. */
.artwahl { display: grid; gap: .5rem; margin-top: .7rem; }
.artwahl button {
  display: grid; gap: .15rem; text-align: left; padding: .7rem .8rem;
  background: var(--karte-innen); border: 1px solid transparent;
  border-radius: var(--radius-klein); color: var(--gedaempft);
}
.artwahl button.aktiv {
  border-color: var(--akzent); background: var(--akzent-schwach); color: var(--text);
}
.artwahl-titel { font-size: .92rem; font-weight: 620; }
.artwahl-hilfe { font-size: .78rem; line-height: 1.4; }
.artwahl button.aktiv .artwahl-hilfe { color: var(--gedaempft); }
.primaer.mitte, .sekundaer.mitte { display: block; text-align: center; text-decoration: none; }

/* Der Haken in einer Listenzeile darf die Zeile nicht auseinanderziehen. */
.schalter.klein { margin: 0; font-size: .75rem; color: var(--gedaempft);
  white-space: nowrap; gap: .35rem; }
.schalter.klein input { width: .95rem; height: .95rem; }

/* Regelprüfung: zwei Zeilen je Fund, damit man das Paar als Paar sieht. */
.funde { display: grid; gap: .8rem; margin-top: .8rem; }
.fund {
  border: 1px solid var(--linie); border-radius: var(--radius-klein);
  padding: .7rem .8rem; display: grid; gap: .4rem;
}
.fund.konflikt { border-color: color-mix(in srgb, var(--knapp) 55%, var(--linie)); }
.fund-kopf { margin-bottom: .1rem; }
.fund-seite {
  display: flex; align-items: center; justify-content: space-between; gap: .7rem;
  padding: .45rem .55rem; border-radius: 8px; background: var(--karte-innen);
}
.fund-seite.empfohlen { outline: 1px solid var(--schlecht); outline-offset: -1px; }
.fund-seite .name { font-size: .88rem; }
.fund-seite .meta { font-size: .74rem; }
.fund .erklaerung { margin-top: .2rem; }

/* Zurück in der schmalen Kopfleiste. Trefferfläche großzügig, damit der
   Daumen ihn auf dem Handy sicher erwischt. */
.marke-zurueck {
  color: var(--akzent); text-decoration: none; font-size: .82rem; font-weight: 600;
  white-space: nowrap; padding: .35rem .45rem; margin: -.35rem -.15rem -.35rem -.3rem;
  border-radius: 8px;
}
.marke-zurueck:active { background: var(--karte-innen); }
.marke-zurueck[hidden] { display: none; }
/* Steht das Zurück da, ist der Seitenname daneben nur noch Beiwerk. */
.marke-zurueck:not([hidden]) + .marke-seite { color: var(--gedaempft); }

/* Zusammenführen: die Auswahl steht in der Fundkarte, nicht in einem Dialog -
   man braucht beide Zeilen im Blick, während man entscheidet. */
.fund-form { border-top: 1px solid var(--linie); margin-top: .7rem; padding-top: .7rem; }
.fund-wahl {
  display: flex; align-items: center; gap: .55rem; padding: .4rem .2rem;
  font-size: .87rem; cursor: pointer;
}
.fund-wahl input { accent-color: var(--akzent); width: 1rem; height: 1rem; flex: none; }
.fund-wahl span { word-break: break-word; }
.fund-form .teil-titel { margin-top: .5rem; }
.fund-form .teilen { margin-top: .8rem; }

/* Am Anfang der Zeitreihe zeigt der Zurück-Pfeil ins Leere. Er bleibt stehen,
   damit die Kopfzeile nicht springt, wird aber sichtbar wirkungslos. */
.pfeil.stumpf { opacity: .25; }

/* Erststart-Führung */
.schrittleiste {
  display: flex; gap: .3rem; margin: 0 0 1rem; flex-wrap: wrap;
}
/* NUR die Reiter der Erststart-Führung.

   `.schritt` gibt es zweimal in der App: hier als schmaler Reiter in der
   Leiste, und auf der Einrichtungsseite als ganze Kachel
   (`<section class="kachel schritt">`). Ohne den Vorfahren traf diese Regel
   beide - und damit lag über der ganzen Einrichtungsseite ein
   `white-space: nowrap`. Nichts brach mehr um: die Erklärungstexte liefen
   rechts aus dem Bild, die Beispielzeilen der Kategorievorschläge machten
   die Karte 395 px breit auf einem 375-px-Schirm. Dazu die zentrierte
   Ausrichtung und die gedämpfte Farbe, beides für einen Reiter gedacht.
   Gemeldet als „optik unschön" (4619815c), gemessen im Browser.

   `.schritt.fertig { opacity: .75 }` weiter oben gilt weiterhin für beide -
   das ist die Regel, die die Einrichtungskachel wirklich meint. */
.schrittleiste .schritt {
  flex: 1 1 auto; text-align: center; font-size: .68rem; padding: .3rem .2rem;
  border-bottom: 2px solid var(--linie); color: var(--gedaempft);
  white-space: nowrap;
}
.schrittleiste .schritt.fertig { border-color: var(--akzent); color: var(--gedaempft); }
.schrittleiste .schritt.jetzt  { border-color: var(--akzent); color: var(--text); font-weight: 650; }

.merkzeilen li { display: block; padding-left: 1rem; position: relative; line-height: 1.5; }
.merkzeilen li::before {
  content: '·'; position: absolute; left: .25rem; color: var(--akzent); font-weight: 700;
}
.merkzeilen span { color: var(--text); }

.beispielkasten {
  background: var(--karte-innen); border-radius: var(--radius-klein);
  padding: .7rem .9rem; margin: .9rem 0 0;
}
.beispielkasten .teil-titel { margin-top: 0; }

.kachel .zugang-titel { margin-top: .2rem; }

/* ------------------------------------------------- Neue Fassung verfügbar

   Über der Tableiste, nicht als Toast: die Nachricht verliert nach drei
   Sekunden nicht an Gültigkeit. Sie lädt auch nichts von selbst nach - wer
   gerade einen Betrag eintippt, verlöre ihn und wüsste nicht, warum. */
.neue-fassung {
  position: fixed; z-index: 45;
  left: .7rem; right: .7rem;
  bottom: calc(4.9rem + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: .6rem;
  padding: .6rem .5rem .6rem .9rem;
  border-radius: var(--radius-klein);
  background: var(--text); color: var(--bg);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .4);
  font-size: .82rem; font-weight: 550;
}
.neue-fassung span { flex: 1; }
.nf-laden {
  border: 0; border-radius: 999px; cursor: pointer; font-family: inherit;
  padding: .3rem .8rem; font-size: .78rem; font-weight: 700;
  background: var(--akzent); color: #04241b;
}
.nf-zu {
  border: 0; background: transparent; color: inherit; cursor: pointer;
  font-size: .9rem; line-height: 1; padding: .2rem .35rem; opacity: .6;
}
body.zugang-offen .neue-fassung {
  bottom: calc(1.1rem + env(safe-area-inset-bottom));
}

/* --------------------------------------- Meldeliste: eine Zeile je Meldung

   Vierzig Meldungen mit vollem Text, Kontext und zwei Knopfreihen sind eine
   Wand, keine Liste. Zum Sichten braucht es die Kopfzeile und sonst nichts —
   der Rest klappt auf. */
details.anfrage > summary {
  cursor: pointer; list-style: none; display: flex;
  align-items: flex-start; justify-content: space-between; gap: .7rem;
}
details.anfrage > summary::-webkit-details-marker { display: none; }
details.anfrage > summary::after {
  content: '⌄'; color: var(--gedaempft); font-size: .9rem; flex-shrink: 0;
}
details.anfrage[open] > summary::after { content: '⌃'; }
details.anfrage > summary > div { min-width: 0; }

/* Der Stand als Marke. Grün heisst nachgeprüft, blau heisst „die Maschine
   sagt gelöst" — das ist ausdrücklich nicht dasselbe. */
.stand.ki {
  background: color-mix(in srgb, #6aa8ff 18%, transparent);
  color: #6aa8ff; border-color: #6aa8ff;
}
.ms-zahl b.ki     { color: var(--ki); }
.ms-zahl b.warten { color: var(--warten); }
.ms-zahl b.leise  { color: var(--gedaempft); }
.ki-satz { color: #6aa8ff; font-size: .78rem; }
.melde-sortierung { margin: .2rem 0 .6rem; }

/* --------------------------------- Vorhaben abhaken

   Ein Vorhaben hat drei Ausgänge: wie geplant, teurer/billiger, ausgefallen.
   Nur der erste ist der Regelfall — und für den darf es keinen Dialog
   brauchen. Das Häkchen sitzt deshalb am Ende der Zeile, hinter dem Pfeil: erst
   lesen, was ansteht, dann abhaken. */
.haken-buchen {
  flex-shrink: 0; width: 1.5rem; height: 1.5rem; margin-left: .5rem;
  border-radius: 50%; border: 1px solid var(--linie); background: transparent;
  color: var(--gedaempft); font-size: .8rem; line-height: 1; cursor: pointer;
  padding: 0; font-family: inherit;
}
.haken-buchen:active { background: var(--akzent); color: #04241b; border-color: var(--akzent); }
.haken-buchen:disabled { opacity: .4; }

/* Zwei Zustaende eines Faelligkeitstermins. Die Klasse sitzt auf der ZEILE,
   nicht auf dem Datum: "mach die ganze zeile gruen bitte" (Frank,
   31.08.2026). Welche Zeile welchen Zustand hat, entscheidet
   datumsklasse() in app.js - hier steht nur, wie er aussieht.

   Ueberfaellig heisst: der Tag ist vorbei und niemand hat gesagt, was
   daraus wurde. Das bleibt auf dem Datum, es ist eine Frage an genau
   diesen Tag. */
li.ueberfaellig .datum { color: var(--schlecht); font-weight: 700; }

/* Erreicht heisst: der Vertrag ist abgebucht, auch wenn der Kontoauszug
   noch hinterherhinkt. Die GANZE Zeile: Datum, Name, Kategorie, Betrag.

   Nur die Farbe auf dem <li> zu setzen reicht nicht - geerbte Farbe
   verliert gegen jede Regel, die ein Kind direkt faerbt. Das tun hier
   zwei: .quelle (die Kategorie, gedaempft) und .unterposten.anklickbar b
   (der Betrag, in der Akzentfarbe). Deshalb der Nachfahren-Selektor, und
   die zweite Zeile mit einer Klasse mehr, um .unterposten.anklickbar b
   (0,2,1) zu schlagen. */
li.erreicht, li.erreicht * { color: var(--gut); }
li.unterposten.erreicht, li.unterposten.erreicht * { color: var(--gut); }
li.erreicht .datum { font-weight: 700; }
/* Was von einer Pendelphase noch aussteht - hinter dem Namen, leiser als er
   (Rueckmeldung 3070f7b3). Kein eigener Rang: die Zahl rechts ist die
   Aussage, das hier sagt nur, woraus sie sich ergibt. */
.phase-rest {
  font-style: normal; color: var(--gedaempft); font-size: .92em;
  margin-left: .35rem;
}

/* Sechsmal derselbe Eintrag ist keine Planung, sondern ein mehrfach
   abgeschickter Knopf. Das gehört benannt, nicht stumm gestapelt. */
.dublette {
  font-style: normal; font-size: .68rem; color: var(--schlecht);
  margin-left: .35rem;
}

/* Mitgliederzeile bricht um.

   Auf 375 px stehen dort Name, Gerätezahl, Rollenwahl und bis zu zwei
   Knöpfe. Nebeneinander geht das nicht auf — die Rollenwahl legte sich über
   die Zeile darunter. Umbrechen statt quetschen; auf breiten Schirmen
   bleibt alles in einer Zeile, weil erst umgebrochen wird, wenn es eng wird. */
.mitgliedszeile { flex-wrap: wrap; row-gap: .5rem; }
.mitgliedszeile .wer { flex: 1 1 11rem; }
.mitgliedszeile .rollenwahl { flex: 0 1 auto; max-width: 100%; }
.mitgliedszeile .meta { overflow-wrap: anywhere; }

/* Der Weg zur Stelle, an der es geknallt hat. */
.fehler-ort { color: var(--akzent); text-decoration: underline; }

/* Der Weg zur gemeldeten Stelle. Steht in einer Kopfzeile, die selbst
   anklickbar ist — deshalb muss er sich davon abheben. */
.melde-ort { color: var(--akzent); text-decoration: underline; }

/* Feste Gliederung statt gemischter Liste: offen, KI-gelöst, erledigt,
   verworfen. Alle vier gleich gebaut, damit sie sich gleich verhalten —
   nur "verworfen" startet zugeklappt. */
details.meldegruppe { margin-top: 1.1rem; }
details.meldegruppe > summary {
  display: flex; align-items: baseline; gap: .45rem;
  cursor: pointer; list-style: none;
  margin: 0 0 .3rem; padding-bottom: .3rem;
  border-bottom: 1px solid var(--linie);
  font-size: .68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; color: var(--gedaempft);
}
details.meldegruppe > summary::-webkit-details-marker { display: none; }
details.meldegruppe > summary::after {
  content: '⌄'; margin-left: auto; font-size: .9rem;
  text-transform: none; letter-spacing: 0;
}
details.meldegruppe[open] > summary::after { content: '⌃'; }
details.meldegruppe > summary em {
  font-style: normal; font-size: .72rem; letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.meldegruppe.g-offen    > summary { color: var(--text); }
.meldegruppe.g-ki       > summary { color: #6aa8ff; border-bottom-color: #6aa8ff44; }
.meldegruppe.g-verworfen > summary { opacity: .7; }
.meldegruppe.g-verworfen .anfrage { opacity: .55; }
.meldegruppe.g-zusammen  > summary { opacity: .7; }
.meldegruppe.g-zusammen  .anfrage { opacity: .6; }
/* "3 zusammengeführt" am Zielticket - eine Angabe, kein Knopf. */
.melde-anhang { color: var(--gedaempft); }

/* Betroffene Buchungen im Regel-Dialog (Ticket 4bf0fe16).

   Frank: "eine scollbare liste groesse von 6 zeilen". Die Hoehe steht
   deshalb in Zeilen und nicht in Pixeln - waechst die Schrift, waechst die
   Liste mit, und es bleiben sechs Zeilen statt fuenfeinhalb. */
.formblock { margin: .6rem 0; }
.formblock-titel {
  display: block; font-size: .78rem; color: var(--gedaempft);
  margin-bottom: .3rem;
}
/* Mehrere Suchtexte (db/159). Untereinander, weil sie eine Liste sind und
   keine Zeile - und weil ein langes Muster sonst die naechsten wegdrueckt. */
/* Einnahme-Vorschlaege heben sich ab - dieselbe Farbe wie Einnahmen ueberall
   sonst in der App, damit die Bedeutung nicht neu gelernt werden muss. */
.chip.chip-einnahme { color: var(--gut); border-color: var(--gut); }

.musterliste { display: flex; flex-direction: column; gap: .3rem; }

/* Das kleine x im Textfeld (Ticket 4c5c4362).

   Die Huelle ist ein block, damit das Feld seine Breite behaelt - saesse sie
   inline, schrumpfte jedes Feld auf seinen Inhalt. Das Feld bekommt rechts
   Platz, damit der lange Text nicht unter dem x verschwindet. */
.feld-mit-x { position: relative; display: block; }
.feld-mit-x > .feld { width: 100%; padding-right: 2.1em; }
.feld-x {
  position: absolute;
  right: .45em;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: none;
  color: var(--gedaempft);
  cursor: pointer;
  font-size: 1.15em;
  line-height: 1;
  padding: .15em .3em;
  border-radius: 50%;
}
.feld-x:hover { color: var(--text); background: var(--karte-innen); }

/* In der Regelliste haengen sie am Namen. Das Plus sagt "und", ohne dass ein
   Wort dafuer noetig waere. */
.und-muster {
  font-weight: normal;
  color: var(--gedaempft);
  margin-left: .4em;
  font-size: .92em;
  white-space: nowrap;
}

.betroffen-stand { font-size: .82rem; margin: 0 0 .4rem; color: var(--gedaempft); }
.betroffen-stand.warnung { color: var(--schlecht); }
.betroffen-liste {
  max-height: calc(6 * 2.55rem);
  overflow-y: auto;
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
}
.betroffen {
  display: flex; justify-content: space-between; gap: .6rem;
  padding: .35rem .55rem;
  border-bottom: 1px solid var(--linie);
  font-size: .82rem;
  min-width: 0;
}
.betroffen:last-child { border-bottom: none; }
/* Eine Buchung, die eine andere Regel bekommt, ist der interessante Fall -
   sie wird gedaempft, nicht hervorgehoben: hervorgehoben ist, was diese
   Regel wirklich hat. */
.betroffen.fremd { background: var(--karte-innen); }
.betroffen-wer { min-width: 0; display: flex; flex-direction: column; }
.betroffen-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.betroffen-datum, .betroffen-weg, .betroffen-hand {
  font-size: .72rem; color: var(--gedaempft);
}
.betroffen-rechts {
  display: flex; flex-direction: column; align-items: flex-end;
  white-space: nowrap; flex-shrink: 0;
}
.betroffen-betrag { font-variant-numeric: tabular-nums; }

/* Die Marke der Arbeitsfolge (db/158). Sie steht ganz vorn in der Zeile und
   soll dort erkennbar, aber nicht laut sein: sie ist eine Ordnungszahl, keine
   Meldung. Feste Breite waere hier falsch - R1 und R12 sollen beide eng
   sitzen, und die Zeile hat vorn ohnehin keine Spalte zu halten. */
.runde-marke {
  display: inline-block;
  padding: 0 .35em;
  margin-right: .15em;
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  font-variant-numeric: tabular-nums;
  font-size: .85em;
  color: var(--gedaempft);
  white-space: nowrap;
}

/* Der Sperrschirm bei ueberholter Fassung. Er liegt ueber allem, und das
   ist sein Zweck: die alte Fassung darf nicht weiterbenutzt werden. */
.fassungssperre {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center; padding: 1rem;
  background: var(--bg);
}
.fassungssperre .kachel { max-width: 26rem; width: 100%; }

/* Mittlere Kennzahl: zwei Zeilen statt einer.

   Fest sind Verträge — die kommen, ob man will oder nicht. Geplant ist,
   was man sich selbst vorgenommen hat, und das lässt sich verschieben.
   Deshalb das eine kräftig, das andere zurückgenommen. */
.kennwert.zweizeilig {
  display: grid; gap: .15rem; align-content: center;
}
.kennwert.zweizeilig > div {
  display: flex; align-items: baseline; justify-content: center; gap: .35rem;
}
.kennwert.zweizeilig span {
  font-size: .68rem; text-transform: uppercase; letter-spacing: .04em;
}
.kennwert.zweizeilig b { font-variant-numeric: tabular-nums; }
.zeile-fix span { color: var(--text); font-weight: 700; }
.zeile-fix b { color: var(--text); font-weight: 700; font-size: 1rem; }
.zeile-geplant span,
.zeile-geplant b { color: var(--gedaempft); font-weight: 500; font-size: .9rem; }

/* Das gemessene Wochenmuster. Sieben Balken, Höhe = Gewicht.
   1,0 heißt "durchschnittlicher Tag" — Ausreißer nach oben fallen auf. */
.wochenbalken {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: .3rem;
  margin: .6rem 0 .2rem; align-items: end;
}
.wotag { display: grid; justify-items: center; gap: .2rem; }
.wobalken {
  display: block; width: 100%; height: 3.2rem;
  display: flex; align-items: flex-end;
  background: var(--karte-innen); border-radius: 4px; overflow: hidden;
}
.wobalken i { display: block; width: 100%; background: var(--linie); }
.wotag.stark .wobalken i { background: var(--akzent); }
.wotag em { font-style: normal; font-size: .65rem; color: var(--gedaempft); }
.wotag b { font-size: .68rem; font-variant-numeric: tabular-nums; color: var(--gedaempft); }
.wotag.stark b { color: var(--akzent); }

/* ================================================== Bilanz je Wirtschaftsmonat

   Zwei Balken je Monat statt einem: grün, was hereinkam, rot, was hinausging,
   beide am selben Maßstab. Rückmeldung vom 21.08.: „umbenennen in Bilanz je
   wirtschaftsmonat mit zwei balken, übereinander grün für einnahmen und rot
   für ausgaben".

   Die Zeile ist ein zweispaltiges Raster (Monatsname · Bilanz), darunter ein
   eigenes dreispaltiges für das Balkenpaar — Beschriftung, Balken, Betrag.
   Getrennt, damit die Balken nicht an der Breite der Bilanzzahl hängen. */
.bilanzzeile { gap: .3rem .6rem; }
.bilanzzeile > b { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Der Betrag ist selbst der Knopf geworden (Rückmeldung 9111f7c8) und muss
   dabei aussehen wie das <b>, das er vorher war: gleiche Schrift, gleiches
   Gewicht, kein Rahmen, rechtsbündig. */
button.bil-summe {
  background: none; border: 0; padding: 0; margin: 0;
  font: inherit; font-weight: 700; cursor: pointer; text-align: right;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Ohne Gewicht in der Spezifität - sonst schlüge das geerbte Grau die Farben
   .gut und .schlecht, und jede Bilanz stünde wieder unbunt da. */
:where(button.bil-summe) { color: inherit; }
button.bil-summe:hover, button.bil-summe:focus-visible { text-decoration: underline; }
.bilanzzeile .balken-name em {
  font-style: normal; color: var(--gedaempft); font-size: .72rem;
}
.bil-paar {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: auto 1fr auto;
  align-items: center; gap: .2rem .5rem;
}
.bil-marke {
  font-size: .64rem; color: var(--gedaempft); text-transform: uppercase;
  letter-spacing: .05em; white-space: nowrap;
}
.bil-wert {
  font-size: .72rem; color: var(--gedaempft); text-align: right;
  font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: 500;
}
.bil-paar .balken { grid-column: auto; }
.balken i.ein { background: var(--gut); }
.balken i.aus { background: var(--schlecht); }
.mini.mitte { display: block; margin: .2rem auto 0; }

/* ==================================== Was auf 375 Pixeln nicht mehr hineinpasst

   Zwei Rückmeldungen vom 21.08., beide „am handy abgeschnitten": die
   Prognose-Kachel und die Tabelle „Plan gegen Ist". Beide Male hat die
   Gestaltung eine feste Breite angenommen, die es auf einem iPhone nicht gibt
   — ein Drittel von 375 Pixeln sind rund 105, und „PROGNOSE MONATSENDE" ist
   in Großbuchstaben breiter als das. */

/* Die Beschriftung einer Kennzahl brach nicht um, sondern endete in „…".
   Ein Wort, das mit Auslassungspunkten aufhört, sagt weniger als eines, das
   in die zweite Zeile geht — die Kacheln stehen ohnehin im Raster und wachsen
   gemeinsam mit. */
.kennwert span {
  white-space: normal; overflow: visible; text-overflow: clip;
  overflow-wrap: anywhere; hyphens: auto; line-height: 1.25;
}
/* Und die Zahl darüber darf schrumpfen, statt über den Rand zu laufen:
   „−12.345 €" passt bei 1,02 rem nicht in eine Drittelspalte. */
.kennwert b { font-size: clamp(.82rem, 3.4vw, 1.02rem); overflow-wrap: anywhere; }
.kennwert.zweizeilig b, .kennwert.zweizeilig span { overflow-wrap: normal; }

/* Der Zweizeiler daneben hat dasselbe Problem in klein: „Fix  −1.184 €" passte
   nicht, und das Eurozeichen rutschte allein in die nächste Zeile. Ein Betrag
   ist ein Wort — er bricht nicht um, er wird kleiner. */
.kennwert.zweizeilig b, .kennwert.zweizeilig span { white-space: nowrap; }
.kennwert.zweizeilig > div { gap: .3rem; justify-content: space-between; }
.zeile-fix b { font-size: clamp(.78rem, 3.1vw, 1rem); }
.zeile-geplant span, .zeile-geplant b { font-size: clamp(.7rem, 2.8vw, .9rem); }

@media (max-width: 480px) {
  /* Fünf Spalten (Kategorie, Plan, Ist, Abw., Knopf) auf rund 314 nutzbaren
     Pixeln. Gerechnet: drei Beträge à „-10.000,00" brauchen bei .72 rem je
     etwa 49 px, macht 147; dazu der Knopf und die Innenabstände — es bleiben
     rund 130 px für den Namen, also gut zwanzig Zeichen. Das reicht für
     „Versicherungen gesamt", ohne ein Wort zu zerschneiden: ein
     „Einkaufen/Lebe⏎n" ist schlimmer als eine enge Zeile. */
  th, td { padding: .42rem .14rem; font-size: .72rem; }
  th { font-size: .58rem; letter-spacing: .01em; }
  td:first-child { overflow-wrap: break-word; hyphens: auto; }
  th.tat, td.tat { padding-left: 0; padding-right: 0; }
  .mini.uebernehmen { font-size: .95rem; padding: .2rem .15rem; }
  /* Letzte Sicherung: sollte es trotzdem breiter geraten — etwa weil jemand
     die Schrift vergrößert —, rollt die Kachel seitlich, statt ihren Inhalt
     abzuschneiden. */
  .kachel { overflow-x: auto; }
}

/* Nachtrag zu einer Meldung: gehört sichtbar zum gemeldeten Text, ist aber
   nicht derselbe. Ein Strich links reicht dafür — der Text darüber bleibt,
   wie er gemeldet wurde. */
.anfrage-text.nachtrag {
  border-left: 2px solid var(--linie); padding-left: .6rem;
  color: var(--gedaempft); font-size: .84rem; white-space: normal;
}

/* Der Verlauf: Nachtraege und KI-Notizen zeitlich gemischt (10.09.2026).

   Eine gemeinsame Spur statt zweier Bloecke - wer die Zeile liest, soll den
   Wortwechsel sehen. Die Herkunft steckt deshalb in der Farbe der Kante und
   im Kopf, nicht in der Position: Position bedeutet hier ab jetzt Zeit. */
.verlauf { display: flex; flex-direction: column; gap: .5rem; margin: .5rem 0 .2rem; }
.verlauf-zeile { border-left: 2px solid var(--linie); padding-left: .6rem; }
.verlauf-zeile.v-ki { border-left-color: #6aa8ff; }
.verlauf-kopf {
  font-size: .68rem; letter-spacing: .03em; color: var(--gedaempft);
  font-variant-numeric: tabular-nums; margin-bottom: .1rem;
}
.verlauf-zeile.v-ki .verlauf-kopf { color: #6aa8ff; }
.verlauf-text { font-size: .84rem; color: var(--gedaempft); white-space: normal; }
.verlauf-zeile.v-ki .verlauf-text { color: #6aa8ff; }

/* Haken in „Plan gegen Ist". Das Label ist die Trefferfläche, nicht das
   Kästchen: ein Kästchen misst 16 px, ein Daumen braucht 44. Rückmeldung
   3fddda55 — der Pfeil davor war rund 14×20 px groß und hat außerdem sofort
   ausgeführt. */
.hakenfeld {
  display: flex; align-items: center; justify-content: center;
  min-width: 2.75rem; min-height: 2.75rem; cursor: pointer;
}
.hakenfeld input { width: 1.1rem; height: 1.1rem; accent-color: var(--akzent); }
#ueb-los[disabled] { opacity: .45; }

/* „Plan gegen Ist" ist jetzt gebaut wie die Bilanz — zwei Balken untereinander
   statt fünf Tabellenspalten (Rückmeldung 21fc9aea). Vorn der Haken, rechts die
   Abweichung; die Trefferfläche der Zeile bleibt bei 44 px, weil die Fläche
   selbst so hoch ist und nicht über die Nachbarzeile ragt. */
/* .balkenliste li setzt selbst schon grid-template-columns und ist mit zwei
   Selektoren spezifischer als .planzeile allein — ohne den Listenselektor davor
   greift die dritte Spalte nicht, und der Haken landet in der 1fr-Spalte
   (gemessen: 223 px breit statt 44). */
.balkenliste li.planzeile { grid-template-columns: auto 1fr auto; }
.planzeile > .balken-name { min-width: 0; overflow-wrap: break-word; align-self: center; }
.planzeile > b { align-self: center; }
/* Der Haken steht neben der ganzen Zeile, nicht nur neben ihrer ersten Reihe:
   sonst zwingen seine 44 px die Namenszeile auf 44 px hoch und die Zeile wird
   110 statt 70 px. So bleibt die Trefferfläche groß und die Liste kurz. */
.planzeile > .hakenfeld { grid-row: 1 / -1; align-self: stretch; }
.planzeile .leerhaken { pointer-events: none; }
.planliste li { padding: .15rem 0; }
.planliste li:active { background: var(--karte-innen); border-radius: var(--radius-klein); }
.balken i.plan { background: var(--linie); }
.alle-zeile {
  display: flex; align-items: center; gap: .1rem; cursor: pointer;
  font-size: .72rem; color: var(--gedaempft); text-transform: uppercase;
  letter-spacing: .06em; font-weight: 600; margin-top: .4rem;
}

/* Wichtigkeit: vier Gruppen, alle in derselben Farbe. Das ist keine
   Nachlässigkeit — Rückmeldung fac6bd5f wollte ausdrücklich „keine wertenden
   Farben etc.". Ein roter Balken für „Luxus" wäre genau das Urteil, das die
   Kachel nicht fällen soll. */
.balken i.wi { background: var(--linie); }
.balkenliste li.wi-zeile { grid-template-columns: 1fr auto; gap: .2rem .6rem; }
.wi-zeile > b { font-variant-numeric: tabular-nums; }
.wi-ziel {
  grid-column: 1 / -1; display: flex; align-items: center; gap: .5rem;
  margin: -.1rem 0 .5rem;
}
.wi-ziel > span {
  font-size: .64rem; color: var(--gedaempft); text-transform: uppercase;
  letter-spacing: .05em; white-space: nowrap;
}
.wi-ziel input { margin: 0; padding: .35rem .5rem; font-size: .85rem; max-width: 8rem; }

/* Wie viele Regeln in einer Gruppe stecken — nur wenn es mehr als zwei sind,
   sonst sagt die Zahl nichts, was man nicht sieht (Rückmeldung 13a6b9e7). */
.fund-anzahl {
  font-size: .68rem; color: var(--gedaempft); text-transform: uppercase;
  letter-spacing: .05em; font-weight: 600;
}
.fund-kopf { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }

/* Die Gruppe direkt in der Kategorienliste. Schmal und unter dem Namen, damit
   die Zeile nicht breiter wird als der Schirm. */
.kl-stufe { display: flex; align-items: center; gap: .4rem; margin-top: .35rem; }
.kl-stufe > span {
  font-size: .64rem; color: var(--gedaempft); text-transform: uppercase;
  letter-spacing: .05em; white-space: nowrap;
}
.kl-stufe select { margin: 0; padding: .3rem .4rem; font-size: .78rem; max-width: 12rem; }

/* Die Wichtigkeit auf der Kategorieseite steht wie ein Formularfeld, nicht wie
   ein Schalter — sie hat vier Zustände, keinen an/aus. */
.kat-wichtigkeit,
.kat-einteilung { margin-top: .9rem; }
.kat-wichtigkeit select,
.kat-einteilung select { margin-bottom: 0; }

/* Wie oft dasselbe auftrat. Steht vor der Meldung, damit eine
   Scanner-Nacht nicht wie vierzig Baustellen aussieht. */
.fehler-zahl { color: var(--akzent); font-variant-numeric: tabular-nums; margin-right: .15rem; }

/* Der Stand der eigenen Meldung. Nur zwei Faelle heben sich ab: erledigt
   und nicht weiterverfolgt - alles dazwischen ist Zwischenstand. */
.meinstand-geloest { color: var(--gut, var(--akzent)); }
.meinstand-verworfen { color: var(--gedaempft); text-decoration: line-through; }

/* Die Antwort steht unter der Meldung, durch eine Linie abgesetzt -
   sie gehoert zum Eintrag, ist aber nicht das, was der Melder schrieb. */
.meldung-antwort {
  margin: .45rem 0 0; padding-top: .4rem; border-top: 1px solid var(--linie);
  color: var(--gedaempft); font-size: .82rem; line-height: 1.45;
}
/* Zugeklappt, damit die eigene Liste die Meldeseite nicht erschlaegt. */
.meine-meldungen > summary { cursor: pointer; list-style: none; }
.meine-meldungen > summary::-webkit-details-marker { display: none; }
.meine-meldungen > summary::after {
  content: '⌄'; margin-left: auto; color: var(--gedaempft); font-size: 1.1rem;
}
.meine-meldungen[open] > summary::after { content: '⌃'; }

/* Die Sorte einer Aenderung. Fehler und Wunsch heben sich ab - das eine
   war kaputt, das andere hat jemand gewuenscht; alles Uebrige ist ruhig. */
.cl-marke {
  display: inline-block; padding: .05rem .4rem; border-radius: 999px;
  border: 1px solid var(--linie); font-size: .72rem; color: var(--gedaempft);
  white-space: nowrap;
}
.cl-marke.cl-fehler { color: var(--akzent); border-color: var(--akzent); }
.cl-marke.cl-wunsch { color: var(--akzent); }
.cl-sorten { display: flex; flex-wrap: wrap; gap: .3rem; margin: .1rem 0 .6rem; }
.feld.schmal { margin: .3rem 0 0; padding: .25rem .4rem; font-size: .8rem; }

/* Das Bild zu einer Meldung. Begrenzt in der Hoehe - ein Screenshot vom
   Handy ist sonst hoeher als die Karte, in der er steckt. */
.meldebild img {
  max-width: 100%; max-height: 22rem; border-radius: .5rem;
  border: 1px solid var(--linie); margin: .3rem 0;
}

/* Eine eigene Meldung in der eigenen Liste.
   Untereinander statt nebeneinander: nebeneinander blieben auf einem
   375er Schirm zehn Zeichen fuer den Text uebrig ("was heißt \"1..."),
   waehrend die Standmarke daneben die halbe Breite nahm. */
.meldungsliste { display: flex; flex-direction: column; }
.meine-meldung { padding: .7rem 0; border-top: 1px solid var(--linie); }
.meldungsliste > .meine-meldung:first-child { border-top: 0; }
.mm-kopf {
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  margin-bottom: .25rem;
}
.mm-datum { font-size: .76rem; color: var(--gedaempft); }
.mm-text { margin: 0; font-size: .88rem; line-height: 1.4; }
.bildwahl { margin: .7rem 0 .2rem; }
.bildwahl .erklaerung { margin-top: .3rem; }
.meldebild.klein img { max-height: 9rem; }

/* Der Haken sitzt neben der Karte, nicht darin: in einem <summary>
   klappt jeder Klick die Karte auf, auch der auf das Kaestchen. */
.melde-reihe { display: flex; align-items: flex-start; gap: .45rem; }
.melde-reihe > details { flex: 1; min-width: 0; }
.rm-wahl { margin-top: .9rem; flex: none; }
.rm-leiste { flex-wrap: wrap; position: sticky; top: 0; z-index: 3;
  background: var(--karte); padding: .4rem; border-radius: .5rem; }
.meldegruppe.g-warten > summary { color: var(--gedaempft); }

/* Die Vertraulichkeitserklaerung im Anmeldeformular. Abgesetzt, damit
   der Haken nicht wie ein weiteres Eingabefeld aussieht. */
.nda {
  margin: .7rem 0; padding: .6rem; border: 1px solid var(--linie);
  border-radius: .5rem; background: var(--karte-innen);
}
.nda-text .warum-inhalt { max-height: 16rem; overflow-y: auto; }
.nda .schalter { margin-top: .5rem; }

/* Ob die Vertraulichkeit bestaetigt wurde. Fehlt sie, faellt es auf -
   freigeben sollte man so einen Zugang naemlich nicht. */
.nda-ja { color: var(--gedaempft); }
.nda-nein { color: var(--akzent); font-weight: 600; }

/* Plan gegen Ist ohne Balken: Name und Abweichung oben, die beiden
   Zahlen darunter im Klartext. Zwei Zeilen passen auf jeden Schirm,
   fuenf Spalten passten auf keinen. */
.planzeile {
  display: flex; align-items: center; gap: .5rem; padding: .45rem 0;
  border-bottom: 1px solid var(--linie);
}
.plan-wer { flex: 1; min-width: 0; }
.plan-name { display: block; font-size: .9rem; }
.plan-zahlen { font-size: .76rem; color: var(--gedaempft); margin-top: .1rem; }
.planzeile > b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.zeitraum-knoepfe {
  display: flex; flex-wrap: wrap; gap: .4rem; margin: .6rem 0 .2rem;
}
.zeitraum-knoepfe button { flex: 1 1 auto; }

/* Angaben, die nur manche Betreiber brauchen. Die Bezeichnung davor,
   damit "DE123456789" nicht ohne Zusammenhang dasteht. */
.imp-weitere { margin-top: .5rem; font-size: .86rem; }
.imp-was { color: var(--gedaempft); }

/* Bleibt unten stehen: die Haken liegen ueber die ganze Seite verteilt,
   und wer oben etwas anhakt, soll nicht ans Ende blaettern muessen. */
.cl-speicherleiste {
  position: sticky; bottom: .6rem; z-index: 4; margin-top: .8rem;
}
/* Ungespeichert geändert. Ohne Rahmen muss der Punkt es tragen - er wird
   voll statt hohl und nimmt die Akzentfarbe an. */
.cl-eintrag.geaendert::before { content: '◉'; color: var(--akzent); }

/* Aus dem Namen in der Balkenliste ist ein Knopf geworden - er oeffnet
   die Herleitung. Aussehen soll er wie vorher der Verweis, nicht wie ein
   Systemknopf. */
button.balken-name {
  background: none; border: 0; padding: 0; margin: 0; font: inherit;
  color: inherit; text-align: left; cursor: pointer;
}
button.balken-name:active { color: var(--akzent); }


/* Beige fuer "unwichtig" - Einstufung und ungelesene Meldungen
   ============================================================
   Die Einstufung darf ein Ticket nie verlieren, und man muss sie ueberall
   sehen: wichtig = rote Linie, normal = nichts, unwichtig = beige Linie an
   derselben Stelle und in derselben Breite - lauter darf sie nicht sein.

   Reines #F5F5DC ist auf beiden Untergruenden zu schwach - hell verschwindet
   es im Weiss, dunkel liest es sich als Grau. Also ein kraeftigerer Ton
   derselben Familie, je Schema ein eigener.

   Alle vier Faelle stehen hier zusammen. Die uebrigen Farbvariablen der Datei
   stehen fuenfmal verteilt, und genau daran ist schon eine Farbe im hellen
   Schema haengengeblieben. */
:root {
  --unwichtig: #efd98a;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --unwichtig: #b08d1c;
  }
}
html[data-theme="light"] {
  --unwichtig: #b08d1c;
}
html[data-theme="dark"] {
  --unwichtig: #efd98a;
}

/* Ungelesen wie eine Mail: fett, solange kein Mensch etwas damit gemacht
   hat. Sobald eingestuft, abgelegt oder abgehakt wird, faellt die Schrift auf
   normal zurueck - das ersetzt die frueher eigene Stufe "unsortiert". */
.anfrage.ungesehen > summary .anfrage-name { font-weight: 800; }
.anfrage.ungesehen > summary .anfrage-mail { font-weight: 600; color: var(--text); }
.anfrage.ungesehen .anfrage-text { font-weight: 600; }


/* ==========================================================================
   Cluster 6a - Darstellung und Lesbarkeit auf der Uebersicht (28.08.2026)
   ========================================================================== */

/* Ein <button> ohne eigene Farbe erbt nicht, er faellt auf die Systemfarbe
   zurueck: Schwarz. Im dunklen Schema stand die Einsparpotenzial-Kachel
   dadurch schwarz auf schwarz (Rueckmeldung ef2e34b3), und dieselbe Falle
   wartete auf jeden kuenftigen Knopf. :where() gibt der Regel das Gewicht
   null - jede vorhandene Farbe schlaegt sie weiterhin, auch .gut/.schlecht.
   Dasselbe Mittel wie bei button.bil-summe weiter oben. */
:where(button) { color: inherit; }

/* Der Monatsblock und der Schalter stehen als Paar rechts. Bisher trug
   .marke-monat das margin-left:auto - die Gruppe wird aber ausgeblendet, wo
   es keine Monatsnavigation gibt, und der Schalter waere mitgewandert. */
.kopf-rechts { margin-left: auto; display: flex; align-items: center; gap: .15rem; }
.marke-monat { margin-left: 0; }

.schemaecke { position: relative; flex: none; }
.schema-knopf { font-size: 1rem; }
.schema-liste {
  position: absolute; top: calc(100% + .4rem); right: 0; z-index: 40;
  display: flex; flex-direction: column; min-width: 8.5rem;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-klein); padding: .25rem;
  box-shadow: 0 12px 32px -14px rgba(0, 0, 0, .6);
}
.schema-liste button {
  display: flex; align-items: center; gap: .5rem; width: 100%;
  padding: .45rem .5rem; border: 0; border-radius: 8px; cursor: pointer;
  background: none; color: var(--text); font: inherit; font-size: .85rem;
  text-align: left;
}
.schema-liste button > span { width: 1.1rem; text-align: center; color: var(--gedaempft); }
.schema-liste button > em { font-style: normal; }
.schema-liste button:active { background: var(--karte-innen); }
.schema-liste button.aktiv { background: var(--akzent-schwach); color: var(--akzent); }
.schema-liste button.aktiv > span { color: var(--akzent); }

/* Faellig ist eine Tatsache, der Plan eine Absicht - im selben Grau waren sie
   nicht auseinanderzuhalten (Rueckmeldung 2dca2d6c). var(--text) heisst im
   hellen Schema schwarz und im dunklen weiss; der Nachtrag ist damit
   miterledigt. Die Ampelfarben (.knapp/.ueberzogen) gibt es in der Vorschau
   nicht, sie koennen hier also nicht ueberschrieben werden. */
.zeilen li.gruppenkopf b.faellig { color: var(--text); }

/* Klappbare Kategorien (Rueckmeldung 101fe193). Der Pfeil steht vor dem
   Namen, weil dort das Auge die Zeile anfaengt zu lesen. */
.zeilen li.gruppenkopf.klappbar { cursor: pointer; }
.zeilen li.gruppenkopf.klappbar:active { background: var(--karte-innen); }
.klapp-pfeil {
  font-style: normal; display: inline-block; width: .75rem; margin-right: .15rem;
  color: var(--gedaempft); transition: transform .15s ease;
}
.zeilen li.gruppenkopf.offen .klapp-pfeil { transform: rotate(90deg); }

/* Zugeklappte Rubriken auf den Listenseiten: "Abgelaufen", "Gelöscht" und
   das Löschen der eigenen Daten (Rückmeldungen bf936b1f, f460f908, 81418e3e).
   Dieselbe Mechanik wie bei .warum, nur als ganze Kachel - der Pfeil steht
   rechts, weil die Zeile links mit dem Namen anfängt. */
details.rubrik > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: baseline; gap: .4rem;
}
details.rubrik > summary::-webkit-details-marker { display: none; }
details.rubrik > summary::after {
  content: '⌄'; margin-left: auto; color: var(--gedaempft);
}
details.rubrik[open] > summary::after { content: '⌃'; }
details.rubrik > :not(summary) { margin-top: .6rem; }

/* Der Kopf einer Vertragsgruppe. Kein .gruppenkopf: der gehört der Übersicht
   und bringt dort Ampelfarben und Klappwerk mit. */
.vertragsgruppe {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .5rem; padding: .9rem .1rem .1rem;
  color: var(--gedaempft); font-size: .72rem; letter-spacing: .08em;
  text-transform: uppercase;
}
.vertragsgruppe b { color: var(--text); font-variant-numeric: tabular-nums; }

/* Ein kleiner Knopf, hinter dem etwas endgültig verschwindet. Dieselbe Farbe
   wie .sekundaer.gefahr - und wie dort steht die Farbe hier ausdrücklich,
   weil ein <button> ohne eigene Schriftfarbe im dunklen Schema schwarz
   bliebe (siehe :where(button) am Ende dieser Datei). */
.mini.gefahr { color: var(--schlecht); }
.mini.gefahr:active {
  background: color-mix(in srgb, var(--schlecht) 12%, transparent);
}

/* Der Haushalt hinter einer Meldung ist gelöscht, der Name steht noch da
   (db/090, Rückmeldung deb106e7). Gedämpft, weil es eine Fußnote zum Namen
   ist und keine zweite Angabe. */
.weg-marke { font-style: normal; color: var(--gedaempft); }

/* Kategorienschritt der Führung (Rückmeldung 63f7d52b).

   Der Haken sitzt in einem eigenen Label, damit die Stufenauswahl daneben
   die Kategorie nicht mit abwählt. Abgewähltes bleibt sichtbar stehen und
   wird blass – es verschwindet erst beim Weitergehen, und bis dahin soll
   man sehen, was man weggeklickt hat. */
.kat-wahl { display: flex; align-items: center; gap: .6rem; }
/* Aus dem Label ist ein Knopf geworden: der Name klappt die Kategorie auf,
   der Haken links waehlt sie ab. Zwei Griffe, zwei Flaechen. */
.kat-wahl-name {
  display: flex; align-items: center; gap: .4rem; flex: 1; min-width: 0;
  cursor: pointer; background: none; border: 0; padding: .35rem 0;
  color: inherit; font: inherit; text-align: left;
}
.kat-wahl-name .klapp-pfeil {
  font-style: normal; color: var(--gedaempft); transition: transform .12s;
}
.kat-wahl-name.offen .klapp-pfeil { transform: rotate(90deg); }
.kat-wahl-name:active { opacity: .6; }
.kat-wahl input[type="checkbox"] {
  width: 1.15rem; height: 1.15rem; accent-color: var(--akzent); flex: none;
}
.kat-wahl .name {
  min-width: 0; overflow-wrap: anywhere;
  white-space: normal; overflow: visible; text-overflow: clip;
}
.kat-wahl select { flex: none; max-width: 7.5rem; }
.kat-wahl.raus { opacity: .45; }
.kat-wahl.raus .name { text-decoration: line-through; }

/* Die Stufenkunde darüber: vier Zeilen, jede mit ihrem Namen vorn. */
.stufenkunde b { font-weight: 650; }

/* Eine Chipleiste, die nicht filtert, sondern auswählen lässt: sie darf
   nicht seitlich weglaufen, sondern bricht um. */
.chips.umbrechend { flex-wrap: wrap; overflow-x: visible; }

/* Die Sortierreihe steht in der Kennzahlenliste, ist aber keine Datenzeile:
   kein space-between, keine Trennlinie - sonst liest sie sich wie ein
   Posten mit fehlendem Betrag. */
/* Titel der Kategorienliste links, Sortierwahl rechts - eine Zeile fuer
   beides. War bis zum 03.09.2026 eine Zeile fuer nur den Knopf. */
.zeilen li.sortierzeile {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; border: 0; padding: .35rem 0 .1rem; min-width: 0;
}
.listentitel {
  font-size: .72rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--gedaempft);
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.zeilen li.sortierzeile .chips { margin: 0; }

/* Betriebsrubriken im Panel (Rückmeldungen 6235eb60, 7d9fe0df).

   Fünf Zeilen im Stil einer Liste: Name links, Zahl rechts, und ein Tipp
   klappt auf, was dahintersteckt. Jede Zeile hat eine Liste – die
   Ausnahme („Plätze insgesamt", ohne Pfeil) gab es einen Tag lang und ist
   wieder weg, mit ihr die Regeln für `.fest`. */
.betriebsrubriken { margin-top: .4rem; }
.betriebszeile { border-top: 1px solid var(--linie); }
.betriebsrubriken > :first-child { border-top: 0; }

.betriebszeile > summary {
  display: flex; align-items: baseline; gap: .6rem;
  padding: .6rem .1rem; list-style: none; cursor: pointer;
}
.betriebszeile > summary::-webkit-details-marker { display: none; }
.betriebszeile > summary > b {
  margin-left: auto; font-variant-numeric: tabular-nums; color: var(--text);
}
.betriebszeile > summary::after {
  content: '⌄'; color: var(--gedaempft); width: .9rem; text-align: right;
}
.betriebszeile[open] > summary::after { content: '⌃'; }
.betriebszeile > summary > span { color: var(--gedaempft); }

.betriebsinhalt { padding: .2rem 0 .8rem; }
/* Die Kennung eines Haushalts, dessen Name abgelaufen ist. */
.kennung { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--gedaempft); }

/* Die Überschrift eines Changelog-Eintrags ist für den Betreiber zugleich
   der Weg, sie zu ändern (Rückmeldung aca93410). Kein Knopf-Aussehen: sie
   soll eine Überschrift bleiben und nur zeigen, dass sie anfassbar ist. */
.cl-titel.aenderbar { cursor: pointer; }
.cl-titel.aenderbar:hover { text-decoration: underline dotted; text-underline-offset: .2em; }
.cl-titel.aenderbar:active { opacity: .7; }

/* Die vier Zahlen auf der Kategorieseite, jede mit ihrem Übernehmen-Knopf
   (Rückmeldung 00fb9107). `.zeilen li` ist Flex mit space-between: bei drei
   Kindern schwämme der Betrag in der Mitte, deshalb hier ein Raster mit
   fester Spalte für den Knopf. */
.zeilen li.kostenzeile {
  display: grid; grid-template-columns: 1fr auto auto; gap: .5rem;
  align-items: baseline;
}
.zeilen li.kostenzeile > b { font-variant-numeric: tabular-nums; }
.zeilen li.kostenzeile.gilt > b { color: var(--akzent); }
.zeilen li.kostenzeile em {
  font-style: normal; color: var(--gedaempft); font-size: .72rem;
}

/* ------------------------------------------ Sortierung rechts (02.09.2026)

   Fuenf Chips nebeneinander brauchten 385 px. `ul.zeilen` ist ein Grid mit
   einer Spalte, also zogen sie die Spalte auf 366 px - und jede
   Kategorienzeile darunter mit aus der 309,6 px breiten Kachel hinaus
   (cdc99208). Zwei Dinge halten das jetzt fest: der Knopf ist klein, und
   `min-width: 0` verbietet der Zeile, die Spalte ueberhaupt aufzuziehen. */
.zeilen li.sortierzeile { min-width: 0; }
.sortierleiste { display: flex; justify-content: flex-end; min-width: 0; }

.sortierwahl { min-width: 0; }
.sortier-knopf {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .22rem .55rem; border-radius: 999px;
  border: 1px solid var(--linie); background: var(--karte);
  color: var(--gedaempft); font-size: .72rem; white-space: nowrap;
}
.sortier-knopf::-webkit-details-marker { display: none; }
.sortier-knopf::after { content: '⌄'; font-size: .85em; line-height: 1; }
.sortierwahl[open] > .sortier-knopf { color: var(--akzent); border-color: var(--akzent); }
.sortierwahl[open] > .sortier-knopf::after { content: '⌃'; }

/* Im Fluss, nicht darueber: `.kachel` rollt unter 480 px seitlich und wuerde
   ein absolut gesetztes Menue abschneiden. */
.sortier-menue {
  display: grid; justify-items: stretch; margin-top: .35rem; padding: .25rem;
  border: 1px solid var(--linie); border-radius: .7rem; background: var(--karte-innen);
}
.sortier-eintrag {
  text-align: right; padding: .42rem .6rem; border: 0; border-radius: .5rem;
  background: none; color: var(--text); font-size: .82rem;
  cursor: pointer; white-space: nowrap;
}
.sortier-eintrag.aktiv { color: var(--akzent); font-weight: 650; }
.sortier-eintrag.standard {
  border-top: 1px solid var(--linie); border-radius: 0;
  margin-top: .25rem; padding-top: .5rem;
  color: var(--gedaempft); font-size: .74rem;
}

/* ------------------------- Rubriken in "Was diesen Monat noch abgeht" (02.09.)

   Vorher: `<p class="label">` als Ueberschrift, darunter alles offen, dahinter
   ein Erklaerabsatz. Frank wollte die Unterteilungen erkennbarer und
   aufklappbar, zugeklappt als Vorgabe - und die Summe in der Ueberschrift,
   damit eine zugeklappte Rubrik trotzdem etwas sagt. */
details.rubrik.ver-rubrik > summary {
  padding: .6rem 0; border-top: 1px solid var(--linie);
}
details.rubrik.ver-rubrik:first-of-type > summary { border-top: 0; padding-top: .1rem; }
/* (ersetzt durch die Rasterregel weiter unten) */
.rubrik-name {
  font-size: .8rem; font-weight: 700; color: var(--text);
  text-transform: uppercase; letter-spacing: .04em;
}


/* Ein zu langer Name kuerzt sich - er zieht die Zeile nicht auf.
   Warum `min-width: 0` am Kind dafuer nicht reicht, steht ausfuehrlich im
   Patch vom 02.09.2026; kurz: die min-content-Breite der Zeile kommt aus dem
   ungebrochenen Text, und als Grid-Element reicht die Zeile sie an die Spalte
   weiter. Gemessen: 314 px Zeile in einer 308,8 px breiten Kachel. */
.zeilen > li { min-width: 0; }
.balkenliste > li { min-width: 0; }

/* Drei Spalten fuer die ganze Rubrik - Ueberschrift wie Zeile.

   Name | Betrag | Pfeil bzw. Knopf. Damit steht die Summe der Rubrik genau
   ueber den Betraegen, die sie zusammenzaehlt, und die Zeilen mit einem
   Knopf verrutschen nicht gegen die ohne (Frank, 02.09.2026: "der betrag
   schoen untereinander buendig"). */
details.rubrik.ver-rubrik > summary,
details.rubrik.ver-rubrik .zeilen > li {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 1.6rem;
  align-items: baseline; gap: .5rem;
}
details.rubrik.ver-rubrik > summary > .rubrik-name,
details.rubrik.ver-rubrik .zeilen > li > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
details.rubrik.ver-rubrik > summary > .rubrik-summe,
details.rubrik.ver-rubrik .zeilen > li > b {
  justify-self: end; white-space: nowrap; font-variant-numeric: tabular-nums;
}
details.rubrik.ver-rubrik > summary > .rubrik-summe { font-size: .85rem; font-weight: 700; }
/* Der Pfeil sitzt in der dritten Spalte, nicht mehr am Ende des Textes -
   sonst schoebe er den Betrag aus der Flucht.

   `grid-column: 3` ist noetig, nicht bequem (Rueckmeldung d9b7df14,
   04.09.2026: "unschoen.... immer untereinander"). "Gestrichen" ist die
   einzige Rubrik OHNE Summe. Ohne das `<b>` daneben ist der Pfeil das
   zweite Rasterelement und landet damit in der Betragsspalte - rund 2 rem
   weiter links als die vier Pfeile darueber. Festgenagelt steht er immer in
   derselben Flucht, egal ob eine Summe daneben steht. */
details.rubrik.ver-rubrik > summary::after {
  grid-column: 3; justify-self: end; margin-left: 0;
}
details.rubrik.ver-rubrik .zeilen > li > .haken-buchen {
  justify-self: end; margin-left: 0;
}

/* Eine echte Buchung in der aufgeklappten Kategorie: durchgestrichen, kursiv
   und heller - "sodass man sieht vorbei gewesen" (Frank, 02.09.2026). Sie ist
   die Herleitung der Ist-Zahl am Kopf; was danach kommt, steht daneben in
   normaler Schrift und hat einen Griff.

   Der Strich liegt auf Name und Betrag, nicht auf der ganzen Zeile: ueber
   einen Zeilenabstand hinweg gezogen sieht er aus wie ein Trennstrich. */
.zeilen li.unterposten.gebucht { cursor: default; font-style: italic; }
.zeilen li.unterposten.gebucht > span,
.zeilen li.unterposten.gebucht > b {
  color: var(--gedaempft); font-weight: 500; text-decoration: line-through;
}
.zeilen li.unterposten.gebucht > span .datum { color: var(--gedaempft); }

/* Eine Summe, die Vergangenes zaehlt, traegt keine Warnfarbe. */
details.rubrik.ver-rubrik > summary > .rubrik-summe.vorbei { color: var(--gedaempft); }

/* "Wer traegt was" (02.09.2026). Name links, Rolle daneben, der Prozentsatz
   ganz rechts und schmal - er traegt hoechstens "100". Auf dem Telefon
   faellt die Rolle unter den Namen, sonst bleibt fuer keines der drei Platz. */
/* EINE Spalte fuer alle Bedienelemente des Bedarfsblocks.

   Frank, 05.09.2026: "mach es immer untereinander... das hab ich schon mal
   als grundregel formuliert... wenn es eine tabelle oder der art ist muss
   es buendig sein". Vorher war die rechte Spalte `auto` - jede Zeile war
   so breit wie ihr eigener Inhalt, und das neue Feld bei "Aufteilung" lief
   ueber die ganze Zeile, waehrend die Auswahlen darueber rechts standen.

   Deshalb eine feste Breite als Variable statt `auto`: die Auswahlen und
   das Zahlenfeld beginnen an derselben Kante, egal wie lang die
   Beschriftung links ist. Die dritte Spalte gehoert dem Zeichen hinter dem
   Feld; die Auswahlen nehmen sie mit, hinter ihnen steht ja nichts. */
:root { --bedarf-steuer: 11rem; }

.zeilen li.bedarfszeile,
.aufteilung-kopf {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--bedarf-steuer) 1.9rem;
  align-items: center; gap: .5rem; min-width: 0;
}
.zeilen li.bedarfszeile > .feld { grid-column: 2 / -1; width: 100%; }
.aufteilung-kopf > .aufteilung-summe { grid-column: 2; width: 100%; }

/* Der Rueckweg: rund, in der dritten Spalte, sonst so unauffaellig wie das
   X in der Dialogecke - er wird selten gebraucht und darf nichts anziehen. */
.bedarf-zurueck {
  grid-column: 3; justify-self: end; align-self: center;
  /* `grid` mit `place-items` statt `line-height`: das Zeichen sitzt sonst
     oben im Kreis, weil ein 1-rem-Glyph in einem 1,8-rem-Kasten von selbst
     an der Schriftlinie klebt. Frank, 05.09.2026: "mittig von der höhe". */
  display: grid; place-items: center;
  width: 1.8rem; height: 1.8rem; border-radius: 50%; padding: 0;
  border: 1px solid var(--linie); background: var(--karte-innen);
  color: var(--gedaempft); font-size: 1rem; line-height: 1; cursor: pointer;
  font-family: inherit;
}
.bedarf-zurueck:active { color: var(--akzent); border-color: var(--akzent); }
.zeilen li.bedarfszeile > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.zeilen li.bedarfszeile .feld { margin: 0; padding: .35rem .5rem; font-size: .82rem; }
.anteilsfeld { text-align: right; }
.bedarfsliste { gap: .55rem; }
.bedarf-rechnung { margin-top: .9rem; }
#bedarf-summe { margin: .6rem 0 .5rem; }
#bedarf-summe.warnung { color: var(--schlecht); }

/* Auf dem Telefon reicht die Breite nicht fuer Name UND Feld nebeneinander:
   die Beschriftung nimmt die ganze Zeile, das Bedienelement steht darunter -
   weiterhin alles untereinander und buendig, nur eine Zeile tiefer. */
/* Auf dem Telefon mindestens 16 px - sonst zoomt iOS beim Hineintippen.

   Rueckmeldung 1bceeefd: "wenn man den betrag eintraegt verschiebt sich die
   optik. wenn man hier ins textfeld rein klickt wird der bug behoben, sollte
   kein workaround sein". Der zweite Satz nennt den Beweis gleich mit: Safari
   vergroessert die Seite, sobald ein Feld mit einer Schrift UNTER 16 px den
   Fokus bekommt - und zoomt nicht von selbst zurueck. Das normale .feld steht
   auf 1 rem = 16 px und loest es deshalb nicht aus; im Bedarfsblock waren die
   Felder auf .82 rem heruntergesetzt (13,1 px), das neue Zahlenfeld erbte
   14,4 px. Ergebnis: die Seite stand vergroessert da, rechts abgeschnitten.

   Nur fuer schmale Schirme - am Rechner duerfen die Felder klein bleiben,
   dort zoomt niemand. Beide bekommen denselben Wert, damit sie untereinander
   gleich gross bleiben. */
@media (max-width: 560px) {
  .zeilen li.bedarfszeile .feld,
  .aufteilung-summe { font-size: 16px; }
}

@media (max-width: 420px) {
  .zeilen li.bedarfszeile,
  .aufteilung-kopf {
    grid-template-columns: minmax(0, 1fr) 1.9rem;
  }
  .zeilen li.bedarfszeile > span,
  .aufteilung-kopf > span { grid-column: 1 / -1; }
  .zeilen li.bedarfszeile > .feld { grid-column: 1 / -1; }
  .aufteilung-kopf > .aufteilung-summe { grid-column: 1; }
}

/* Ein Regler je Gehalt (02.09.2026).

   Frank: "die prozent lassen sich richtig bescheiden eingeben... wie waere es
   mit einem schieberegler?"

   Name links, Prozent und Betrag rechts, der Regler ueber die ganze Breite
   darunter - genauso wie `.gruppenbalken` unter dem Kategoriekopf steht. Ein
   Regler, der sich die Zeile mit drei anderen Dingen teilt, ist auf einem
   Telefon nicht zu treffen. */
.zeilen li.reglerzeile {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline; gap: .2rem .6rem; min-width: 0;
}
.zeilen li.reglerzeile > span {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.regler-prozent { font-variant-numeric: tabular-nums; color: var(--akzent); }
.regler-euro {
  font-variant-numeric: tabular-nums; color: var(--gedaempft);
  font-weight: 500; font-size: .82rem;
}
.zeilen li.reglerzeile > input[type="range"] {
  grid-column: 1 / -1; width: 100%; margin: 0;
  accent-color: var(--akzent);
  /* 44 px Trefferflaeche - gemessen waren es vorher 22. Die Bahn selbst
     bleibt duenn, der Kasten darum traegt den Daumen. */
  height: 2.75rem; padding: 0; touch-action: none;
}

.gewichtung { margin-top: 1rem; }
.gewichtung[hidden] { display: none; }
.vorschlagszeile { color: var(--akzent); margin: .2rem 0 .6rem; }
/* Beide Knoepfe in einer Reihe: gleiche Hoehe, keine Einzelregel mehr. */
.reglerknoepfe .mini { line-height: 1.25; }

/* Der eine Regler fuer zwei Gehaelter. Er steht unter beiden Zeilen, nicht in
   einer davon: er gehoert ja beiden. Dieselbe Trefferflaeche wie die
   Einzelregler - 44 px, gemessen. */
#paarregler {
  display: block; width: 100%; margin: .2rem 0 .1rem;
  accent-color: var(--akzent); height: 2.75rem; padding: 0; touch-action: none;
}
#paarregler[hidden], .einzelregler[hidden] { display: none; }

/* Ein Monat in der Auswertung. Dieselbe Klappe wie die Rubriken in "Was
   diesen Monat noch abgeht" - eine Sorte Klappe in der App -, nur eine
   Stufe eingerueckt, weil sie in einer Rubrik steht. */
details.rubrik.ver-rubrik.monatsklappe { padding-left: .5rem; }
.monatsposten { margin-top: .4rem; margin-bottom: .6rem; }
.monatsposten .mini.breit { width: 100%; margin-top: .5rem; }

/* Was hinter einer Kategorie steckt, wenn man sie antippt. */
.kat-detail {
  padding: .1rem 0 .6rem 1.75rem; border-bottom: 1px solid var(--linie);
}
.kat-detail[hidden] { display: none; }
.kat-detail .hinweis-klein { margin: .3rem 0 0; }

/* Zwei Knoepfe nebeneinander unter den Reglern: der faire Vorschlag und
   die gleichmaessige Teilung. Sie brechen um, statt hinauszulaufen. */
.reglerknoepfe { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .5rem; }
/* Dieselbe Form wie der Sortierknopf: runder Rand, Kartenfarbe. Ein blosses
   .mini ist ein Textknopf ohne Rand - unter den Reglern hat ihn niemand als
   Knopf erkannt. */
.reglerknoepfe .mini {
  border: 1px solid var(--linie); background: var(--karte);
  border-radius: 999px; padding: .4rem .8rem; color: var(--text);
  font-weight: 550;
}
.reglerknoepfe .mini:active {
  background: var(--akzent-schwach); color: var(--akzent);
  border-color: var(--akzent);
}

/* Ein Termin, dessen Tag da ist, sieht erledigt aus (03.09.2026).

   Frank: "vertraege und plane sind doch schon abgezogen... es soll dann
   nur gruen eingefaerbt werden und bei der Katliste als erledigt
   markiert werden."

   Der Strich liegt auf Name und Betrag, das Datum bleibt gruen und fett.
   Damit ist er von einer echten Buchung zu unterscheiden: die ist kursiv
   und hat ein graues Datum. Gruen = der Tag ist da, grau = das Konto hat
   es bestaetigt. Pfeil und Haken bleiben - man kann den Termin weiter
   abhaken oder aussetzen. */
.zeilen li.unterposten.erreicht > span,
.zeilen li.unterposten.erreicht > b { text-decoration: line-through; }
.zeilen li.unterposten.erreicht > span .datum { text-decoration: none; }

/* Die Kopfzeile der Aufteilung: Titel links, die 100 Prozent rechts in
   Rot (Frank, 03.09.2026). Sie steht ueber den beiden Anteilen und ist
   ihre Summe - deshalb dieselbe Flucht wie deren Betraege. */
/* Das Raster fuer diese Zeile steht weiter oben, bei .bedarfszeile - beide
   muessen dieselben Spalten haben, sonst steht nichts buendig. Hier stand
   bis zum 05.09.2026 ein eigenes `display: flex`, und weil es SPAETER kam,
   hat es das Raster stillschweigend ueberstimmt: gemessen begann das Feld
   bei 119 px, die Auswahlen darueber bei 393. */
/* Die Grundlage der Aufteilung ist ein FELD, kein Knopf (2ce1b721).

   Drei Anlaeufe hat das gebraucht, und die ersten beiden waren zu schlau:
   erst eine Zahl mit gepunkteter Unterstreichung ("man erkennt nicht das
   man es anklicken kann"), dann ein Knopf mit rundem Rahmen. Frank hat
   dann ein Bild der Rollenauswahl geschickt: "mach es so ..genauso senk
   den Bedarf.. da moechte ich die 5600 drin sehen... ein normales feld".

   Damit traegt `.feld` das Aussehen - Rand, Hintergrund, Radius, alles wie
   bei jedem anderen Eingabefeld der App - und hier steht nur, was diesem
   einen eigen ist: schmal, rechtsbuendig, rot und fett wie die Zahl, die es
   vorher war. Zwei Sorten Eingabefeld waeren eine zu viel.

   Die Breite ist gesetzt, weil ein Feld sonst die ganze Zeile nimmt und die
   Ueberschrift "AUFTEILUNG" an den Rand quetscht. */
.aufteilung-summe {
  /* `margin: 0` ist der Punkt, an dem der Kreis daneben haengt: .feld bringt
     einen Aussenabstand nach unten mit, damit wird das Feld im Raster hoeher
     als die Zeile, rutscht an deren Oberkante - und der Kreis, der brav
     mittig steht, sitzt dann tiefer als das Feld. Gemessen: Feldmitte 63,
     Kreismitte 67. Dieselbe Zeile steht aus demselben Grund schon bei
     .bedarfszeile .feld. */
  margin: 0;
  padding: .35rem .5rem; font-size: .82rem;
  text-align: right; color: var(--schlecht);
  font-variant-numeric: tabular-nums;
  font-size: .9rem; font-weight: 700; text-transform: none;
  letter-spacing: 0;
}
/* Auf dem Telefon mindestens 16 px - sonst zoomt iOS beim Hineintippen und
   zoomt nicht von selbst zurueck (1bceeefd). Steht hier UNTEN und nicht oben
   bei den anderen schmalen Regeln: dort kam sie vor .aufteilung-summe und
   wurde von deren .82 rem wieder ueberstimmt - gemessen 14,4 px statt 16. */
@media (max-width: 560px) {
  .aufteilung-summe { font-size: 16px; }
}

/* Die Pfeilchen des Zahlenfeldes nehmen Platz und laden zum Klicken ein,
   obwohl niemand den Bedarf in Einerschritten hochtippt. */
.aufteilung-summe::-webkit-outer-spin-button,
.aufteilung-summe::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.aufteilung-summe { -moz-appearance: textfield; appearance: textfield; }


/* -------------------------------------------------------------------
   Einstellungen: Bloecke statt einer flachen Liste  (03.09.2026)
   ------------------------------------------------------------------- */

/* Die Zahl am rechten Rand einer Einstellungszeile ("23 Vertraege").
   .reihe ist Flex mit space-between und .wer traegt flex:1 - die Zahl und
   der Pfeil ruecken damit von selbst zusammen nach rechts. Tabellenziffern,
   damit die Zahlen untereinander in einer Flucht stehen. */
.ein-zahl {
  flex: none; font-size: .85rem; font-weight: 600; color: var(--gedaempft);
  font-variant-numeric: tabular-nums;
}

/* Ein Knopf, der nicht zur Liste darueber gehoert - Abmelden unter den
   Haushaltszeilen. Die Linie ist der ganze Punkt: ohne sie liest man ihn
   als sechste Zeile und trifft ihn irgendwann versehentlich.

   Die Klasse sitzt auf einer HUELLE, nicht auf dem Knopf. Seit dem
   Randblock traegt jeder Knopf ringsum einen Rand; ein border-top auf dem
   Knopf selbst faerbt nur dessen eigene Kante um - man sieht nichts. */
.abgesetzt {
  margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--linie);
}

/* Der Knopf hat es getan. Zwei Sekunden markiert, dann wieder normal -
   lang genug zum Lesen, kurz genug, um nicht als Zustand zu gelten.

   Der Ausschluss ist der ganze Punkt: ein gefuellter Knopf ist bereits
   gruen. `color: var(--gut)` haette dort gruene Schrift auf gruenem Grund
   ergeben - beim ersten Blick in den Messstand genau so passiert. Auf
   gefuellten Knoepfen traegt der Haken im Text die Aussage allein. */
button.fertig:not(.primaer):not(.schwebeknopf),
a.fertig { color: var(--gut); border-color: var(--gut); }

/* Was noch zu tun ist  (Frank, 03.09.2026)
   ------------------------------------------------------------------
   "mach kacheln die noch abzuarbeiten sind auch leicht rot"

   Leicht ist hier das ganze Wort. Eine voll rote Kachel liest sich als
   Fehler; offen ist aber kein Fehler, sondern eine Einladung. Deshalb ein
   getoenter Grund und eine Kante links - dieselbe Form, die die App schon
   fuer "hier steht etwas an" benutzt.

   color-mix statt einer festen Farbe: --schlecht gibt es in beiden
   Schemata, und der Anteil bleibt in beiden derselbe. Eine eigene helle
   und eine eigene dunkle Farbe waeren zwei Stellen, die auseinanderlaufen
   koennen - und Farbvariablen stehen in dieser Datei ohnehin fuenfmal.

   Wer kein color-mix kann, sieht die Kachel wie bisher: die Regel faellt
   dann als Ganzes aus, und "offen" bleibt an Nummer und Text erkennbar. */
.kachel.schritt.offen,
.kachel.hinweis-kachel.offen,
.liste .reihe.offen {
  background: color-mix(in srgb, var(--schlecht) 7%, var(--karte));
  border-left: 3px solid var(--schlecht);
}
.kachel.schritt.offen,
.kachel.hinweis-kachel.offen { padding-left: calc(1.1rem - 3px); }
.liste .reihe.offen { padding-left: calc(.9rem - 3px); }

/* Die Nummer im Kreis traegt die Farbe mit - sonst sitzt ein graues
   Plaettchen auf getoentem Grund und sieht aus wie vergessen. */
.kachel.schritt.offen .schrittnr {
  background: color-mix(in srgb, var(--schlecht) 18%, var(--karte));
  color: var(--schlecht);
}

/* Zurueck in der Fuehrung (Ticket 93832292). Sitzt zwischen Schrittleiste
   und Inhalt, linksbuendig - dort, wo das Auge nach dem Lesen der Leiste
   steht. Klein und still: es ist der Nebenweg, nicht das Ziel. */
.fuehrung-zurueck { margin: .2rem 0 .8rem; }

/* Ein Knopf, der gerade arbeitet. Der Kreis sitzt als ::before im Knopf,
   damit kein zusaetzliches Element noetig ist und der Text an seiner
   Stelle bleibt. Wer Bewegung abbestellt hat, sieht einen ruhenden Ring -
   die Aussage "hier laeuft etwas" traegt auch der gesperrte Knopf.

   currentColor: der Kreis nimmt die Schriftfarbe des Knopfs an und passt
   damit auf dem gefuellten wie auf dem stillen Knopf, hell wie dunkel. */
.arbeitet { position: relative; cursor: progress; }
.arbeitet::before {
  content: ""; display: inline-block; vertical-align: -.1em;
  width: .85em; height: .85em; margin-right: .5em;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; opacity: .8;
  animation: dreht .7s linear infinite;
}
@keyframes dreht { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .arbeitet::before { animation: none; }
}

/* Kurz hervorheben, wohin gesprungen wurde. Zwei Sekunden, dann von
   selbst weg - eine Markierung, die bleibt, ist eine Auszeichnung, und
   das soll sie nicht sein. Wer Bewegung abbestellt hat, bekommt denselben
   Rahmen ohne das Verblassen. */
.hervor { box-shadow: 0 0 0 2px var(--akzent); animation: hervor 2s ease-out; }
@keyframes hervor {
  0%, 60% { box-shadow: 0 0 0 2px var(--akzent); }
  100%    { box-shadow: 0 0 0 2px transparent; }
}
@media (prefers-reduced-motion: reduce) { .hervor { animation: none; } }

/* Zwei Wahlreihen in einer Kachel (Darstellung, Sprache). Ohne das steht
   die zweite Ueberschrift ohne Luft auf der ersten Knopfreihe. */
.kachel > .label + .schemawahl { margin-bottom: .9rem; }
.kachel > .schemawahl + .label { margin-top: 0; }

/* ===================================================================
   Jeder Knopf traegt einen Rand  (Frank, 03.09.2026)
   ===================================================================
   "ich möchte das alle knöpfe einen rand haben! sodass man sie als knöpf
   erkennen kann. das ist meine absicht!"

   Eine Farbe fuer alle: var(--linie). Ein Rand heisst "Knopf", nicht
   "wichtig". Ausgenommen bleibt einzig .ms-balken button - 6 px hohe
   Segmente eines Fortschrittsbalkens, die kein Knopf sind und durch einen
   Rand unleserlich wuerden.

   Auf gesaettigt gefuellten Knoepfen waere var(--linie) unsichtbar; dort
   steht --rand-gefuellt, eine dunkle Kante, die auf jedem Grund haelt. */

:root { --rand-gefuellt: rgba(0, 0, 0, .3); }

/* ---- der haeufigste Knopf der App: 71 Stellen ---- */
.mini { border: 1px solid var(--linie); }

/* ---- Kopfzeile: die Monatspfeile ---- */
.pfeil { border: 1px solid var(--linie); }
/* .kopfmitte bleibt ohne: der Monatsname steht zwischen zwei Pfeilen, die
   ihn schon einfassen - ein Kasten darum wurde zur dritten Linie in einer
   Zeile mit drei Elementen. Frank am 03.09.2026: "border 0". */

/* ---- Namen, die zugleich Knopf sind ---- */
/* Nur noch .kat-wahl-name. Betrag und Balkenname stehen mitten in einer
   Zeile, die ihre Grenzen schon hat; ein Rand um jede Zahl machte aus der
   Auswertung ein Karopapier. Frank am 03.09.2026: "border 0" fuer
   button.bil-summe, button.balken-name und .wi-betrag. */
.kat-wahl-name {
  border: 1px solid var(--linie); padding: .35rem .45rem; border-radius: .35rem;
}

/* ---- Listen und Menues, deren Eintraege Knoepfe sind ---- */
/* Ohne .sortier-eintrag: das Menue ist eine kurze Liste in einem Kasten,
   der schon einen Rand hat - jeder Eintrag noch einmal umrandet ergab
   Kaesten im Kasten. Der Eintrag "Standard" behaelt seine Trennlinie oben,
   so wie vorher. Frank am 03.09.2026: "border 0". */
/* Ohne .schema-liste button, aus demselben Grund wie .sortier-eintrag: die
   Liste hell/dunkel/automatisch steht in einem Kasten, der schon einen Rand
   hat - drei Kaesten darin ergeben Kaesten im Kasten. Die gewaehlte Zeile
   traegt ohnehin Flaeche und Akzentfarbe, das ist die deutlichere Auskunft.
   Frank am 03.09.2026: "die raender muessen noch weg". */
.vorschlagsliste button { border: 1px solid var(--linie); }
.vorschlagsliste button { border-bottom: 1px solid var(--linie); margin-bottom: .2rem; }
.vorschlagsliste button:last-child { border-bottom: 1px solid var(--linie); margin-bottom: 0; }

/* ---- Wahlknoepfe: der Rand war da, aber durchsichtig, bis man sie waehlte.
        Jetzt sieht man sie auch ungewaehlt. ---- */
.rollenknoepfe button,
.artwahl button { border-color: var(--linie); }

/* ---- Betreiber-Panel ---- */
button.ms-zahl,
.melde-id,
.melde-klammer { border: 1px solid var(--linie); }
.melde-klammer { border-radius: .3rem; }

/* ---- Auswertung: die Zellen des Bilanzrasters ---- */
.bilanzzelle { border: 1px solid var(--rand-gefuellt); }
.bilanzzelle.leer { border-color: var(--linie); }

/* ---- gefuellte Knoepfe: hier traegt var(--linie) nicht ---- */
/* .primaer bleibt ohne Rand: der Knopf ist gruen gefuellt und breit, er
   sieht aus jedem Winkel nach Knopf aus. Frank am 03.09.2026: "border 0". */
.schwebeknopf,
.vorzeichen,
.ring-plus,
.nf-laden { border: 1px solid var(--rand-gefuellt); }
.nf-zu { border: 1px solid var(--linie); }

/* .aufteilung-summe bleibt ohne Rand - die Begruendung steht bei der Regel
   selbst, zusammen mit .wi-betrag und den anderen fuenf vom 03.09. */

/* Ein Verweis mitten im Satz. Kein Knopf mit Rand: er steht in einer
   Zeile Prosa, und dort ist ein Kasten um ein Wort ein Fremdkoerper.
   Unterstrichen und in der Akzentfarbe - so, wie ein Verweis aussieht. */
.textlink {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--akzent); text-decoration: underline;
  text-underline-offset: .15em;
}
.textlink:active { opacity: .6; }

/* Die Import-Vorschau stellt drei Beispielzeilen untereinander. Ohne dies
   liefe alles in einen Absatz - pre-line bricht nur an echten Zeilen-
   umbruechen und laesst jeden vorhandenen Text unveraendert. */
#rueckfrage-text { white-space: pre-line; }
