/* ==========================================================================
   eür.wk.de – Web-EÜR   |   Eigenes Stylesheet, keine Fremd-Frameworks
   ========================================================================== */

:root {
  /* ---- helle Palette (Standard) ---------------------------------------- */
  --bg:        #f4f5f4;
  --surface:   #ffffff;
  --surface-2: #eef0ee;
  --border:    #d9ddd9;
  --text:      #1c231f;
  --muted:     #5f6b62;
  --primary:   #1f6f54;
  --primary-c: #ffffff;
  --ein:       #1f6f54;
  --aus:       #b4442b;
  --plus:      #1f6f54;
  --minus:     #b4442b;
  --err:       #b4442b;
  --ok:        #1f6f54;
  --warn:      #8a6100;
  --radius:    10px;
  --shadow:    0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.04);
  --font:      system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* ---- Buttons: Form, Tiefe, Zustände ---------------------------------- */
  /* Eigener Radius, damit --radius (Karten, Felder, Dialog, Flash) unberührt bleibt. */
  --radius-btn:  12px;
  --radius-pill: 999px;
  /* Markengrün mit Tiefe. Hell: Hover dunkler, Klick deutlich dunkler.
     Kontraste mit Weiß: #1a6249 = 7,27:1 · #185742 = 8,47:1. */
  --primary-h:   #1a6249;
  --primary-p:   #185742;
  --aus-h:       #a43d26;
  --aus-p:       #8f3521;
  /* Fokusring. Muss je Modus die Farbe wechseln: das Icon-Mint #9ff0cf hat auf
     hellem Grund nur 1,21:1 und wäre unsichtbar; #185742 kommt auf 5,55:1. */
  --ring:        #185742;
  --ring-soft:   rgba(31,111,84,.22);
  /* Grünlich getönte Schatten (Tintbasis #144837) statt neutralem Grau. */
  --btn-shadow:   0 1px 2px rgba(20,72,55,.10), 0 2px 5px rgba(20,72,55,.07);
  --btn-shadow-h: 0 2px 4px rgba(20,72,55,.12), 0 8px 18px rgba(20,72,55,.16);
  --btn-shadow-a: inset 0 2px 4px rgba(20,72,55,.20);
  --t-btn: 130ms cubic-bezier(.2,.7,.3,1);

  /* ---- dunkle Rohwerte -------------------------------------------------
     Nur HIER gepflegt. Die beiden Blöcke unten weisen sie bloß noch zu, damit
     eine Farbänderung nicht an zwei Stellen nachgezogen werden muss. */
  --d-bg:          #14161a;
  --d-surface:     #1d2025;
  --d-surface-2:   #262a30;
  --d-border:      #343a42;
  --d-text:        #e6e8e6;
  --d-muted:       #9aa39b;
  --d-primary:     #3fae86;
  --d-primary-c:   #0f1512;
  --d-shadow:      0 1px 3px rgba(0,0,0,.4);
  /* Im Dunkeln heißt „näher" HELLER. Ein dunklerer Hover ließe den Button
     zurücktreten – genau der Fehler, den --primary-d (#359974) hatte. */
  --d-primary-h:   #5cc09b;
  --d-primary-p:   #359974;
  --d-aus-h:       #c0503a;
  --d-aus-p:       #9e3c25;
  --d-ring:        #9ff0cf;
  --d-ring-soft:   rgba(159,240,207,.28);
  --d-btn-shadow:   0 1px 2px rgba(0,0,0,.45), 0 2px 5px rgba(0,0,0,.32);
  --d-btn-shadow-h: 0 2px 4px rgba(0,0,0,.50), 0 8px 20px rgba(0,0,0,.45);
  --d-btn-shadow-a: inset 0 2px 4px rgba(0,0,0,.50);
  /* Nur die VORDERGRUND-Rollen aufhellen. --ein/--aus bleiben bewusst auf den
     hellen Werten: sie sind Flächen (Diagrammbalken, .btn-gefahr-Hintergrund)
     mit festem weißem Text; ein Aufhellen drückte die unter 4,5:1. */
  --d-err:   #e8836a;
  --d-minus: #e8836a;
  --d-ok:    #58c39c;
  --d-plus:  #58c39c;
  --d-warn:  #e0b155;
}

/* Dunkle Palette: greift bei Systemvorgabe „dunkel" (sofern nicht manuell auf
   hell gestellt) UND wenn manuell auf dunkel geschaltet.
   Beide Blöcke enthalten dieselbe Zuweisungsliste – sie ändert sich nicht mehr,
   Werte werden ausschließlich oben bei den --d-*-Tokens gepflegt. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: var(--d-bg);                 --surface: var(--d-surface);
    --surface-2: var(--d-surface-2);   --border: var(--d-border);
    --text: var(--d-text);             --muted: var(--d-muted);
    --primary: var(--d-primary);       --primary-c: var(--d-primary-c);
    --shadow: var(--d-shadow);
    --primary-h: var(--d-primary-h);   --primary-p: var(--d-primary-p);
    --aus-h: var(--d-aus-h);           --aus-p: var(--d-aus-p);
    --ring: var(--d-ring);             --ring-soft: var(--d-ring-soft);
    --btn-shadow: var(--d-btn-shadow);
    --btn-shadow-h: var(--d-btn-shadow-h);
    --btn-shadow-a: var(--d-btn-shadow-a);
    --err: var(--d-err);               --minus: var(--d-minus);
    --ok: var(--d-ok);                 --plus: var(--d-plus);
    --warn: var(--d-warn);
  }
}
:root[data-theme="dark"] {
  --bg: var(--d-bg);                 --surface: var(--d-surface);
  --surface-2: var(--d-surface-2);   --border: var(--d-border);
  --text: var(--d-text);             --muted: var(--d-muted);
  --primary: var(--d-primary);       --primary-c: var(--d-primary-c);
  --shadow: var(--d-shadow);
  --primary-h: var(--d-primary-h);   --primary-p: var(--d-primary-p);
  --aus-h: var(--d-aus-h);           --aus-p: var(--d-aus-p);
  --ring: var(--d-ring);             --ring-soft: var(--d-ring-soft);
  --btn-shadow: var(--d-btn-shadow);
  --btn-shadow-h: var(--d-btn-shadow-h);
  --btn-shadow-a: var(--d-btn-shadow-a);
  --err: var(--d-err);               --minus: var(--d-minus);
  --ok: var(--d-ok);                 --plus: var(--d-plus);
  --warn: var(--d-warn);
}

* { box-sizing: border-box; }

/* Das hidden-Attribut muss immer gewinnen, auch gegen display:flex o. ä. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; overflow-x: hidden; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  overflow-x: clip; /* nichts darf die Seite seitlich scrollen lassen */
}

h1 { font-size: 1.5rem; margin: 0 0 .5rem; }
h2 { font-size: 1.15rem; margin: 0 0 .75rem; }
a { color: var(--primary); }

.muted { color: var(--muted); }
.err   { color: var(--err); font-size: .875rem; }

/* --- Layout ------------------------------------------------------------- */
.wrap {
  max-width: 960px;
  margin: 0 auto;
  padding: 1rem 1rem 3rem;
}
.stack > * + * { margin-top: 1rem; }
/* Aufeinanderfolgende Abschnitte auf oberster Ebene gleichmäßig trennen.
   Die Startseite reiht vier <section> ohne .stack aneinander; die Abstände kamen
   bisher aus Einzelregeln (.features margin-top, .card + .card) und ergaben
   0,5rem / 1,5rem / 0 – vor „Was drin ist" fehlte der Abstand ganz, weil
   .card + .card dort nicht greift (davor steht .features, keine Karte).
   Betrifft ausschließlich die Startseite: alle übrigen Ansichten haben genau
   einen Abschnitt auf oberster Ebene. */
.wrap > section + section { margin-top: 1.5rem; }
.pagehead h1 { margin-bottom: .1rem; }

/* --- Topbar / Navigation --------------------------------------------- */
.topbar {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .6rem 1rem;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 10;
}
.brand {
  font-weight: 700;
  text-decoration: none;
  color: var(--text);
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}
.brand span { font-weight: 400; font-size: .8rem; color: var(--muted); }

.navtoggle {
  margin-left: auto;
  font-size: 1.4rem;
  line-height: 1;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .2rem .6rem;
  color: var(--text);
  cursor: pointer;
}

.mainnav {
  display: none;
  width: 100%;
  flex-direction: column;
  gap: .25rem;
  margin-top: .5rem;
}
.mainnav.open { display: flex; }
.mainnav a {
  text-decoration: none;
  color: var(--text);
  padding: .55rem .6rem;
  border-radius: var(--radius);
}
/* Aktiver Punkt im Markenton statt neutralem Grau – so ist auf einen Blick
   erkennbar, wo man ist. */
.mainnav a[aria-current="page"] {
  background-color: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
  font-weight: 600;
}
.mainnav a:hover { background: var(--surface-2); }
.mainnav .logout { margin-top: .25rem; }
.mainnav .logout button {
  width: 100%;
  text-align: left;
  padding: .55rem .6rem;
  background: none;
  border: 0;
  border-radius: var(--radius);
  color: var(--muted);
  font: inherit;
  cursor: pointer;
}
.mainnav .logout button:hover { background: var(--surface-2); color: var(--text); }

@media (min-width: 720px) {
  .navtoggle { display: none; }
  .mainnav {
    display: flex;
    flex-direction: row;
    align-items: center;
    width: auto;
    margin-top: 0;
    margin-left: auto;
    gap: .15rem;
  }
  .mainnav .logout { margin: 0 0 0 .5rem; }
  .mainnav .logout button { width: auto; }
}

/* --- Cards & Flash -------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.25rem;
}
.card + .card { margin-top: 1rem; }

.auth-card { max-width: 520px; margin: 2rem auto; }

/* margin-bottom, damit der Hinweis nicht am folgenden Inhalt klebt. In .wrap
   steht er direkt vor dem Seiteninhalt (z. B. der Drucken-Leiste der Rechnung),
   dort gäbe es sonst gar keinen Abstand. Innerhalb von .stack kollabiert er mit
   dem dortigen margin-top zu einem – kein doppelter Abstand. */
.flash {
  margin-bottom: 1rem;
  padding: .7rem .9rem;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--surface-2);
}
.flash-fehler { border-color: var(--err); color: var(--err); background: color-mix(in srgb, var(--err) 10%, transparent); }
.flash-erfolg { border-color: var(--ok);  color: var(--ok);  background: color-mix(in srgb, var(--ok) 12%, transparent); }
/* Der Hinweis steht als direktes Kind von <main class="wrap"> (960px) und war
   damit breiter als Formularseiten, die .form-card (640px) nutzen. Er soll so
   breit sein wie der Inhalt darunter. Browser ohne :has() zeigen weiterhin die
   volle Breite – unschön, aber unschädlich. */
main.wrap:has(.form-card) .flash { max-width: 640px; }

/* --- Formulare --------------------------------------------------- */
form.stack label { display: block; font-weight: 600; }
form.stack label small { display: block; font-weight: 400; margin-top: .15rem; }

input, select, textarea {
  width: 100%;
  margin-top: .3rem;
  padding: .6rem .7rem;
  font: inherit;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* Trennlinie zwischen zwei Bereichen derselben Karte. */
.trenner { border: 0; border-top: 1px solid var(--border); margin: 1.5rem 0 1rem; }

/* Wiederherstellungscode: zum Abschreiben gedacht, also groß, monospace und
   mit Abstand zwischen den Zeichen. */
.wh-code {
  font: 700 1.35rem/1.8 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: .12em;
  text-align: center;
  margin: 1rem 0;
  padding: 1rem;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  user-select: all;          /* ein Klick markiert alles */
  overflow-wrap: anywhere;
}

/* Suchfeld über dem Anlagenspiegel. Schmal – es filtert eine überschaubare
   Liste und soll die Tabelle nicht dominieren. */
/* Hinweisbalken oben. Ruhig gehalten – er erscheint bei jeder Anmeldung. */
.hinweisbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .75rem;
  padding: .55rem 1rem; font-size: .88rem;
  background: var(--surface-2); border-bottom: 1px solid var(--border);
  border-left: 3px solid var(--warn);
}
.hinweisbar span { flex: 1 1 16rem; }
.hinweisbar a { font-weight: 600; }
.hinweisbar button {
  background: none; border: 0; font-size: 1.25rem; line-height: 1;
  color: var(--muted); padding: 0 .25rem;
}
.hinweisbar button:hover { color: var(--text); }
.hinweisbar form { margin: 0; }

/* Mehrere Aktionen rechts neben einer Seitenüberschrift. */
.pagehead-aktionen { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.pagehead-aktionen form { margin: 0; }

/* Nur für Vorlesesoftware – sichtbar ist die Beschriftung über den
   placeholder. Ein Eingabefeld ganz ohne Label wäre nicht bedienbar. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Zurückgezogene Nachricht: noch da, aber ohne Wirkung. */
.zeile-inaktiv { opacity: .55; }

/* Meldung im Adminbereich: Rohtext, umbrechend, nicht seitlich scrollend. */
.meldung-text {
  white-space: pre-wrap; word-break: break-word;
  font-size: .85rem; line-height: 1.5;
  background: var(--surface-2); padding: .9rem; border-radius: var(--radius-btn);
  max-height: 32rem; overflow-y: auto;
}

/* --- Buchungsart wählen ---------------------------------------- */
.modus-wahl { border: 0; padding: 0; margin: 0 0 .8rem; display: grid; gap: .2rem; }
.modus-wahl legend { padding: 0; }
#bewirtung-fields { display: grid; gap: .6rem; margin-bottom: .8rem; }

/* --- USt-IdNr prüfen ------------------------------------------- */

.feld-mit-knopf { display: flex; gap: .4rem; align-items: stretch; }
.feld-mit-knopf input { flex: 1 1 auto; min-width: 0; }
.feld-mit-knopf .btn-small { flex: 0 0 auto; white-space: nowrap; }

.ustid-ergebnis { display: block; margin-top: .35rem; font-size: .82rem; color: var(--muted); }
.ustid-ergebnis.ok   { color: var(--ok); }
.ustid-ergebnis.bad  { color: var(--err); }
/* „Nicht erreichbar" ist KEINE Aussage über die Nummer – deshalb nicht rot. */
.ustid-ergebnis.warn { color: var(--warn); }

/* --- Hilfeseite ----------------------------------------------- */

.hilfe-gruppe { margin-top: 1.8rem; }
.hilfe-gruppe > h2 {
  font-size: 1.05rem; margin: 0 0 .8rem;
  padding-bottom: .35rem; border-bottom: 2px solid var(--border);
}

.hilfe-eintrag {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1rem 1.1rem; margin-bottom: .7rem;
}
.hilfe-eintrag > h3 { margin: 0 0 .5rem; font-size: .97rem; }
.hilfe-eintrag p, .hilfe-eintrag ul, .hilfe-eintrag ol { margin: .5rem 0; }
.hilfe-eintrag p:last-child, .hilfe-eintrag ul:last-child, .hilfe-eintrag ol:last-child { margin-bottom: 0; }
.hilfe-eintrag li { margin: .25rem 0; }

.hilfe-leer { padding: 1rem 0; color: var(--muted); }

/* Das Suchfeld ist der Einstieg – es darf nicht wie ein Nebenfeld aussehen. */
#hilfe-suche { width: 100%; font-size: 1.05rem; }

/* Ausdruckbar: Die Hilfe ist auch etwas zum Danebenlegen. Suchfeld und
   Navigation gehören dann nicht aufs Papier, aufgeklappt muss alles sein. */
@media print {
  .hilfe .card:first-of-type, .hilfe-leer { display: none; }
  .hilfe-eintrag { break-inside: avoid; border: 0; padding: 0 0 .6rem; }
  .hilfe-eintrag[hidden], .hilfe-gruppe[hidden] { display: block !important; }
}

/* --- Zweiter Faktor: Authenticator-App ------------------------ */

/* Trenner zwischen zwei gleichwertigen Wegen („Passkey ODER Code"). */
.trenner-oder {
  display: flex; align-items: center; gap: .75rem;
  margin: 1.1rem 0; color: var(--muted); font-size: .85rem;
}
.trenner-oder::before, .trenner-oder::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--border);
}

/* Sechsstelliger Code: gross, weit gesperrt, Ziffern gleich breit – so
   erkennt man Zahlendreher beim Abtippen. */
.code-feld {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.5rem; letter-spacing: .3em; text-align: center;
  font-variant-numeric: tabular-nums;
}

/* QR und Schlüssel nebeneinander, auf schmalen Geräten untereinander. */
.totp-einrichten {
  display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start;
  margin-bottom: 1rem;
}
.totp-einrichten > * { flex: 1 1 15rem; min-width: 0; }
.totp-qr { flex: 0 0 auto; margin: 0; text-align: center; }
/* Der QR-Code muss auf WEISSEM Grund stehen, auch im Dunkelmodus – sonst
   scheitert jeder Scanner. Gleiche Begründung wie beim GiroCode. */
/* `max-width` ist hier kein Schönheitsfehler, sondern nötig: Der Code ist
   jetzt (45+16) x 6 px breit. Ohne die Begrenzung liefe er auf einem
   schmalen Telefon aus der Karte heraus — und `html { overflow-x: hidden }`
   würde ihn dann ABSCHNEIDEN statt scrollen zu lassen. Ein halber QR-Code
   ist gar keiner. */
.totp-qr .qr { display: block; background: #fff; padding: .4rem;
  border-radius: var(--radius-btn); max-width: 100%; height: auto; }
/* Flexible Variante: Die Breite bestimmt das CSS, nicht das SVG. So wird das
   Vektorbild GLEICHMÄSSIG skaliert statt per `max-width` gestaucht — bei
   gestauchten `crispEdges` werden Module ungleich groß, und daran scheitert
   jeder Scanner. `max-width` in `ch` statt `px`, damit es bei großer Schrift
   mitwächst. */
.totp-qr .qr-flex { width: 100%; height: auto; max-width: 20rem; margin: 0 auto; }
.totp-qr figcaption { margin-top: .4rem; font-size: .72rem; color: var(--muted); }

/* Ersatzcodes: zum Abschreiben und Ausdrucken. */
.ersatzcodes {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.05rem; letter-spacing: .06em;
  columns: 2; column-gap: 2rem;
  margin: 1rem 0; padding-left: 1.6rem;
}
.ersatzcodes li { margin: .3rem 0; break-inside: avoid; }
@media (max-width: 32rem) { .ersatzcodes { columns: 1; } }

/* Betreiber-Nachricht als Balken: derselbe Streifen, aber in der
   Hinweisfarbe statt der Warnfarbe – sie ist eine Mitteilung, keine Mahnung. */
.nachrichtbar { border-left-color: var(--akzent, var(--warn)); }
.nachrichtbar strong { margin-right: .25rem; }

/* Betreiber-Nachricht, die bestätigt werden muss.
   `open` steht schon im HTML: Fällt JavaScript aus, liegt der Kasten trotzdem
   über der Seite (position: fixed) statt im Textfluss zu verschwinden. Mit
   JavaScript öffnet app.js ihn zusätzlich per showModal(), was den
   Tastaturfokus einfängt und den Hintergrund abdunkelt. */
.nachricht-dialog {
  max-width: 32rem;
  text-align: left;
}
.nachricht-dialog h2 { margin: 0 0 .6rem; font-size: 1.05rem; }
.nachricht-dialog p { margin: 0 0 1.2rem; font-size: .95rem; line-height: 1.5; }
.nachricht-dialog[open]:not(:modal) {
  position: fixed;
  inset: auto;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 60;
}

/* Liste hinterlegter Passkeys. */
.pk-liste { list-style: none; margin: .5rem 0; padding: 0; font-size: .9rem; }
.pk-liste li {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: .4rem 0; border-bottom: 1px solid var(--border);
}
.pk-liste small { display: block; }

/* Sicherungs-Hinweis auf der Übersicht: ruhig, aber nicht zu übersehen. */
.sicherung-hinweis {
  margin: 0 0 1rem; padding: .55rem .8rem; font-size: .9rem;
  border-left: 3px solid var(--warn); border-radius: var(--radius);
  background: var(--surface-2);
}

/* Suchfeld über einer im Browser gefilterten Liste. Eine Klasse für alle
   drei Stellen (Anlagen, Vorlagen, Rechnungsarchiv) – nicht je Seite
   eine eigene, sonst laufen sie auseinander. */
/* Einheitliches Suchfeld über einer im Browser gefilterten Liste.
   Hiess bis 2026-09-19 `.anl-suche` – ein von den Anlagen geborgter Name,
   den Vorlagen, Archiv und Fahrten mitkopiert hatten. Das Muster ist
   allgemein, der Name jetzt auch. Aufbau siehe docs/DESIGN.md. */
.listensuche { display: block; max-width: 22rem; margin: 0 0 .8rem; font-weight: 600; }

/* Weiterführende Links (AfA, Kleinunternehmergrenze). Bewusst schlicht:
   Hilfe, kein Werbebanner. */
.hilfe-links { list-style: none; margin: .5rem 0 0; padding: 0; font-size: .8rem; }
.hilfe-links li { margin: .2rem 0; }
.hilfe-links a::after { content: " ↗"; opacity: .6; }

/* Kleinunternehmergrenze. Vier Stufen, von „noch Zeit" bis „endet sofort" —
   die Farbe trägt die Dringlichkeit, der Text die Begründung. */
.ku-warnung {
  margin-bottom: 1rem; padding: .9rem 1.1rem;
  border: 1px solid var(--border); border-left: 3px solid var(--warn);
  border-radius: var(--radius); background: var(--surface);
}
.ku-warnung strong { display: block; margin-bottom: .3rem; }
.ku-warnung p { margin: .3rem 0; font-size: .9rem; line-height: 1.5; }
.ku-warnung .ku-zahlen { font-size: .8rem; color: var(--muted); }
.ku-nah            { border-left-color: var(--warn); }
.ku-naechstes_jahr { border-left-color: var(--warn); }
/* Ab hier ist es kein Hinweis mehr, sondern ein Zustand, der Handeln erfordert. */
.ku-pflichtig, .ku-ende { border-left-color: var(--err); }

/* AfA-Tabelle am Nutzungsdauer-Feld. Zugeklappt, damit sie das Formular nicht
   dominiert – aufgeklappt eine ruhige Liste mit Zahlen rechtsbündig. */
.nd-tabelle { margin-top: .5rem; font-weight: 400; }
.nd-tabelle > summary { cursor: pointer; font-size: .82rem; color: var(--muted); }
.nd-tabelle > summary:hover { color: var(--text); }
.nd-tabelle ul { list-style: none; margin: .5rem 0; padding: 0; font-size: .82rem; }
.nd-tabelle li {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .18rem .4rem; border-radius: 4px;
}
.nd-tabelle li span { color: var(--muted); min-width: 0; }
.nd-tabelle li strong { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Das gerade gewählte Konto hervorheben – dann sieht man sofort, woher der
   vorgeschlagene Wert stammt. */
.nd-tabelle li.ist-gewaehlt { background: var(--surface-2); }
.nd-tabelle li.ist-gewaehlt span { color: var(--text); }
.nd-tabelle p { font-size: .78rem; margin: .35rem 0 0; }

/* Hinweis der Versionswache. Ganz oben und auffällig, aber nicht modal —
   der Nutzer soll weitertippen können, bis er selbst neu lädt. */
.neu-version {
  position: sticky; top: 0; z-index: 60;
  display: flex; flex-wrap: wrap; align-items: center; gap: .75rem;
  padding: .6rem 1rem;
  font-size: .9rem;
  color: #fff; background: #8a6100;
}
.neu-version span { flex: 1 1 12rem; }
.neu-version .btn-small { flex: 0 0 auto; background: #fff; color: #23241f; border-color: #fff; }

/* Hinweis ohne JavaScript. Der <noscript>-Block blendet alles andere aus. */
.ohne-js {
  max-width: 34rem;
  margin: 3rem auto;
  padding: 1.5rem;
  border: 1px solid var(--border);
  border-left: 3px solid var(--err);
  border-radius: var(--radius);
  background: var(--surface);
}
.ohne-js h1 { margin-top: 0; font-size: 1.3rem; }
.ohne-js p { line-height: 1.55; }

/* Ersatz-Eingabefeld für Adressen (siehe adressfeld() in helpers.php).
   Muss sich von einem echten Feld nicht unterscheiden lassen – dieselben
   Maße wie oben, damit PLZ und Ort im .grid2 auf gleicher Höhe stehen. */
.eingabe {
  display: block;
  width: 100%;
  margin-top: .3rem;
  padding: .6rem .7rem;
  font: inherit;
  font-weight: 400;              /* die Beschriftung daneben ist fett */
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  min-height: calc(1.5em + 1.2rem + 2px);
  white-space: pre-wrap;         /* Leerzeichen am Ende nicht verschlucken */
  overflow-wrap: anywhere;       /* lange Namen sprengen das Feld nicht */
  cursor: text;
}
.eingabe:focus { outline: 2px solid var(--ring); outline-offset: 2px; }
.eingabe.leer::before {
  content: attr(data-platzhalter);
  color: var(--muted);
  pointer-events: none;
}
.eingabe[contenteditable="false"] { background: var(--surface-2); cursor: default; }

/* ---- Tastaturfokus --------------------------------------------------------
   Eine einzige Regel deckt ALLE klickbaren Elemente ab, auch die fünf
   klassenlosen <button> (Infobar, Adminbar, Abmelden, zwei Löschen-Kreuze) und
   die klassenlosen Aktions-Links in Tabellenzellen – ohne Markup-Änderung.
   Zuvor hatten nur Eingabefelder eine Fokusanzeige.
   outline-offset erzeugt einen Spalt in der Hintergrundfarbe, dadurch ist der
   Ring auch auf einem gefüllten grünen Button klar abgesetzt und es braucht
   keinen zweischichtigen box-shadow, der sich mit dem Button-Schatten stritte.
   Bewusst NICHT auf :focus-visible für Eingabefelder umgestellt: bei <select>
   verhalten sich Browser dabei uneinheitlich. */
:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
}

/* Das Radio in .segmented ist visuell versteckt (opacity:0) – ohne diese Regel
   gibt es beim Durchtabben gar keine sichtbare Anzeige. */
.segmented:focus-within { outline: 2px solid var(--ring); outline-offset: 2px; }

/* .buchzeile hat overflow:hidden; ein Outline am Kind würde abgeschnitten.
   Deshalb den Ring an die Zeile hängen und am Kind unterdrücken. */
.buchzeile:focus-within { outline: 2px solid var(--ring); outline-offset: 2px; }
.buchzeile-main:focus-visible { outline: none; }

/* Sanfte Übergänge für das übrige Klickbare. Bewusst NICHT über den Selektor
   `button`: der träfe auch .linkbtn, .chip, .bz-del und die Navigation, die
   weder Fläche noch Polsterung wollen. Nur Farbwechsel, keine Bewegung. */
.linkbtn, .chip, .navtoggle, .themetoggle, .quartale a, .segmented label,
.mainnav a, .mainnav .logout button, .adminbar button, .infobar button,
.bz-del button, .ac-item, .pos-del, .split-del {
  transition: background-color var(--t-btn), color var(--t-btn),
              border-color var(--t-btn);
}

/* Wer Bewegung reduziert haben will, behält die Farbübergänge (das ist keine
   Bewegung) und verliert nur das Heben/Senken. */
@media (prefers-reduced-motion: reduce) {
  .btn-primary, .btn-ghost, .btn-big, .btn-small, .btn-mini,
  .btn-ein, .btn-aus, .btn-gefahr, .btn-danger, .btn-disabled, .chip {
    transition-property: background-color, border-color, color, box-shadow;
  }
  .btn-primary:hover, .btn-ghost:hover, .btn-big:hover, .btn-small:hover,
  .btn-mini:hover, .btn-ein:hover, .btn-aus:hover, .btn-gefahr:hover,
  .btn-danger:hover, .chip:hover,
  .btn-primary:active, .btn-ghost:active, .btn-big:active, .btn-small:active,
  .btn-mini:active, .btn-ein:active, .btn-aus:active, .btn-gefahr:active,
  .btn-danger:active, .chip:active {
    transform: none;
  }
}

fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  margin: 0;
}
fieldset legend { font-weight: 700; padding: 0 .4rem; }
fieldset label + label { margin-top: .8rem; }
/* …aber NICHT im layoutneutralen .fs-blank. Das umschließt nur das Rechnungs-
   formular, um es mit einem `disabled` sperren zu können. Ohne diese Ausnahme
   bekäme in jedem .grid2-Paar das ZWEITE Label 0,8rem Abstand nach oben — „Ort"
   stünde tiefer als „PLZ", „Leistungsdatum" tiefer als „Rechnungsdatum".
   Der Abstand zwischen gestapelten Labels kommt dort ohnehin aus .stack. */
.fs-blank label + label { margin-top: 0; }

button { font: inherit; cursor: pointer; }

/* ==========================================================================
   Buttons — alles an EINER Stelle.
   Die Reihenfolge innerhalb dieses Blocks ist bedeutungstragend:
     Basis → Rollen → Größen → :hover → :active → deaktiviert (zuletzt).
   Nach außen gibt es keine Reihenfolgeabhängigkeit mehr, weil keine zwei
   Button-Regeln an verschiedenen Dateistellen um dieselbe Eigenschaft streiten.

   Die Basis liegt bewusst NICHT auf dem Element `button`: das träfe auch
   .linkbtn, .chip, .navtoggle, .themetoggle, .bz-del button und die
   Navigation, die weder Polsterung noch Fläche wollen.
   ========================================================================== */
.btn-primary, .btn-ghost, .btn-big, .btn-small, .btn-mini,
.btn-ein, .btn-aus, .btn-gefahr, .btn-danger, .btn-disabled {
  display: inline-flex;          /* auch nötig, damit transform auf <span> wirkt */
  align-items: center;
  justify-content: center;
  gap: .4em;
  padding: var(--btn-py, .7rem) var(--btn-px, 1.1rem);
  /* Rand für ALLE, auch gefüllte: background-clip ist border-box, der
     Hintergrund malt darunter durch. Gefüllte Buttons sehen unverändert aus,
     fluchten aber endlich mit .btn-ghost (vorher 2px Versatz in jeder
     .form-actions- und .druck-toolbar-Zeile). */
  border: 1px solid transparent;
  border-radius: var(--radius-btn);
  background-color: var(--btn-bg, var(--surface));
  color: var(--btn-fg, var(--text));
  font: inherit;
  font-weight: 600;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--btn-shadow);
  transition: background-color var(--t-btn), border-color var(--t-btn),
              color var(--t-btn), box-shadow var(--t-btn), transform var(--t-btn);
}

/* ---- Rollen: setzen NUR Variablen ---------------------------------------
   Damit gibt es eine einzige Hover-Mechanik statt der bisherigen drei
   (Farbwechsel / filter:brightness / Hintergrundwechsel). */
.btn-primary, .btn-big, .btn-small, .btn-mini, .btn-ein {
  --btn-bg:   var(--primary);
  --btn-bg-h: var(--primary-h);
  --btn-bg-p: var(--primary-p);
  --btn-fg:   var(--primary-c);
}
/* .btn-aus steht nach .btn-big/.btn-small, damit die Kombinationen
   `btn-big btn-aus` und `btn-small btn-aus` ohne Extraregel greifen. */
.btn-aus, .btn-gefahr, .btn-danger {
  --btn-bg:   var(--aus);
  --btn-bg-h: var(--aus-h);
  --btn-bg-p: var(--aus-p);
  --btn-fg:   #fff;
}
/* .btn-ghost zuletzt: löst `btn-small btn-ghost` strukturell auf, das frühere
   Sicherheitsnetz entfällt ersatzlos. */
.btn-ghost {
  --btn-bg:   var(--surface);
  --btn-bg-h: var(--surface-2);
  --btn-bg-p: var(--surface-2);
  --btn-fg:   var(--text);
  border-color: var(--border);
}

/* ---- Größen: über Variablen, nicht über Nachfahren-Selektoren ------------
   Custom Properties erben, deshalb kann ein Container (.pagehead-actions,
   .filterbar, .app-dialog-actions) die Größe vorgeben, ohne jede Buttonklasse
   einzeln adressieren zu müssen. Größenklassen setzen sie am Element und
   gewinnen damit gegen die Vererbung. Ersetzt vier Ad-hoc-Paddings. */
.btn-big   { --btn-py: 1rem;   --btn-px: 1.4rem; flex: 1 1 140px;
             font-size: 1.05rem; font-weight: 700; }
.btn-small { --btn-py: .5rem;  --btn-px: .8rem;  white-space: nowrap; }
.btn-mini  { --btn-py: .45rem; --btn-px: .8rem;  white-space: nowrap; }

/* ---- Zustände ----------------------------------------------------------
   Ein :hover und ein :active für alle Rollen. Die :not()-Kette sperrt
   deaktivierte Buttons aus, damit sie sich weder heben noch einfärben. */
:is(.btn-primary, .btn-ghost, .btn-big, .btn-small, .btn-mini,
    .btn-ein, .btn-aus, .btn-gefahr, .btn-danger):not(.btn-disabled):not(:disabled):not([aria-disabled="true"]):hover {
  background-color: var(--btn-bg-h, var(--btn-bg));
  box-shadow: var(--btn-shadow-h);
  transform: translateY(-1px);
}
:is(.btn-primary, .btn-ghost, .btn-big, .btn-small, .btn-mini,
    .btn-ein, .btn-aus, .btn-gefahr, .btn-danger):not(.btn-disabled):not(:disabled):not([aria-disabled="true"]):active {
  background-color: var(--btn-bg-p, var(--btn-bg-h));
  box-shadow: var(--btn-shadow-a);
  transform: translateY(1px);
}

/* ---- Deaktiviert: MUSS zuletzt stehen ------------------------------------
   Überschreibt nur die Variablen – background/color in der Basis lösen sich
   daraus auf. Damit greifen `btn-primary btn-disabled` UND
   `btn-mini btn-disabled` ohne !important und ohne Zufall, und die vier
   disabled-Buttons im Markup sehen erstmals deaktiviert aus. */
.btn-disabled,
[aria-disabled="true"],
.btn-primary:disabled, .btn-ghost:disabled, .btn-small:disabled,
.btn-mini:disabled, .btn-big:disabled, .btn-gefahr:disabled, .btn-danger:disabled {
  --btn-bg:   var(--surface-2);
  --btn-bg-h: var(--surface-2);
  --btn-bg-p: var(--surface-2);
  --btn-fg:   var(--muted);
  border-color: var(--border);
  box-shadow: none;
  transform: none;
  cursor: not-allowed;
}
.btn-disabled s { text-decoration: line-through; }

/* --- KPIs ------------------------------------------------------ */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: .75rem;
}
@media (min-width: 720px) { .kpi-row { grid-template-columns: repeat(4, 1fr); } }

.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .9rem;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: .2rem;
}
.kpi-label { font-size: .8rem; color: var(--muted); }
.kpi-val   { font-size: 1.25rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.kpi-ein .kpi-val, .kpi-plus .kpi-val { color: var(--plus); }
.kpi-aus .kpi-val, .kpi-minus .kpi-val { color: var(--minus); }

/* --- Quick actions ------------------------------------------ */
.quick-actions { display: flex; gap: .75rem; flex-wrap: wrap; }
/* .btn-big, .btn-big.btn-aus und der brightness-Hover sind in den
   Button-Block oben gewandert. */

.checklist { margin: 0; padding-left: 1.1rem; }
.checklist li { margin: .25rem 0; }

/* --- Footer ------------------------------------------------ */
.pagefoot {
  text-align: center;
  padding: 1.5rem 1rem 2.5rem;
  color: var(--muted);
  font-size: .85rem;
}

/* --- Tabellen (später) ----------------------------------- */
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: .5rem .6rem; border-bottom: 1px solid var(--border); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* --- Öffentliche Kopfzeile + Buttons -------------------- */
.topbar-public { justify-content: space-between; }
.mainnav-public { display: flex; align-items: center; gap: .75rem; }
/* :where() nimmt diesem Kontext die Spezifität (0-1-1 → 0-0-1). Nur deshalb
   brauchte .btn-mini früher zwei !important – und genau die verhinderten, dass
   `btn-mini btn-disabled` als deaktiviert erkennbar wurde. */
:where(.mainnav-public) a { text-decoration: none; color: var(--text); padding: .4rem .2rem; }
/* .btn-mini und .btn-ghost stehen jetzt im Button-Block oben. */

/* --- Admin-Balken -------------------------------------- */
.adminbar {
  display: flex;
  align-items: center;
  gap: .9rem;
  justify-content: center;
  flex-wrap: wrap;
  background: #2c3440;
  /* Fester dunkler Balken, folgt dem Hell/Dunkel-Modus NICHT. Der modusabhängige
     --ring wäre hier im Hellmodus mit 1,48:1 unsichtbar – deshalb lokal auf einen
     hellen Ton festgelegt (9,47:1 auf diesem Grund). */
  --ring: #9ff0cf;
  color: #e6e8e6;
  font-size: .85rem;
  padding: .45rem 1rem;
}
.adminbar a { color: #9fd0ff; }
.adminbar form { margin: 0; }
.adminbar button {
  background: none;
  border: 1px solid #55606e;
  color: inherit;
  border-radius: var(--radius);
  padding: .15rem .6rem;
  cursor: pointer;
  font: inherit;
}

/* --- Demo-Hinweisbalken -------------------------------- */
.demobar {
  background: #f3e6c4;
  color: #5a4a1e;
  /* Spiegelbildlich zum Adminbalken: fester heller Grund, auf dem der
     Dunkelmodus-Ring (Mint) mit 1,07:1 verschwände. 6,96:1 mit der Textfarbe. */
  --ring: #5a4a1e;
  text-align: center;
  padding: .5rem 1rem;
  font-size: .9rem;
}
.demobar a { color: #5a4a1e; }
@media (prefers-color-scheme: dark) {
  .demobar { background: #4a3f1c; color: #f0e2b8; }
  .demobar a { color: #f0e2b8; }
}

/* --- Landingpage -------------------------------------- */
.hero { padding: 1.5rem 0 .5rem; }
.hero h1 { font-size: 1.8rem; line-height: 1.25; max-width: 22ch; }
.lead { font-size: 1.1rem; color: var(--muted); max-width: 60ch; }
.hero-actions { display: flex; gap: .75rem; flex-wrap: wrap; margin-top: 1rem; }
/* .hero-actions .btn-primary entfernt: display:inline-block (0-2-0) haette das
   inline-flex der Button-Basis gekippt; text-decoration liefert die Basis. */

/* .demo-card .creds / .demo-card code entfernt (2026-09-05): Die Startseite
   zeigt die Demo-Zugangsdaten nicht mehr an, der Button meldet direkt an. */
.small { font-size: .8rem; }

.features { margin-top: 1.5rem; }
.feature-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: .9rem;
  margin-top: .75rem;
}
@media (min-width: 640px) { .feature-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 960px) { .feature-grid { grid-template-columns: 1fr 1fr 1fr; } }
.feature {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem;
  box-shadow: var(--shadow);
}
.feature h3 { margin: 0 0 .3rem; font-size: 1rem; }
.feature p { margin: 0; color: var(--muted); font-size: .92rem; }

/* --- Auth-Seiten ------------------------------------- */
.auth-alt { margin-top: 1rem; text-align: center; color: var(--muted); }
.resend { margin-top: .75rem; }
.tokenlink { word-break: break-all; font-size: .85rem; }

/* --- Cookie-/Technik-Hinweisleiste ------------------- */
.infobar {
  display: flex;
  align-items: center;
  gap: .8rem;
  flex-wrap: wrap;
  justify-content: center;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
  color: var(--muted);
  font-size: .85rem;
  padding: .5rem 1rem;
}
.infobar a { color: var(--text); }
.infobar button {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  border-radius: var(--radius);
  padding: .3rem .8rem;
  cursor: pointer;
  font: inherit;
}
.infobar button:hover { background: var(--surface-2); }

/* --- Footer-Links ----------------------------------- */
.footlinks { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; margin-top: .4rem; }
.footlinks a { color: var(--muted); }

/* --- Fließtext (Rechtstexte) ----------------------- */
.prose { max-width: 68ch; }
.prose h2 { font-size: 1.05rem; margin: 1.4rem 0 .4rem; }
.prose p, .prose ul { margin: .5rem 0; }
.prose ul { padding-left: 1.2rem; }
.prose code { background: var(--surface-2); padding: .05rem .35rem; border-radius: 5px; }
.flash-info { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }
/* Warnung: die Aktion hat geklappt, aber etwas fehlt noch. Nicht rot —
   das waere ein Fehler, und der liegt hier nicht vor. */
.flash-warn { border-color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent); }
label.check { display: flex; gap: .5rem; align-items: flex-start; font-weight: 400; }
label.check input { width: auto; margin-top: .25rem; }
.nb-abbruch { margin-top: .6rem; }
.nowrap { white-space: nowrap; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Erläuternder Text IM Eingabefeld, rechtsbündig (z. B. „4930  Bürobedarf").
   Das Feld selbst bleibt rein numerisch – der Text liegt nur darüber, wird
   nicht mitgesendet und ändert an Validierung/Persistenz nichts.
   Die Werte top/right entsprechen margin-top bzw. padding des Feldes
   (siehe „Formulare" oben); bottom:0 spannt den Text über die Feldhöhe,
   flex zentriert ihn darin vertikal. */
.feld-mit-zusatz { display: block; position: relative; }
.feld-mit-zusatz input { padding-right: 42%; }
.feld-zusatz {
  position: absolute;
  top: .3rem;
  right: .7rem;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  max-width: 58%;
  color: var(--muted);
  font-size: .95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;   /* Klick landet im Feld, nicht auf dem Text */
}
.feld-zusatz:empty { display: none; }

/* --- Buchungen: Liste -------------------------------- */
.pagehead-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
/* Größe für alle Buttons in der Kopfzeile – über die geerbten Variablen statt
   über einen Nachfahren-Selektor je Buttonklasse. Vorher galt sie nur für
   .btn-ghost, weshalb .btn-small daneben zufällig anders gepolstert war. */
.pagehead-actions {
  display: flex; gap: .5rem; flex-wrap: wrap;
  --btn-py: .5rem; --btn-px: .8rem;
}
/* .btn-small, .btn-small.btn-aus und das frühere Sicherheitsnetz
   .btn-small.btn-ghost stehen jetzt im Button-Block oben bzw. haben sich durch
   die Rollen-Reihenfolge erledigt. */

.filterbar {
  display: flex;
  flex-wrap: wrap;
  gap: .6rem;
  align-items: end;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .8rem;
  --btn-py: .5rem; --btn-px: .9rem;
}
.filterbar label { font-size: .8rem; font-weight: 600; display: flex; flex-direction: column; gap: .2rem; }
.filterbar select, .filterbar input { margin-top: 0; padding: .45rem .5rem; min-width: 8rem; }
/* Größe kommt jetzt aus --btn-py/--btn-px an .filterbar. */

.buchliste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.buchzeile {
  display: flex;
  align-items: stretch;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.buchzeile-main {
  flex: 1;
  display: grid;
  grid-template-columns: auto auto 1fr auto auto;
  gap: .1rem .7rem;
  align-items: center;
  padding: .6rem .8rem;
  text-decoration: none;
  color: var(--text);
  min-width: 0;
}
.buchzeile-main:hover { background: var(--surface-2); }
.bz-datum { font-variant-numeric: tabular-nums; color: var(--muted); font-size: .85rem; white-space: nowrap; }
.bz-konto {
  font-variant-numeric: tabular-nums;
  background: var(--surface-2);
  border-radius: 6px;
  padding: .1rem .4rem;
  font-size: .85rem;
}
.bz-text { min-width: 0; display: flex; flex-direction: column; }
.bz-text strong { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bz-text small { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bz-betrag { font-variant-numeric: tabular-nums; font-weight: 700; white-space: nowrap; }
.bz-betrag.plus { color: var(--plus); }
.bz-betrag.minus { color: var(--minus); }
.bz-beleg { font-size: .8rem; color: var(--muted); white-space: nowrap; }
.bz-del button {
  height: 100%;
  border: 0;
  border-left: 1px solid var(--border);
  background: none;
  color: var(--muted);
  padding: 0 .8rem;
  cursor: pointer;
  font-size: 1rem;
}
.bz-del button:hover { background: color-mix(in srgb, var(--err) 12%, transparent); color: var(--err); }

@media (max-width: 620px) {
  .buchzeile-main { grid-template-columns: 1fr auto; grid-auto-rows: auto; row-gap: .15rem; }
  .bz-datum { grid-column: 1; }
  .bz-konto { grid-column: 2; grid-row: 1; justify-self: end; }
  .bz-text { grid-column: 1 / -1; grid-row: 2; }
  .bz-betrag { grid-column: 1; grid-row: 3; }
  .bz-beleg { grid-column: 2; grid-row: 3; justify-self: end; }
}

/* --- Buchungen: Formular ---------------------------- */
.form-card { max-width: 640px; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
@media (max-width: 520px) { .grid2 { grid-template-columns: 1fr; } }

.segmented { display: flex; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.segmented label {
  flex: 1;
  text-align: center;
  padding: .6rem;
  cursor: pointer;
  font-weight: 600;
  background: var(--surface);
}
/* Aktive Seite in der Farbe der jeweiligen Richtung – dieselbe wie die
   Schaltflächen „+ Einnahme" / „+ Ausgabe" auf der Übersicht. Vorher war
   beides grün, obwohl Ausgaben dort rot sind.
   --ein/--aus werden im Dunkelmodus NICHT umgeschrieben, als Fläche mit
   weisser Schrift also in beiden Designs tragfähig (wie .btn-aus). */
.segmented label.on     { background: var(--primary); color: var(--primary-c); }
.segmented label.on-ein { background: var(--ein); color: #fff; }
.segmented label.on-aus { background: var(--aus); color: #fff; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; }

.ust-info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: .2rem;
  font-size: .9rem;
  color: var(--muted);
}
.ust-info strong { color: var(--text); font-variant-numeric: tabular-nums; }

.vorschlag { font-size: .9rem; display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-top: -.4rem; }

/* Hinweis auf die Abschreibung. Bewusst als Hinweis gestaltet, nicht als
   Fehler: die Buchung ist ja nicht falsch, es fehlt nur der zweite Schritt. */
.hinweis-afa {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin: 1rem 0; padding: .7rem .9rem;
  font-size: .9rem; line-height: 1.45;
  border: 1px solid var(--border); border-left: 3px solid var(--warn);
  border-radius: var(--radius); background: var(--surface-2);
}
.hinweis-afa strong { flex: 0 0 auto; }
.hinweis-afa span { flex: 1 1 14rem; min-width: 0; }
.hinweis-afa .btn-small { flex: 0 0 auto; }
/* Folgt der Vorschlag direkt auf ein Label (Buchungsformular, Konto-Feld), darf
   das negative margin-top oben nicht greifen: es glich früher die <small>-Zeile
   mit der Kontobezeichnung aus. Die liegt seit 2026-09-04 absolut IM Feld
   (.feld-zusatz) und belegt keinen Platz mehr im Textfluss – ohne diese Regel
   schöbe sich der Vorschlag unter das Eingabefeld.
   In anlagen/form.php folgt .vorschlag auf ein </div>, dort greift die Regel
   nicht und das ursprüngliche Verhalten bleibt unverändert. */
label + .vorschlag { margin-top: .4rem; }
.chip {
  border: 1px solid var(--primary);
  background-color: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--text);
  border-radius: var(--radius-pill);
  padding: .3rem .8rem;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.chip:hover  { background-color: color-mix(in srgb, var(--primary) 22%, transparent);
               transform: translateY(-1px); }
.chip:active { background-color: color-mix(in srgb, var(--primary) 30%, transparent);
               transform: translateY(1px); }

.beleg-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.beleg-liste li { display: flex; align-items: center; gap: .6rem; font-size: .9rem; }
.beleg-liste form { margin: 0; }

.mehr { border: 1px solid var(--border); border-radius: var(--radius); padding: .3rem .8rem; }
.mehr summary { cursor: pointer; padding: .4rem 0; font-weight: 600; }
.mehr label + label { margin-top: .8rem; }

/* margin-top, damit eine Aktionszeile auch außerhalb von .stack Luft nach oben
   hat (in einer .card kam sie sonst direkt am Text darüber zu liegen).
   Innerhalb von .stack ist der Wert derselbe wie dort – kein doppelter Abstand,
   Margins addieren sich bei gleicher Eigenschaft nicht. */
.form-actions { display: flex; gap: .6rem; flex-wrap: wrap; justify-content: flex-end; margin-top: 1rem; }
.form-actions .btn-ghost { text-decoration: none; }
/* Abbrechen/Zurück steht links, die Aktion (Speichern …) immer rechts. */
.form-actions > a.btn-ghost:first-child,
.form-actions > button.btn-ghost:first-child { margin-right: auto; }

.danger-row { margin-top: 1rem; text-align: right; }
.linkbtn { background: none; border: 0; color: var(--primary); cursor: pointer; font: inherit; text-decoration: underline; padding: 0; }
.linkbtn.danger { color: var(--err); }

/* --- Auswertungen ----------------------------------- */
.quartale { display: flex; gap: .25rem; flex-wrap: wrap; align-items: end; }
.quartale a {
  text-decoration: none;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: .4rem .8rem;
  font-size: .85rem;
}
.quartale a:hover { background-color: var(--surface-2); border-color: var(--primary); }
.quartale a.on {
  background-color: var(--primary);
  color: var(--primary-c);
  border-color: var(--primary);
  box-shadow: var(--btn-shadow);
}

/* Auswertungstabellen. Breite, Rahmenmodell, linksbündige Zellen und die
   Ausrichtung von .num stehen bereits in den globalen `table`- und
   `th, td`-Regeln — hier steht nur, was davon ABWEICHT. Bis zum 2026-09-19
   wiederholte jede Tabellenklasse die Vorgaben vollständig; eine Korrektur
   kam dadurch nie überall an. */
.konten-tab { font-size: .92rem; }
.konten-tab th, .konten-tab td { padding: .4rem .6rem; }
.konten-tab .num { white-space: nowrap; }
.konten-tab tfoot th { border-top: 2px solid var(--border); border-bottom: 0; }
.konten-tab td.minus, .konten-tab .minus { color: var(--minus); }
.konten-tab td.plus, .konten-tab .plus { color: var(--plus); }
.card h3 { font-size: .98rem; margin: 1.1rem 0 .4rem; }

.jv-links { white-space: nowrap; }
.jv-links a { margin-right: .6rem; font-size: .85rem; }

.ergebnis { font-size: 1.05rem; }
.ergebnis.plus strong { color: var(--plus); }
.ergebnis.minus strong { color: var(--minus); }

.zwei-spalten { display: grid; grid-template-columns: 1fr; gap: 1rem; }
@media (min-width: 760px) { .zwei-spalten { grid-template-columns: 1fr 1fr; } }

.toplist { list-style: none; margin: 0; padding: 0; }
.toplist li { display: flex; justify-content: space-between; gap: 1rem; padding: .35rem 0; border-bottom: 1px solid var(--border); }
.toplist .tl-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.toplist .tl-val { font-variant-numeric: tabular-nums; white-space: nowrap; }
.toplist .plus { color: var(--plus); }
.toplist .minus { color: var(--minus); }

/* --- SVG-Diagramm (handgezeichnet) ------------------ */
.chart { position: relative; margin: 0; }
.chart svg { width: 100%; height: auto; display: block; }
.c-axis { stroke: var(--border); stroke-width: 1; }
.c-ein { fill: var(--ein); }
.c-aus { fill: var(--aus); }
.c-kum { fill: none; stroke: #3a72c4; stroke-width: 2; }
.c-kum-dot { fill: #3a72c4; }
.c-mon { fill: var(--muted); font-size: 10px; }
.chart-legende { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: .5rem; font-size: .8rem; }
.lg::before { content: ""; display: inline-block; width: .8em; height: .8em; border-radius: 3px; margin-right: .3em; vertical-align: middle; }
.lg-ein::before { background: var(--ein); }
.lg-aus::before { background: var(--aus); }
.lg-kum::before { background: #3a72c4; border-radius: 50%; }

/* --- EÜR-Druckansicht ------------------------------ */
.druck-toolbar { display: flex; gap: .6rem; margin-bottom: 1rem; }
/* cursor kommt aus der Button-Basis. */
.euer-doc { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 2rem; max-width: 800px; }
.euer-kopf h1 { font-size: 1.4rem; margin-bottom: .6rem; }
.euer-meta { color: var(--muted); font-size: .9rem; }
.euer-doc h2 { font-size: 1.05rem; margin: 1.6rem 0 .5rem; border-bottom: 1px solid var(--border); padding-bottom: .2rem; }
.euer-tab { font-size: .92rem; }
.euer-tab td { padding: .3rem .5rem; border-bottom-color: var(--surface-2); }
.euer-tab td.k { color: var(--muted); width: 4rem; font-variant-numeric: tabular-nums; }
.euer-tab td.num { white-space: nowrap; }
.euer-tab tfoot td { border-top: 2px solid var(--border); font-weight: 700; }
.euer-ergebnis .summe td { border-top: 2px solid var(--text); font-weight: 700; font-size: 1.05rem; }
.euer-fuss { margin-top: 2rem; color: var(--muted); font-size: .8rem; }

@media print {
  /* .flash gehört dazu: „Rechnung 2026-0005 gestellt." ist eine Rückmeldung an
     den Bildschirm, kein Bestandteil des Dokuments. Sie landete im Ausdruck,
     weil RechnungController::stellen mit gesetztem Flash direkt auf die
     Druckansicht weiterleitet. */
  .topbar, .pagefoot, .infobar, .demobar, .adminbar, .footlinks, .flash, .noprint { display: none !important; }
  body { background: #fff; color: #000; }
  .wrap { max-width: none; padding: 0; }
  .euer-doc { border: 0; padding: 0; max-width: none; }
  .euer-doc h2 { border-color: #999; }
  .euer-tab td { border-color: #ddd; }
  @page { margin: 18mm; }
}

/* --- Rechnungen ------------------------------------ */
.re-status {
  display: inline-block;
  padding: .15rem .55rem;
  border-radius: 999px;
  font-size: .78rem;
  font-weight: 600;
  background: var(--surface-2);
  color: var(--muted);
  text-transform: capitalize;
}
.re-status.re-gestellt { background: color-mix(in srgb, #3a72c4 18%, transparent); color: #2f5da3; }
.re-status.re-bezahlt { background: color-mix(in srgb, var(--ok) 18%, transparent); color: var(--ok); }
.re-status.re-storniert { background: color-mix(in srgb, var(--err) 15%, transparent); color: var(--err); }
.re-status.re-teilbezahlt { background: color-mix(in srgb, #d68910 20%, transparent); color: #a9690a; }

/* Fieldset ohne eigene Optik – es dient nur dazu, mit einem einzigen `disabled`
   alle Felder einer gesperrten Rechnung abzuschalten. */
.fs-blank { border: 0; padding: 0; margin: 0; min-width: 0; }
/* Gesperrte Felder sollen LESBAR bleiben. Der Browser-Standard blasst sie so
   stark ab, dass eine bezahlte Rechnung kaum noch zu entziffern wäre. */
.fs-blank[disabled] input,
.fs-blank[disabled] textarea,
.fs-blank[disabled] select {
  color: var(--text);
  background: var(--surface-2);
  opacity: 1;
  -webkit-text-fill-color: var(--text);   /* Safari/iOS ignoriert color sonst */
  cursor: default;
}
.re-gesperrt { margin: 0; }

.re-actions { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.re-actions form { margin: 0; }
.inline-form { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.inline-form input[type="date"] { width: auto; margin: 0; }
.inline-form .check { font-weight: 400; }

/* Eingaberaster: Tabellen, deren Zellen Formularfelder enthalten. Die beiden
   (Rechnungspositionen, Splittbuchung) teilen sich alles bis auf die
   Spaltenbreiten und die Feldbreite. */
.pos-tab, .split-tab { font-size: .9rem; }
.pos-tab th, .pos-tab td,
.split-tab th, .split-tab td { padding: .3rem .35rem; vertical-align: middle; }
.pos-tab input, .pos-tab select,
.split-tab input, .split-tab select { margin: 0; padding: .4rem .45rem; }
.pos-tab .w-menge { width: 5rem; }
.pos-tab .w-einheit { width: 4.5rem; }
.pos-tab .w-preis { width: 7rem; }
.pos-tab .w-ust { width: 4.5rem; }
.pos-tab .num { white-space: nowrap; }
.pos-del { color: var(--muted); }
.pos-del:hover { color: var(--err); }

/* Splittbuchung */
.split-tab input, .split-tab select { width: 100%; }
.split-tab .w-ust { width: 4.5rem; }
.split-tab td.num input { text-align: right; }
.split-del { color: var(--muted); }
.split-del:hover { color: var(--err); }
#split-add { margin-top: .5rem; }
.split-summe { margin: .8rem 0 0; font-size: .9rem; }
.split-summe strong { font-variant-numeric: tabular-nums; }
.split-diff { font-weight: 600; }
.split-diff.bad { color: var(--err); }

/* Summenblock: schmale, rechts ausgerichtete Tabelle mit Abschlusszeile.
   `.summe-tab` (Buchungsformular) und `.re-summe` (Rechnung) waren bis zum
   2026-09-19 Wort für Wort identisch — bis auf `margin-top`. */
.summe-tab, .re-summe { max-width: 22rem; margin-left: auto; }
.summe-tab { margin-top: .8rem; }
.summe-tab td, .re-summe td { padding: .25rem .3rem; }
.summe-tab .s-total td, .re-summe .s-total td {
  border-top: 2px solid var(--text); font-weight: 700; font-size: 1.05rem;
}

/* Rechnungs-Druckansicht */
.rechnung-doc { position: relative; }
/* Logo im TEXTFLUSS statt absolut. Vorher `position:absolute; top:2rem;
   right:2rem` (relativ zu .rechnung-doc): es belegte damit 32–102 px von oben,
   während .re-kopf erst bei 80 px begann — die oberen Zeilen des Metablocks
   (Datum, Leistung, Zahlbar bis) lagen also darunter und waren verdeckt.
   Aufgefallen ist es erst, als das Demo-Konto ein Logo bekam; ohne Logo gab es
   das Element gar nicht. Im Druck wäre es zusätzlich verrutscht, weil
   .euer-doc dort padding:0 bekommt.
   `margin-left:auto` schiebt es an den rechten Rand — der Rest fließt darunter,
   eine Überlagerung ist konstruktiv ausgeschlossen. */
/* Kopfzeile des Rechnungsdokuments: Entwurfsvermerk links, Logo rechts.
   `align-items: flex-start` verhindert, dass ein hohes Logo den Vermerk mittig
   zieht; `min-height: 0`, damit die Zeile ohne Inhalt keinen Platz belegt. */
.re-topline { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
.re-entwurf {
  margin: 0;
  font-weight: 700;
  font-size: 1.05rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--aus);
  border: 2px solid var(--aus);
  border-radius: var(--radius-btn);
  padding: .15rem .6rem;
}
/* Bildschirmgröße entspricht dem Druckkasten unten (55 × 20 mm bei 96 dpi).
   Das hochgeladene Logo ist bereits auf 660 × 240 gerechnet (Bild::logo), hier
   wird also nur noch dargestellt, nicht mehr heruntergerechnet. */
.re-logo { display: block; margin: 0 0 1rem auto; max-height: 76px; max-width: 208px; }

/* Vorschau in den Einstellungen: derselbe Kasten wie im Rechnungskopf, damit
   der Nutzer vor dem Drucken sieht, was herauskommt. */
.logo-vorschau { margin: 0 0 .75rem; }
.logo-vorschau img {
  display: block;
  max-height: 76px; max-width: 208px;
  background: #fff;
  border: 1px dashed var(--border);
  padding: .35rem;
  border-radius: var(--radius-btn);
}
.logo-vorschau figcaption { margin-top: .3rem; font-size: .72rem; color: var(--muted); }
.re-kopf { display: flex; justify-content: space-between; gap: 2rem; flex-wrap: wrap; margin-top: 2rem; }
.re-absender { font-size: .72rem; color: var(--muted); border-bottom: 1px solid var(--border); padding-bottom: .1rem; margin-bottom: .5rem; }
/* Kompaktes Zweispalten-Raster statt einer Tabelle mit Einzelzeilen: dieselben
   Angaben auf etwa der halben Höhe. `auto max-content` lässt die Wertespalte nur
   so breit werden, wie sie muss – die Beschriftungen bleiben linksbündig. */
.re-meta {
  display: grid;
  grid-template-columns: auto max-content;
  gap: .12rem .9rem;
  margin: 0;
  font-size: .88rem;
  align-content: start;
}
.re-meta dt { color: var(--muted); }
.re-meta dd { margin: 0; font-variant-numeric: tabular-nums; text-align: right; }
/* Die Rechnungsnummer ist die wichtigste Angabe des Blocks – hervorheben. */
.re-meta dt:first-of-type, .re-meta dd:first-of-type { font-weight: 700; }
.re-meta dt:first-of-type { color: var(--text); }
.re-titel { font-size: 1.25rem; margin: 1.8rem 0 .6rem; }
.re-text { white-space: pre-line; margin: .6rem 0; }
/* Rechnungspositionen im Druck: eigene Rahmenfarben, sonst wie überall. */
.re-pos { margin: 1rem 0; font-size: .9rem; }
.re-pos th, .re-pos td { padding: .4rem .5rem; border-bottom-color: var(--surface-2); }
.re-pos th { border-bottom-color: var(--text); }
.re-pos .num { white-space: nowrap; }
/* (Regeln siehe Summenblock oben.) */
.re-fuss { margin-top: 2.5rem; padding-top: .5rem; border-top: 1px solid var(--border); font-size: .72rem; color: var(--muted); }

/* Zahlungsblock: Bankdaten links, GiroCode rechts daneben. */
.re-zahlung.hat-qr { display: flex; align-items: flex-start; gap: 1.2rem; }
.re-zahlung.hat-qr .re-text { flex: 1 1 auto; min-width: 0; }
.re-qr { flex: 0 0 auto; margin: .6rem 0 0; text-align: center; }
.re-qr figcaption { margin-top: .25rem; font-size: .68rem; color: var(--muted); }
/* Der Code braucht weißen Grund und schwarze Module – im Dunkelmodus würde
   er sonst zwar dargestellt, aber nicht mehr zuverlässig gescannt. */
/* Das SVG trägt seit dem 2026-09-19 KEIN festes Pixelmaß und kein
   `crispEdges` mehr (`GiroCode::svg`), die Größe steht allein hier. Vorher
   war es 390 px breit bei `max-width: none` — auf dem Telefon lief es damit
   aus der rund 310 px breiten Karte heraus, und `html { overflow-x: hidden }`
   schnitt es ab. Ein halber QR-Code ist keiner.
   Die Ruhezone steckt im SVG selbst (8 Module); der Abstand zur Beschriftung
   hält zusätzlich Inhalt aus dem Randbereich fern. */
.re-qr .qr {
  display: block; background: #fff;
  width: 100%; max-width: 15rem; height: auto; margin: 0 auto;
}
.re-qr figcaption { margin-top: .5rem; }
@media (max-width: 30rem) {
  .re-zahlung.hat-qr { flex-direction: column; align-items: flex-start; }
}

@media print {
  .rechnung-doc { padding: 0; border: 0; }
  .re-kopf { margin-top: 1rem; }
  /* Nie über einen Seitenumbruch zerreißen und nicht aufhellen lassen. */
  .re-zahlung { break-inside: avoid; page-break-inside: avoid; }
  /* Im Druck eine PHYSISCHE Größe: 40 mm ergeben bei 49 Modulen rund 0,8 mm
     je Modul – deutlich über dem, was Scanner brauchen. */
  .re-qr .qr {
    /* `max-width` muss hier ausdrücklich zurück — sonst deckelte die
       Bildschirmregel (15rem) die physischen 40 mm. */
    width: 40mm; height: 40mm; max-width: none;
    print-color-adjust: exact; -webkit-print-color-adjust: exact;
  }
  /* Auch das Logo in PHYSISCHER Größe – vorher stand hier 70px/200px, was der
     Browser beim Drucken selbst umrechnet und je nach Programm unterschiedlich
     ausfällt. Zwei Maßsysteme auf einem Blatt (mm beim QR-Code, px beim Logo)
     waren die eigentliche Ungereimtheit. 55 × 20 mm passen in den Kopf und
     entsprechen den 660 × 240 Pixeln, auf die Bild::logo() rechnet. */
  .re-logo {
    max-width: 55mm; max-height: 20mm;
    print-color-adjust: exact; -webkit-print-color-adjust: exact;
  }
}

/* --- Bestätigungs-Modal ---------------------------- */
.app-dialog {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.25rem;
  max-width: 24rem;
  width: calc(100% - 2rem);
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 10px 40px rgba(0, 0, 0, .3);
}
.app-dialog::backdrop { background: rgba(0, 0, 0, .45); }
.app-dialog form { margin: 0; }
.app-dialog-msg { margin: 0 0 1.2rem; font-size: 1rem; }
.app-dialog-actions {
  display: flex; gap: .6rem; justify-content: flex-end; flex-wrap: wrap;
  --btn-py: .55rem; --btn-px: 1rem;
}
/* .btn-danger ist jetzt eine echte globale Rolle (Button-Block oben) statt nur
   innerhalb von .app-dialog zu gelten – der Name legte das ohnehin nahe. */

/* --- Passwort-Regeln (Registrierung) --------------- */
.pw-check { list-style: none; margin: .4rem 0 0; padding: 0; font-size: .82rem; }
.pw-check li { display: flex; align-items: center; gap: .4rem; color: var(--muted); padding: .1rem 0; }
.pw-check li::before { content: "○"; font-size: .9em; }
.pw-check li.ok { color: var(--ok); }
.pw-check li.ok::before { content: "✓"; }
.pw-strength { height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; margin-top: .4rem; }
.pw-strength span { display: block; height: 100%; width: 0; background: var(--minus); transition: width .15s, background .15s; }
.pw-strength.s1 span { width: 25%; background: #c0392b; }
.pw-strength.s2 span { width: 50%; background: #d68910; }
.pw-strength.s3 span { width: 75%; background: #b7950b; }
.pw-strength.s4 span { width: 100%; background: var(--ok); }
.pw-strength-label { font-size: .78rem; color: var(--muted); margin-top: .2rem; }

/* --- Autovervollständigung ------------------------- */
.ac-wrap { position: relative; display: block; }
/* position:fixed statt absolute – sonst beschneidet jeder Scroll-Container die
   Liste. Konkret: die Positionstabelle der Rechnung steckt in einem
   `overflow-x:auto`-Wrapper, und `overflow-x:auto` erzwingt laut Spezifikation
   auch vertikal `auto`. Die Vorschläge verschwanden dadurch hinter dem Rand,
   was wie „unter dem Button" aussah. Ort und Breite setzt app.js aus der
   Position des Eingabefeldes. */
.ac-list {
  position: fixed;
  z-index: 30;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
  max-height: 15rem;
  overflow-y: auto;
}
.ac-item {
  padding: .5rem .7rem;
  cursor: pointer;
  font-size: .9rem;
  border-bottom: 1px solid var(--surface-2);
}
.ac-item:last-child { border-bottom: 0; }
.ac-item small { color: var(--muted); display: block; }
.ac-item.active, .ac-item:hover { background: var(--surface-2); }
.filterbar .ac-wrap { width: 100%; }
.filterbar .ac-wrap input { width: 100%; }

/* --- Diagramm-Tooltip ----------------------------- */
.c-hit { fill: transparent; cursor: crosshair; }
.chart-tip {
  position: absolute;
  top: 4px;
  z-index: 20;
  pointer-events: none;
  background: var(--text);
  color: var(--bg);
  font-size: .78rem;
  line-height: 1.35;
  padding: .4rem .6rem;
  border-radius: 8px;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .3);
  transform: translateX(-50%);
}
.chart-tip b { font-weight: 600; }

/* --- Design-Umschalter (hell/dunkel) ------------------ */
.themetoggle {
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: 1.1rem;
  line-height: 1;
  padding: .3rem .55rem;
  cursor: pointer;
}
.themetoggle:hover { background: var(--surface-2); }
.topbar .navtoggle { margin-left: auto; }
.mainnav .themetoggle { align-self: flex-start; margin: .15rem 0; }
@media (min-width: 720px) {
  .topbar .navtoggle { display: none; }
  .mainnav .themetoggle { align-self: center; margin: 0 .15rem 0 .5rem; }
}
.mainnav-public .themetoggle { font-size: 1rem; }

/* --- CSV-Import-Assistent ------------------------------- */
.wizard-steps {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .4rem;
  margin: 0 0 .4rem;
  padding: 0;
  font-size: .82rem;
}
.wizard-steps li {
  padding: .25rem .6rem;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--muted);
}
.wizard-steps li.on {
  background: var(--primary);
  color: var(--primary-c);
  font-weight: 600;
}
.mapping-grid {
  display: grid;
  gap: .75rem 1rem;
  grid-template-columns: 1fr;
}
@media (min-width: 620px) {
  .mapping-grid { grid-template-columns: 1fr 1fr; }
}
.tabelle-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tabelle { font-size: .85rem; }
.tabelle th, .tabelle td { white-space: nowrap; }

/* ---- Auffangnetz gegen seitliches Scrollen auf dem Telefon ---------------
   `white-space: nowrap` hält Datum und Beträge zusammen — auf einem schmalen
   Schirm zieht es die Tabelle aber über die Seitenbreite hinaus. Unter 44rem
   darf TEXT deshalb umbrechen; **Zahlen bleiben umbruchfrei** (`.num`), sonst
   stünde „1.234," in der einen und „56 €" in der nächsten Zeile.

   Das gilt bewusst für ALLE Tabellenklassen, nicht nur `.tabelle`: Es gibt
   derer elf (`konten-tab`, `euer-tab`, `summe-tab`, `re-pos` …), und genau
   diese Zersplitterung war der Grund, warum das Problem auf so vielen Seiten
   auftrat. Die Zusammenführung steht als offener Punkt in docs/DESIGN.md —
   bis dahin greift dieses Netz für alle.

   **Es ersetzt `.tabelle-scroll` nicht.** Eine Tabelle aus lauter Zahlen lässt
   sich nicht schmaler umbrechen; die braucht weiterhin einen Scroll-Container
   oder das Kartenlayout. */
@media (max-width: 44rem) {
  .wrap table th, .wrap table td { white-space: normal; }
  .wrap table th.num, .wrap table td.num,
  .wrap table .num, .wrap table .nowrap { white-space: nowrap; }
}
.tabelle-fix td, .tabelle-fix th {
  max-width: 16rem;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Einzelne Zelle kürzen, statt die ganze Tabelle zu begrenzen. Nötig, weil
   .tabelle td generell nowrap ist: ein langer Text (z. B. Konto 4210
   „Miete (unbewegliche Wirtschaftsgüter)") zieht sonst die Tabelle breit und
   erzeugt einen horizontalen Scrollbalken. Volltext steht im title-Attribut. */
.tabelle td.zelle-kurz { max-width: 13rem; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 40rem) { .tabelle td.zelle-kurz { max-width: 8rem; } }

/* Oberhalb des Umbruchpunkts: Text darf umbrechen, statt die Tabelle breiter zu
   machen als ihre Karte. `.tabelle td` ist global `nowrap` – das ist die
   eigentliche Ursache dafür, dass eine einzige lange Bezeichnung (Konto 4210
   „Miete (unbewegliche Wirtschaftsgüter)") die Tabelle über den Rand schiebt.
   Zahlen und Aktionen bleiben umbruchfrei: „01.09.2026" oder „bearbeiten"
   sollen nie mitten im Wort brechen. */
.tabelle-stapel { width: 100%; }
.tabelle-stapel td, .tabelle-stapel th { white-space: normal; }
.tabelle-stapel td.num, .tabelle-stapel th.num,
.tabelle-stapel td.zelle-aktion { white-space: nowrap; }
/* Mit Umbruch braucht es kein Abschneiden mehr – der Volltext bleibt lesbar. */
.tabelle-stapel td.zelle-kurz { overflow: visible; text-overflow: clip; }

/* Responsive Tabelle: unter 44rem wird jede Zeile zu einer Karte, Kopfzeile weg,
   Spaltenname kommt aus data-label. Verhindert seitliches Scrollen unabhängig
   von der Auflösung – und damit auch, dass Aktionen („bearbeiten") außerhalb
   des Sichtfelds landen. Jede <td> braucht ein data-label; Zellen ohne eines
   (Aktionsspalte) bleiben unbeschriftet. */
@media (max-width: 44rem) {
  .tabelle-stapel thead { display: none; }
  .tabelle-stapel,
  .tabelle-stapel tbody,
  .tabelle-stapel tr,
  .tabelle-stapel td { display: block; width: auto; }
  .tabelle-stapel tr {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: .55rem .7rem;
    margin-bottom: .55rem;
  }
  .tabelle-stapel td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    white-space: normal;
    max-width: none;      /* hebt .zelle-kurz auf, hier zählt Lesbarkeit */
    overflow: visible;
    text-align: left;
    padding: .12rem 0;
    border: 0;
  }
  .tabelle-stapel td[data-label]::before {
    content: attr(data-label);
    color: var(--muted);
    flex: 0 0 auto;
    font-size: .8rem;
  }
  .tabelle-stapel td.num { text-align: left; }
  .tabelle-stapel td:empty { display: none; }
  .tabelle-stapel td.zelle-aktion {
    justify-content: flex-start;
    gap: .75rem;
    margin-top: .45rem;
    padding-top: .5rem;
    border-top: 1px solid var(--border);
    /* **Umbruch erzwingen.** Ausserhalb der Kartenansicht steht
       `white-space: nowrap` an dieser Zelle, damit Knöpfe in einer
       Tabellenzeile nicht mitten im Wort brechen. In der Karte ist die Zelle
       aber ein Flex-Container — und ein Flex-Container bricht ohne
       `flex-wrap: wrap` NIE um. Drei Knöpfe („Ausgabe", „Einnahme",
       „löschen") waren damit breiter als jedes Telefon.

       Warum das lange unbemerkt blieb: Die Fahrtenliste hat als einzige nur
       EINEN Knopf je Zeile und passte deshalb. Genau daran ist es
       aufgefallen — dort gab es kein seitliches Scrollen, überall sonst
       schon. */
    flex-wrap: wrap;
    white-space: normal;
  }

  /* ---- Summenzeile (tfoot) in der Kartenansicht ----------------------
     `thead` wird ausgeblendet, `tfoot` NICHT — dort stehen Zahlen, die man
     gerade auf dem Telefon sehen will. Ohne diese Regeln bliebe die Zeile
     eine Tabellenzeile in einem Blocklayout und zöge die Tabelle wieder in
     die Breite; genau daran hing der Anlagen-Scrollbalken.

     `colspan` verliert im Blocklayout seine Wirkung — deshalb werden leere
     Füllzellen ausgeblendet und die Beschriftungszelle zur Überschrift der
     Karte. Die Zahlenzellen holen ihren Namen wie überall aus `data-label`. */
  .tabelle-stapel tfoot,
  .tabelle-stapel tfoot tr,
  .tabelle-stapel tfoot th { display: block; width: auto; }
  .tabelle-stapel tfoot tr {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: .55rem .7rem;
    background: var(--surface-2);
  }
  .tabelle-stapel tfoot th {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    text-align: left;
    padding: .12rem 0;
    border: 0;
    font-weight: 700;
  }
  .tabelle-stapel tfoot th[data-label]::before {
    content: attr(data-label);
    color: var(--muted);
    flex: 0 0 auto;
    font-size: .8rem;
    font-weight: 400;
  }
  /* Die Beschriftungszelle („Summe" / „Summe der Treffer") trägt kein
     data-label und wird zur Überschrift der Summenkarte. */
  .tabelle-stapel tfoot th:not([data-label]) {
    display: block;
    margin-bottom: .3rem;
  }
  /* Leere Füllzellen aus dem colspan-Aufbau – im Blocklayout nur Lücken. */
  .tabelle-stapel tfoot th:empty { display: none; }
}
.tag {
  display: inline-block;
  padding: .12rem .55rem;
  border-radius: var(--radius-pill);
  font-size: .75rem;
  background: var(--surface-2);
  color: var(--muted);
}
/* Feste Werte statt --ok/--err: die beiden Tokens sind im Dunkelmodus aufgehellt
   (Textrolle, gut lesbar auf dunklem Grund). Als FLÄCHE mit weißem Text ergäbe
   das nur 2,66:1. So bleiben die Badges in beiden Modi bei 6,07:1 bzw. 5,52:1. */
.tag-ok { background: #1f6f54; color: #fff; }
.tag-err { background: #b4442b; color: #fff; }
.tag-warn { background: #8a6100; color: #fff; }

/* --- Vergleichsrechner Fahrzeug -------------------------- */
/* Zwei gleich hohe Karten nebeneinander; die günstigere bekommt einen Rand.
   Nur ein Rand, keine Hintergrundfarbe: Die Zahlen sollen sich vergleichen
   lassen, ohne dass eine Seite optisch „richtig" aussieht. */
.fz-paar { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; align-items: start; }
.fz-paar > .card { margin: 0; }
.fz-paar h3 { margin: 0; font-size: 1rem; }
.fz-besser { outline: 2px solid #1f6f54; outline-offset: -2px; }
.fz-gross { font-size: 1.6rem; font-weight: 700; font-variant-numeric: tabular-nums; margin: .2rem 0 0; }
@media (max-width: 720px) { .fz-paar { grid-template-columns: 1fr; } }

/* --- Zahlungsabgleich ------------------------------------ */
/* Zwei Karten nebeneinander mit einem Pfeil dazwischen: Rechnung ← Zahlung.
   Auf dem Handy untereinander, der Pfeil dreht sich dann nach unten — sonst
   zeigt er ins Leere. */
.abgleich-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
.abgleich-paar {
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  padding: .8rem;
}
.abgleich-paar.ab-sicher { border-left-color: #1f6f54; }
.abgleich-paar.ab-wahr   { border-left-color: #8a6100; }
.abgleich-paar.ab-pruef  { border-left-color: #b4442b; }
.ab-kopf { display: flex; flex-wrap: wrap; gap: .35rem; margin-bottom: .5rem; }
.ab-seiten { display: grid; grid-template-columns: 1fr auto 1fr; gap: .8rem; align-items: start; }
.ab-seite { min-width: 0; }
.ab-seite h3 { margin: 0 0 .25rem; font-size: .8rem; text-transform: uppercase;
               letter-spacing: .04em; color: var(--muted); font-weight: 600; }
.ab-seite p { margin: .15rem 0; overflow-wrap: anywhere; }
.ab-zahl { font-variant-numeric: tabular-nums; font-weight: 700; }
.ab-pfeil { align-self: center; font-size: 1.4rem; color: var(--muted); }
.ab-gruende { margin: .5rem 0 0; }
.ab-tat { margin-top: .6rem; display: flex; justify-content: flex-end; }
@media (max-width: 620px) {
  .ab-seiten { grid-template-columns: 1fr; }
  .ab-pfeil { justify-self: start; transform: rotate(90deg); }
}

/* --- Änderungsverlauf ------------------------------------ */
.verlauf-liste { margin: .4rem 0 0; padding-left: 1.1rem; }
.verlauf-liste > li { margin: .35rem 0; }
.verlauf-liste > li strong { display: inline; margin-left: .3rem; }
.verlauf-felder { margin: .15rem 0 0; padding-left: 1.1rem; font-size: .85rem; color: var(--muted); }
.verlauf-felder, .verlauf-felder li { margin: .1rem 0; white-space: normal; }
.verlauf-box > summary { cursor: pointer; }
