/* Belegbot UI v8 — Richtung C „Präzisionswerkzeug".
 *
 * Verbindliche Design-Quelle: docs/superpowers/specs/2026-09-07-ui-relaunch-c-design.md
 * plus Mockup 2026-09-07-ui-relaunch-c-mockup.html. Fast monochrome Palette,
 * ein Kanzleiblau als einziger Akzent, 13px Arbeitsfläche, Mono-Ziffern,
 * Haarlinien-Tabellen, doppelter Abschlussstrich unter Summenzeilen.
 *
 * Hand-written CSS, no build step (Begründung unverändert: kein CDN, kein
 * Node im Docker-Build für ein internes Accounting-UI). Die CSP
 * (belegbot/web/middleware.py, style-src 'self') verbietet style=-Attribute
 * und Inline-Skripte — alles Sichtbare steht hier, die eine dynamische
 * Positionierung (.bbox) setzt app.js über das CSSOM.
 *
 * Klassen-Vertrag: alle von den Templates (W1–W4) benutzten Klassennamen
 * bleiben gültig und sind hier im neuen System gestylt. app.js/Tests hängen
 * an .viewer, .bbox, .kbd-legend, .confirm-*, .field-error, .is-invalid,
 * .htmx-*, .is-dragover, class="active" — nichts davon umbenennen.
 *
 * GUI-Welle 1 (2026-10-27) hat sieben Regelblöcke entfernt, zu denen kein
 * Markup mehr existierte: .btn-sm, .usr-modal(+:target), .usr-close,
 * .tile.is-alert, tr.is-sum, .row-between (samt .umsatz-Kopfzeile, die daran
 * hing) und .filterzeile. Nachgeprüft über templates/, static/*.js und *.py
 * — keine Fundstelle. Wer eine davon wieder braucht, baut sie mit dem
 * Markup zusammen neu auf, statt eine tote Regel wiederzubeleben.
 */

:root {
  /* Papier & Tinte — fast monochrom, ein einziger dunkler Akzent */
  --paper:       #fbfbfa;
  --surface:     #ffffff;
  --surface-2:   #f6f7f8;
  --ink:         #14171a;
  --ink-2:       #565c63;
  --ink-3:       #878d94;
  --rule:        #e4e6e8;   /* Haarlinie */
  --rule-2:      #cbcfd3;   /* betonte Trennung */
  --rule-3:      #9aa0a6;   /* Summen-/Kopflinie */
  --accent:      #1b3a5c;   /* Kanzleiblau, tief und nüchtern */
  --accent-2:    #12293f;
  --accent-tint: #eef2f6;

  /* Signale — sparsam, nur wo etwas zu tun ist */
  --red:         #a32015;
  --red-tint:    #fdf1ef;
  --red-line:    #dfc4c0;
  --amber:       #8a6100;
  --amber-tint:  #fdf6e6;
  --amber-line:  #eadfc2;
  --green:       #17603f;
  --green-tint:  #eef7f2;
  --green-line:  #c3ddd0;

  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  --rail: 212px;   /* Seitenleiste */
  --head: 46px;    /* Kopfzeile   */
  --pad:  12px;    /* Innenabstand der Karten/Panels */
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 13px;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }

h1, h2, h3 { letter-spacing: -0.015em; }
h1 { font-size: 19px; font-weight: 650; }
h2 { font-size: 14px; font-weight: 650; }
h3 { font-size: 12.5px; font-weight: 650; }

::selection { background: var(--accent-tint); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.btn:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible,
summary:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ------------------------------------------------- Mikro-Typografie
 * Die Auszeichnung dieses Entwurfs: Versal-Etiketten in 10px mit
 * Sperrung tragen jede Überschrift zweiter Ordnung, Ziffern stehen in
 * der Mono in fester Breite.
 */

.eyebrow,
th,
.tile .label,
.card > h2, .card > h3 {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.mono { font-family: var(--mono); font-size: 12px; letter-spacing: -0.01em; }
.num { font-family: var(--mono); font-size: 12px; text-align: right; white-space: nowrap; letter-spacing: -0.01em; }
.muted { color: var(--ink-2); }
.dim { color: var(--ink-3); }
.small, .tiny { font-size: 11.5px; line-height: 1.4; }
.text-error { color: var(--red); }
.sub { font-weight: 400; letter-spacing: 0; text-transform: none; font-size: 11.5px; color: var(--ink-3); }

/* ------------------------------------------------------------------ Shell
 * Seitenleiste links, Kopfzeile + Inhalt rechts. Auf schmalen Schirmen
 * wird die Leiste zur horizontalen Zeile oben.
 */

.shell {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr);
  min-height: 100vh;
}

.sidebar {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--rule);
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.brand {
  height: var(--head);
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border-bottom: 1px solid var(--rule);
  color: var(--ink);
}
.brand .mark {
  width: 14px;
  height: 17px;
  background: var(--accent);
  /* gezackte Unterkante — ein abgerissener Bon */
  clip-path: polygon(0 0, 100% 0, 100% 100%, 86% 86%, 71% 100%, 57% 86%, 43% 100%, 29% 86%, 14% 100%, 0 86%);
  flex: 0 0 auto;
}
.brand .name { font-size: 14px; font-weight: 650; letter-spacing: -0.015em; }

.sidebar nav {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 10px 8px;
}
.sidebar nav .group {
  padding: 14px 6px 5px;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.sidebar nav a {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px 5px 10px;
  border-radius: 2px;
  color: var(--ink);
  font-size: 13px;
  line-height: 1.4;
}
.sidebar nav a::before {
  content: "";
  position: absolute;
  left: 0;
  top: 5px;
  bottom: 5px;
  width: 2px;
  background: var(--accent);
  opacity: 0;
}
.sidebar nav a:hover { background: var(--surface-2); text-decoration: none; }
.sidebar nav a.active { background: var(--accent-tint); color: var(--accent); font-weight: 600; }
.sidebar nav a.active::before { opacity: 1; }

.sidebar .spacer { margin-top: auto; }

.userbox {
  border-top: 1px solid var(--rule);
  padding: 10px 14px 12px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  font-size: 11.5px;
  color: var(--ink-2);
}
.userbox strong { color: var(--ink); font-weight: 600; }

.main { min-width: 0; display: flex; flex-direction: column; }

/* ---------------- Kopfzeile mit Mandanten-Umschalter ---------------- */

.head {
  min-height: var(--head);
  flex: 0 0 auto;
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 20px;
  position: sticky;
  top: 0;
  z-index: 20;
}

/* <details>-Element statt JS-Menü: die CSP verbietet Inline-Skripte, und
 * ein Umschalter, der ohne JS nicht aufgeht, wäre genau dann kaputt, wenn
 * ohnehin etwas kaputt ist. */
.switcher { position: relative; }
.switcher > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 8px;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  padding: 3px 9px 3px 10px;
  background: var(--surface);
  white-space: nowrap;
}
.switcher > summary::-webkit-details-marker { display: none; }
.switcher > summary:hover { border-color: var(--accent); }
.switcher .lbl {
  font-size: 9.5px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.switcher .val { font-size: 13px; font-weight: 600; letter-spacing: -0.01em; }
.switcher .caret { color: var(--ink-3); font-size: 9px; }

.switcher-menu {
  position: absolute;
  z-index: 30;
  left: 0;
  top: 100%;
  min-width: 240px;
  margin-top: 4px;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  box-shadow: 0 8px 24px rgba(20, 23, 26, 0.12);
}
.switcher-menu a { padding: 5px 8px; border-radius: 2px; color: var(--ink); }
.switcher-menu a:hover { background: var(--surface-2); text-decoration: none; }
.switcher-menu a.active { background: var(--accent-tint); color: var(--accent); font-weight: 600; }

/* ------------------------------------------------------------------ Layout */

.wrap { padding: 20px 20px 40px; max-width: 1240px; width: 100%; }
.wrap-narrow { max-width: 640px; margin: 0 auto; padding: 1rem; }

.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--rule-2);
}
.page-head .eyebrow { display: block; }
.page-title {
  margin: 2px 0 0;
  font-size: 19px;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.split {
  display: grid;
  grid-template-columns: minmax(320px, 45%) 1fr;
  gap: 16px;
  align-items: start;
}
@media (max-width: 1100px) { .split { grid-template-columns: 1fr; } }

.row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.row-top { align-items: flex-start; }
.row-end { margin-left: auto; }
.row-tight { gap: 6px; }
.stack > * + * { margin-top: 12px; }
.grow { flex: 1 1 auto; }
.self-end { align-self: flex-end; }

/* ------------------------------------------------- Messleiste (Kacheln)
 * Signatur des Entwurfs: ein durchgehender Kennzahlen-Streifen, nur durch
 * Haarlinien geteilt — keine schwebenden Kacheln. .strip ist das neue
 * Markup (W1), .tiles trägt die Bestandsseiten in derselben Optik.
 */

.strip, .tiles {
  display: grid;
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  margin-bottom: 18px;
}
.strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.tiles { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0; }

.tile {
  display: block;
  padding: 11px 14px 12px;
  border-left: 1px solid var(--rule);
  color: inherit;
  min-width: 0;
}
.strip > .tile:first-child, .tiles > .tile:first-child { border-left: 0; }
/* Bestandsseiten stapeln .card auf .tile — in der Leiste zählt die Zelle,
 * nicht die Karte. */
.tiles > .card.tile, .strip > .card.tile {
  border-top: 0;
  border-right: 0;
  border-bottom: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 11px 14px 12px;
}
a.tile:hover { background: var(--surface-2); text-decoration: none; }
.tile .label { display: block; margin-bottom: 5px; }
.tile .value {
  display: block;
  font-family: var(--mono);
  font-size: 23px;
  font-weight: 600;
  letter-spacing: -0.035em;
  line-height: 1.1;
  color: var(--ink);
  white-space: nowrap;
}
.tile .unit { font-size: 13px; font-weight: 400; color: var(--ink-3); letter-spacing: 0; margin-left: 2px; }
.tile .foot {
  display: block;
  margin-top: 6px;
  font-size: 11.5px;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tile .foot .sep { color: var(--rule-2); margin: 0 5px; }
/* Bestandsmarkup stellt den Wert vor das Etikett — dieselbe Leiste,
 * andere Reihenfolge; beides trägt. */
.tile .value + .label { margin-bottom: 0; margin-top: 2px; }
.tile.is-error .value, .tile.is-error .label { color: var(--red); }
.tile.is-ok .value { color: var(--green); }

/* Tagesbalken: reine CSS-Rechtecke (Höhen setzt app.js/Template über Klassen
 * oder gar nicht — kein style=-Attribut). */
.bars { display: flex; align-items: flex-end; gap: 2px; height: 16px; margin-top: 8px; }
.bars i { flex: 1 1 0; background: var(--rule-2); min-height: 1px; }
.bars i.hi { background: var(--accent); }

/* ------------------------------------------------------------- Karte/Panel
 * .card ist das Panel des Systems: Haarlinienrahmen, 2px-Ecken, keine
 * Schatten. Eine direkt an erster Stelle stehende h2/h3 wird zum
 * Abschnittskopf über die volle Breite; direkte Kind-Tabellen laufen
 * randlos bis an die Panelkante.
 */

.card {
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  padding: var(--pad);
}
.card > h2:first-child, .card > h3:first-child {
  margin: calc(-1 * var(--pad)) calc(-1 * var(--pad)) var(--pad);
  padding: 9px var(--pad);
  background: var(--surface-2);
  border-bottom: 1px solid var(--rule);
  border-radius: 2px 2px 0 0;
}
.card h2, .card h3 { margin-top: 0; margin-bottom: 8px; }

.card > table, .card > .table-scroll {
  margin-left: calc(-1 * var(--pad));
  margin-right: calc(-1 * var(--pad));
}
.card > table { width: calc(100% + 2 * var(--pad)); }
.card > table:last-child, .card > .table-scroll:last-child { margin-bottom: calc(-1 * var(--pad)); }
.card > h2:first-child + table, .card > h3:first-child + table,
.card > h2:first-child + .table-scroll, .card > h3:first-child + .table-scroll {
  margin-top: calc(-1 * var(--pad));
}

hr { border: 0; border-top: 1px solid var(--rule); margin: 10px 0; }

/* --------------------------------------------------------------- Tabellen
 * Haarlinien, kein Zebra, Zahlen rechtsbündig in der Mono. Kopfzeilen
 * kleben im Scroll-Container. Summenzeilen tragen den doppelten
 * Abschlussstrich — die Buchhalter-Signatur.
 */

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td {
  padding: 5px 10px;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  vertical-align: top;
}
th:first-child, td:first-child { padding-left: var(--pad); }
th:last-child, td:last-child { padding-right: var(--pad); }
thead th {
  padding-top: 7px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--rule-3);
  background: var(--surface);
  position: sticky;
  top: 0;
  z-index: 1;
  white-space: nowrap;
}
thead th.num { text-align: right; }
td.num, th.num { text-align: right; }
tbody tr:last-child > td { border-bottom: 0; }
tbody tr:hover { background: var(--surface-2); }

/* Doppelter Abschlussstrich (3px double) unter dem letzten Posten: die
 * Summenzeile ist als Abschluss lesbar, nicht als weiterer Posten. */
tr.is-total > td, tr.is-total > th {
  border-top: 3px double var(--rule-3);
  font-weight: 600;
  background: var(--surface-2);
}

.table-scroll { overflow: auto; max-height: 72vh; }

.col-severity { width: 6rem; }
.col-code { width: 12rem; }
.col-actions { width: 14rem; }

/* ----------------------------------------------------------------- Badges */

.badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 0 5px;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  color: var(--ink-2);
  background: var(--surface);
  white-space: nowrap;
}
.badge.is-error { color: var(--red); border-color: var(--red-line); background: var(--red-tint); }
.badge.is-warn { color: var(--amber); border-color: var(--amber-line); background: var(--amber-tint); }
.badge.is-ok { color: var(--green); border-color: var(--green-line); background: var(--green-tint); }
.badge.is-accent { color: var(--accent); border-color: var(--rule-2); background: var(--accent-tint); }

/* ----------------------------------------------------------------- Knöpfe */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  padding: 4px 11px;
  border: 1px solid var(--rule-2);
  background: var(--surface);
  color: var(--ink);
  border-radius: 2px;
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.btn:disabled, .btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.btn-primary, .btn.is-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover, .btn.is-primary:hover { background: var(--accent-2); border-color: var(--accent-2); color: #fff; }
.btn-danger { background: var(--surface); border-color: var(--red-line); color: var(--red); }
.btn-danger:hover { border-color: var(--red); color: var(--red); background: var(--red-tint); }
/* Zustimmung zu etwas Zerstörendem: gefüllt wie .btn-primary, damit sie im
 * Rückfrage-Dialog als Hauptknopf lesbar ist — aber in der Signalfarbe. */
.btn-danger-strong { background: var(--red); border-color: var(--red); color: #fff; }
.btn-danger-strong:hover { background: #8a1b12; border-color: #8a1b12; color: #fff; }

/* -------------------------------------------------------------- Formulare */

input:not([type]), input[type="text"], input[type="password"], input[type="date"],
input[type="search"], input[type="number"], input[type="email"], select, textarea {
  font: inherit;
  font-size: 12px;
  padding: 4px 8px;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  background: var(--surface);
  color: var(--ink);
  width: 100%;
  min-width: 0;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-tint);
  outline: none;
}
label { font-weight: 500; }

/* Feldgruppe: Etikett über dem Eingabefeld, feste Mindestbreite in
 * Filterzeilen (Export, Bank). */
.field { display: flex; flex-direction: column; gap: 3px; min-width: 10rem; }
.field > label, .field .k {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}

input.input-wide { width: 18rem; }
input.input-narrow { width: 10rem; }

/* ------------------------------------------------------------- Meldungen */

.note {
  border: 1px solid var(--rule-2);
  border-left: 2px solid var(--rule-3);
  background: var(--surface-2);
  padding: 8px 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
  border-radius: 0 2px 2px 0;
}
.note strong { color: var(--ink); }
.note.is-error { border-left-color: var(--red); background: var(--red-tint); border-color: var(--red-line); color: var(--ink); }
.note.is-error strong { color: var(--red); }
.note.is-warn { border-left-color: var(--amber); background: var(--amber-tint); border-color: var(--amber-line); color: var(--ink); }
.note.is-warn strong { color: var(--amber); }
.note.is-ok { border-left-color: var(--green); background: var(--green-tint); border-color: var(--green-line); color: var(--ink); }
.note.is-ok strong { color: var(--green); }

/* -------------------------------------------------------------- Belegbild */

.viewer {
  position: relative;
  overflow: auto;
  max-height: 78vh;
  background: var(--ink);
  border: 1px solid var(--rule-2);
  border-radius: 2px;
}
.viewer img { display: block; width: 100%; transform-origin: top left; }
.viewer-canvas { position: relative; }
.viewer .bbox {
  position: absolute;
  border: 2px solid #ffd400;
  box-shadow: 0 0 0 9999px rgba(20, 23, 26, 0.45);
  pointer-events: none;
}
.viewer-bar { display: flex; gap: 6px; align-items: center; padding-bottom: 8px; }
.viewer-bar h2 { margin: 0; font-size: 10px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink-3); }
.caption { font-size: 11.5px; color: var(--ink-3); margin: 5px 0 0; font-family: var(--mono); }

/* ------------------------------------------------------------ Feldeditor */

.field-row { display: grid; grid-template-columns: 11rem 1fr auto; gap: 8px; align-items: center; }
.field-row + .field-row { margin-top: 5px; }
.field-row label {
  color: var(--ink-3);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.field-row input { font-family: var(--mono); }
.field-row.is-doubtful input { border-color: var(--amber); background: var(--amber-tint); }
.field-row.is-flagged input { border-color: var(--red); background: var(--red-tint); }
.field-row .meta { font-size: 11px; color: var(--ink-3); white-space: nowrap; font-family: var(--mono); }
.field-hint { font-size: 11.5px; color: var(--red); grid-column: 2 / -1; }

/* ----------------------------------------------------------------- Modal */

dialog {
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  box-shadow: 0 8px 24px rgba(20, 23, 26, 0.16);
  padding: 16px 18px;
  max-width: 32rem;
  width: 90%;
  color: var(--ink);
}
dialog::backdrop { background: rgba(20, 23, 26, 0.5); }

/* Rückfrage-Dialog (base.html, gefüllt von app.js) — Ersatz für
 * window.confirm(). Text wird mit textContent gesetzt, nie mit innerHTML. */
.confirm { max-width: 30rem; }
.confirm-title { margin: 0 0 6px; font-size: 14px; font-weight: 650; }
.confirm.is-danger .confirm-title { color: var(--red); }
.confirm-text { margin: 0; font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; }
.confirm-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }

/* ------------------------------------------------------- Tastatur-Legende
 * Einklappbar (<details>), aber per .kbd-legend weiterhin das Ziel der
 * "?"-Taste in app.js. Der Verantwortungs-Hinweis bleibt immer sichtbar.
 */

.kbd-legend {
  margin-top: 22px;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
  font-size: 11.5px;
  color: var(--ink-3);
}
.kbd-legend summary {
  cursor: pointer;
  user-select: none;
  list-style: none;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.kbd-legend summary::-webkit-details-marker { display: none; }
.kbd-legend summary:hover { color: var(--ink); }
.kbd-legend .keys { display: flex; gap: 12px; flex-wrap: wrap; padding-top: 6px; }
.kbd-legend > span { margin-left: auto; color: var(--ink-2); }
kbd {
  font-family: var(--mono);
  font-size: 10.5px;
  border: 1px solid var(--rule-2);
  border-bottom-width: 2px;
  border-radius: 2px;
  padding: 0 4px;
  background: var(--surface);
  color: var(--ink-2);
}

/* ------------------------------------------------------------------ HTMX */

.htmx-request { opacity: 0.55; }
/* HTMX-Standardregeln — sonst injiziert htmx sie als Inline-Stylesheet, was
 * die CSP blockt (deshalb includeIndicatorStyles:false in base.html). */
.htmx-indicator { opacity: 0; transition: opacity 200ms ease-in; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

/* ------------------------------------------------------------- Utilities
 * Ersetzen style="…"-Attribute: die CSP sagt style-src 'self'.
 */

.flush { margin: 0; }
.flush-top { margin-top: 0; }
.flush-bottom { margin-bottom: 0; }
.mt-1 { margin-top: 6px; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 10px; }
.mt-4 { margin-top: 16px; }
.mb-1 { margin-bottom: 6px; }
.mb-2 { margin-bottom: 8px; }
.mb-3 { margin-bottom: 12px; }

/* Honigtopf des Registrierungsformulars (W2-6). Bewusst `display: none` und
   nicht `.visually-hidden`: Letztere Klasse hält den Inhalt für Screenreader
   lesbar — genau das darf eine Bot-Falle nicht, sonst füllt ein blinder
   Mensch sie aus und seine Registrierung verschwindet lautlos. Hier als
   Klasse und nicht als style-Attribut, weil die CSP Inline-Styles verbietet
   (belegbot.web.middleware). */
.honeypot { display: none; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------- Upload */

.dropzone {
  display: block;
  padding: 18px 12px;
  border: 1px dashed var(--rule-3);
  border-radius: 2px;
  text-align: center;
  color: var(--ink-2);
  cursor: pointer;
  font-size: 12px;
}
.dropzone:hover, .dropzone:focus-within { border-color: var(--accent); color: var(--ink); }
.dropzone.is-dragover { border-color: var(--accent); background: var(--accent-tint); color: var(--accent); }
.dropzone input[type="file"] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
}
.upload-results { list-style: none; padding: 0; margin: 0; display: grid; gap: 3px; }

/* --------------------------------------------- Betreiber-Dashboard (SVG)
 * Server-seitig gerendertes Inline-SVG (belegbot/web/svg.py). Farben und
 * Schrift kommen aus Klassen statt style-Attributen.
 */

.chart { width: 100%; height: auto; display: block; }
.chart .chart-bar { fill: var(--accent); }
.chart .chart-track { fill: var(--accent-tint); }
.chart .chart-label { fill: var(--ink-3); font-size: 11px; font-family: inherit; }
.chart .chart-value {
  fill: var(--ink);
  font-size: 11px;
  font-family: inherit;
  font-variant-numeric: tabular-nums;
}
.chart .chart-line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; }
.chart .chart-area { fill: var(--accent-tint); }
.chart .chart-dot { fill: var(--accent); }
.chart .chart-axis { stroke: var(--rule-2); stroke-width: 1; }

/* Zeitraum-Umschalter: Links als Segmente. */
.zeitraum {
  display: inline-flex;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  background: var(--surface);
}
.zeitraum a { padding: 3px 10px; font-size: 12px; color: var(--ink-2); border-left: 1px solid var(--rule); }
.zeitraum a:first-child { border-left: 0; }
.zeitraum a:hover { text-decoration: none; background: var(--surface-2); }
.zeitraum a.active { background: var(--accent-tint); color: var(--accent); font-weight: 600; }

.verlauf-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
}

/* ----------------------------------------------------------- Kasse (W2)
 * Statuszeile, Aufklapper und Kassenbuch-Scroller der Bestandsseite —
 * gestylt im neuen System, das Markup zieht in Welle 2 nach.
 *
 * ``details.hilfe`` hieß bis GUI-Welle 3e ``details.kasse-fold``. Der Name
 * stammte von der ersten Seite, die den Aufklapper bekam, und stimmte schon
 * nicht mehr, als benutzer.html ihn mitbenutzte: es ist der Hilfe-Layer des
 * ganzen Hauses — Prosa, die beim Einrichten erklärt und danach nur Platz
 * kostet. Reine Umbenennung, kein Verhalten geändert.
 */


/* ``details.panel`` teilt sich jede dieser Regeln: es ist derselbe
   Aufklapper, nur mit einem Formular statt einem Hilfetext darin (eigener
   Abschnitt weiter unten erklärt, warum er trotzdem anders heißt). Kopierte
   statt geteilter Regeln hatten in Welle 3e genau einen Tag lang dazu
   geführt, dass dem Panel der Chevron fehlte — bei unterdrücktem nativem
   Marker also jede Andeutung, dass man hier klicken kann. */
details.hilfe > summary,
details.panel > summary {
  cursor: pointer;
  user-select: none;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
details.hilfe > summary::-webkit-details-marker,
details.panel > summary::-webkit-details-marker { display: none; }
details.hilfe > summary::before,
details.panel > summary::before {
  content: "›";
  font-size: 13px;
  color: var(--ink-3);
  transform: rotate(0deg);
  transition: transform 120ms ease;
  display: inline-block;
  width: 8px;
}
details.hilfe[open] > summary::before,
details.panel[open] > summary::before { transform: rotate(90deg); }
details.hilfe[open] > summary,
details.panel[open] > summary { margin-bottom: 10px; }
/* Ein ``.flush``-Absatz verzichtet auf seinen unteren Abstand, weil er in
   seiner alten Umgebung der letzte vor der Kartenkante war. Aufgeklappt in
   einem ``details.hilfe`` ist er das nicht mehr — darunter kommt der
   Absenden-Knopf, und der soll nicht am Text kleben. */
details.hilfe[open] > :last-child { margin-bottom: 8px; }
details.hilfe > summary:hover,
details.panel > summary:hover { color: var(--ink); }

.kasse-buch-head {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 10px;
}
.kasse-buch-head h2 { margin: 0; }
.kasse-export { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; margin: 0; }
.kasse-export label { font-size: 10px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--ink-3); }
.kasse-export input[type="date"] { display: block; width: auto; }

.kasse-buch-scroll {
  max-height: 62vh;
  overflow: auto;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
}
.kasse-buch-scroll > table { margin: 0; }

/* Mandanten-Mehrfachauswahl beim Benutzer-Anlegen. */
.check-list {
  display: grid;
  gap: 2px;
  max-height: 9rem;
  overflow: auto;
  padding: 5px 8px;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  background: var(--surface);
}
.check-list label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 400;
  color: var(--ink);
  margin: 0;
}

/* ---------------------------------------------------- Benutzer-Reiter (W3) */

.usr-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: flex-end;
  justify-content: space-between;
  margin-bottom: 10px;
}
.usr-scroll {
  max-height: 60vh;
  overflow: auto;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
}
.usr-scroll > table { margin: 0; }

.usr-head,
.usr-list > details > summary {
  display: grid;
  grid-template-columns: 2fr 1fr 1.3fr 1.6fr auto;
  gap: 10px;
  align-items: center;
}
.usr-head {
  padding: 7px 10px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1px solid var(--rule-3);
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface);
}
.usr-list > details { border-bottom: 1px solid var(--rule); }
.usr-list > details > summary {
  padding: 7px 10px;
  cursor: pointer;
  list-style: none;
  font-size: 13px;
}
.usr-list > details > summary::-webkit-details-marker { display: none; }
.usr-list > details > summary::after {
  content: "Bearbeiten ›";
  color: var(--accent);
  font-size: 11.5px;
  white-space: nowrap;
  text-align: right;
}
.usr-list > details[open] > summary { background: var(--surface-2); }
.usr-list > details[open] > summary::after { content: "schließen ‹"; }
.usr-panel { padding: 8px 12px 14px; background: var(--surface-2); border-top: 1px solid var(--rule); }
@media (max-width: 720px) {
  .usr-head { display: none; }
  .usr-list > details > summary { grid-template-columns: 1fr auto; }
}

/* ---------------------------------------------------- Feldmeldungen (app.js)
 * Ersetzen die Sprechblase des Browsers. Am Dateiende, damit sie bei
 * Spezifitäts-Gleichstand gewinnen.
 */

.field-error {
  margin: 3px 0 0;
  color: var(--red);
  font-size: 11.5px;
  line-height: 1.35;
  grid-column: 2 / -1;
}
input.is-invalid, select.is-invalid, textarea.is-invalid {
  border-color: var(--red);
  background: var(--red-tint);
}

/* --------------------------------------------------- Login (public.html)
 * Self-Service-Seiten (Registrierung, Passwort-Reset, Einladung) im
 * login-*-Namensraum; die Bon-Abrisskante bleibt die stille Signatur.
 */

.login-main { margin-top: 12vh; }
.login-card {
  position: relative;
  border-radius: 2px 2px 0 0;
  border-bottom: 0;
  padding: 24px 26px 20px;
  box-shadow: 0 8px 24px rgba(20, 23, 26, 0.08);
}
.login-card::after {
  content: "";
  position: absolute;
  top: 100%;
  left: -1px;
  right: -1px;
  height: 7px;
  background: var(--surface);
  -webkit-mask: conic-gradient(from 135deg at 50% 0, #000 90deg, #0000 0) top / 18px 7px repeat-x;
  mask: conic-gradient(from 135deg at 50% 0, #000 90deg, #0000 0) top / 18px 7px repeat-x;
}
.login-title {
  margin: 0;
  font-size: 19px;
  font-weight: 650;
  letter-spacing: -0.02em;
  display: flex;
  align-items: center;
  gap: 8px;
}
.login-title::before {
  content: "";
  width: 16px;
  height: 19px;
  background: var(--accent);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 86% 86%, 71% 100%, 57% 86%, 43% 100%, 29% 86%, 14% 100%, 0 86%);
}
.login-foot { margin: 14px 0 0; text-align: center; font-size: 11.5px; color: var(--ink-2); }

/* ------------------------------------------------ Login-Karte (login.html)
 * signin-* bleibt der Login-Seite vorbehalten (Test prüft das Markup),
 * jetzt in der C-Farbwelt: nüchtern, 2px-Ecken, ein Akzent.
 */

.signin-body { min-height: 100vh; }
.signin-main {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1rem;
}
.signin-card {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  padding: 28px 26px 22px;
  box-shadow: 0 8px 24px rgba(20, 23, 26, 0.08);
}
.signin-head { display: flex; align-items: center; gap: 10px; }
.signin-badge {
  flex: 0 0 auto;
  width: 34px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 86% 88%, 71% 100%, 57% 88%, 43% 100%, 29% 88%, 14% 100%, 0 88%);
  color: #fff;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  padding-bottom: 4px;
}
.signin-title { margin: 0; font-size: 21px; font-weight: 650; letter-spacing: -0.02em; color: var(--ink); }
.signin-sub { margin: 10px 0 0; color: var(--ink-2); font-size: 12px; line-height: 1.5; }
.signin-note { margin-top: 14px; }
.signin-form { margin-top: 18px; }
.signin-field + .signin-field { margin-top: 12px; }
.signin-label {
  display: block;
  margin-bottom: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
input.signin-input {
  width: 100%;
  padding: 8px 10px;
  font-size: 13px;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  background: var(--surface);
  color: var(--ink);
}
input.signin-input::placeholder { color: var(--ink-3); opacity: 1; }
.signin-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 14px;
  font-size: 12px;
}
.signin-check {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
}
.signin-check input[type="checkbox"] {
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.signin-link { color: var(--accent); font-weight: 500; }
.signin-hint { margin: 5px 0 0; font-size: 11px; line-height: 1.45; color: var(--ink-3); }
.signin-hint + .signin-submit { margin-top: 12px; }
.signin-submit {
  display: block;
  width: 100%;
  margin-top: 18px;
  padding: 9px 12px;
  border: 1px solid var(--accent);
  border-radius: 2px;
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.signin-submit:hover { background: var(--accent-2); border-color: var(--accent-2); }
.signin-foot { margin: 14px 0 0; text-align: center; font-size: 11.5px; color: var(--ink-2); }
@media (max-width: 520px) {
  .signin-main { padding: 1.25rem 0.9rem; align-items: flex-start; }
  .signin-card { padding: 20px 16px 16px; }
}

/* ------------------------------------------------------ Schmalere Fenster */

@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar { position: static; height: auto; border-right: 0; border-bottom: 1px solid var(--rule-2); }
  .sidebar nav { flex-direction: row; flex-wrap: wrap; gap: 2px; padding: 8px; }
  .sidebar nav .group { width: 100%; padding: 6px 4px 2px; }
  .sidebar nav a { padding: 4px 9px; }
  .sidebar nav a::before { display: none; }
  .userbox { flex-direction: row; align-items: center; flex-wrap: wrap; }
  .head { padding: 0 14px; gap: 10px; position: static; }
  .wrap { padding: 14px 14px 32px; }
  .strip { grid-template-columns: 1fr 1fr; }
  .strip > .tile:nth-child(odd) { border-left: 0; }
  .strip > .tile:nth-child(n+3) { border-top: 1px solid var(--rule); }
  .kbd-legend > span { margin-left: 0; }
}

/* === W2: Kasse/Bank/OP/Export ===
 * Page-scoped Ergänzungen der Welle 2 — nur additiv, am Dateiende
 * (Merge-Disziplin: W3/W4 hängen ihre Abschnitte genauso an).
 * Quelle: Mockup C, Ansicht „Kasse" (Statuszeile, Statusrinne, .line/.acct,
 * key-Spalte) plus die Panel-Köpfe der <details>-Aufklapper.
 */

/* ---- Statuszeile (Kasse): ein Messstreifen aus Segmenten, wie .strip ---- */
.statusline {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  background: var(--surface);
}
.statusline > span {
  padding: 8px 14px;
  border-left: 1px solid var(--rule);
  font-size: 12px;
  color: var(--ink-2);
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.statusline > span:first-child { border-left: 0; }
.statusline b {
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.statusline .is-red { color: var(--red); }
.statusline .is-red b { color: var(--red); }
.statusline .push { margin-left: auto; border-left: 1px solid var(--rule); }
@media (max-width: 900px) {
  .statusline .push { margin-left: 0; }
}

/* ---- Klärzeile: Statusrinne an der Kante statt Alarm-Rot --------------- */
tr.is-error > td { background: var(--red-tint); border-bottom-color: var(--red-line); }
tr.is-error > td:first-child { box-shadow: inset 3px 0 0 var(--red); }
tbody tr.is-error:hover > td { background: #fbe9e6; }
tr.is-error .flag { color: var(--red); font-weight: 600; }

/* Fehlertext als durchlaufende Anmerkungszeile unter der Klärzeile — die
 * Zahlenzeile bleibt niedrig, die Begründung bekommt die volle Breite. */
tr.kb-anmerkung > td {
  padding-top: 4px;
  padding-bottom: 7px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-2);
}
tbody tr.kb-anmerkung:hover { background: transparent; }
tr.kb-anmerkung.is-flagged > td {
  background: var(--red-tint);
  border-bottom-color: var(--red-line);
  box-shadow: inset 3px 0 0 var(--red);
  color: var(--ink);
}
tbody tr.kb-anmerkung.is-flagged:hover > td { background: var(--red-tint); }
tr.kb-anmerkung strong { color: var(--red); }
/* Die Klärzeile gibt ihre Unterkante an die Anmerkung weiter. */
tr.hat-anmerkung > td { border-bottom: 0; }

/* ---- Kassenbuch: Kontensplit als Mono-Block, Bar-Spalte als Träger ----- */
.line {
  display: block;
  white-space: nowrap;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: -0.01em;
}
.line + .line { margin-top: 2px; }
.acct { font-family: var(--mono); font-size: 11px; color: var(--ink-3); margin-right: 6px; }

td.key, th.key { background: var(--accent-tint); }
thead th.key { background: var(--accent-tint); }
tbody tr:hover td.key { background: #e6ecf2; }
tr.is-error > td.key { background: #f7e7e3; }
tr.is-total > td.key { background: var(--accent-tint); }

.c-hint { width: 250px; min-width: 250px; }

/* ---- Panel-Kopf über dem Kassenbuch: Titel, Zeitraum, Export-Knopf ----- */
.card > .kasse-buch-head {
  margin: calc(-1 * var(--pad)) calc(-1 * var(--pad)) var(--pad);
  padding: 7px var(--pad);
  min-height: 40px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--rule);
  border-radius: 2px 2px 0 0;
  align-items: center;
}
.kasse-export label { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.kasse-export .btn { margin-left: 4px; }

/* ---- <details class="card hilfe|panel">: Aufklapper mit Panel-Kopf ---- */
details.card.hilfe > summary,
details.card.panel > summary {
  margin: calc(-1 * var(--pad)) calc(-1 * var(--pad));
  padding: 9px var(--pad);
  min-height: 34px;
  align-items: center;
  background: var(--surface-2);
  border-radius: 2px;
}
details.card.hilfe[open] > summary,
details.card.panel[open] > summary {
  margin-bottom: var(--pad);
  border-bottom: 1px solid var(--rule);
  border-radius: 2px 2px 0 0;
}
details.card.hilfe > summary:hover,
details.card.panel > summary:hover { background: var(--accent-tint); }

/* ---- <details class="panel">: ein eingeklapptes Formular, keine Hilfe --
 * **Optisch identisch zu ``details.hilfe``** — und zwar, weil es sich jede
 * Regel mit ihm teilt (Selektorlisten weiter oben, Zeile ~787 ff.) statt
 * sie zu kopieren. Eine Kopie wäre genau der Fehler, den Welle 3e kurz
 * hatte: sie vergaß den Chevron, und ein Aufklapper ohne Andeutung ist
 * keiner.
 *
 * Getrennt benannt ist er trotzdem, weil der Inhalt ein **Bedienelement**
 * ist — „Neuer Benutzer", „Mitarbeiter einladen". Das ist keine Formsache:
 * ``tests/test_web_queue.py::HILFE_FOLDS`` zählt die Hilfetexte je Seite,
 * damit niemand unbemerkt einen Warnhinweis wegfaltet. Zählte ein
 * Anlegeformular dort mit, wäre die Zahl keine Aussage mehr über Prosa.
 */


/* ---- OP-Verfolgung: Aufklapper in der Tabelle als stille Links --------- */
td > details > summary.small {
  cursor: pointer;
  user-select: none;
  list-style: none;
  color: var(--accent);
}
td > details > summary.small::before { content: "› "; color: var(--ink-3); }
td > details[open] > summary.small::before { content: "‹ "; }
td > details > summary.small::-webkit-details-marker { display: none; }
td > details[open] > summary.small { margin-bottom: 6px; }

/* „Als erledigt markiert": die h2 wohnt im summary — Kopf bleibt Kopf. */
.card > details > summary { cursor: pointer; list-style: none; }
.card > details > summary::-webkit-details-marker { display: none; }
.card > details > summary h2 { display: inline; margin: 0; }
.card > details > summary:hover h2 { color: var(--accent); }

/* === W3: Verwaltung/Admin === */

/* Fakten-Leiste: Tarif-Konditionen, Kontostände u. Ä. als Mini-Messleiste —
 * dieselbe Sprache wie .strip/.tile, nur eine Nummer kleiner, damit sie in
 * ein Panel passt. Kein Zebra, keine Kacheln: Haarlinien teilen die Zellen. */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: var(--surface);
  overflow: hidden;
}
.facts > div {
  padding: 9px 12px 10px;
  border-left: 1px solid var(--rule);
  border-top: 1px solid var(--rule);
  margin-left: -1px;
  margin-top: -1px;
  min-width: 0;
}
.facts .k {
  display: block;
  margin-bottom: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.facts .v {
  display: block;
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
  white-space: nowrap;
}
.facts .v .unit { font-size: 11.5px; font-weight: 400; color: var(--ink-3); letter-spacing: 0; }
.facts .s { display: block; margin-top: 3px; font-size: 11px; color: var(--ink-2); }
.facts .v .badge { vertical-align: 2px; margin-left: 4px; }

/* Kontingent-Balken (Abrechnung): das native <progress> in Systemsprache. */
progress {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  max-width: 26rem;
  height: 8px;
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  background: var(--surface-2);
  overflow: hidden;
}
progress::-webkit-progress-bar { background: var(--surface-2); }
progress::-webkit-progress-value { background: var(--accent); }
progress::-moz-progress-bar { background: var(--accent); }

/* Formulare, die Etikett und Feld in EINEM <label> stapeln (Benutzer-Reiter):
 * dieselbe Mikro-Typografie wie .field, ohne das Markup anzufassen. */
form.usr-form > label {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  max-width: 24rem;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-3);
}
form.usr-form > label > input,
form.usr-form > label > select {
  width: 100%;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}

/* Zweite Fußzeile in einer Kachel (Verbrauch: „… darüber zu …/Beleg"):
 * direkt unter der ersten, ohne den 6px-Versatz zu wiederholen. */
.tile .foot + .foot { margin-top: 1px; }

/* Badge im Seitentitel (Zähler, Stand, Status): mitlaufen, nicht schreien. */
.page-title .badge { vertical-align: 3px; margin-left: 6px; font-weight: 500; }

/* .spacer schiebt in Zeilen (Kontoauszug, Tarif-Kopf) den Rest nach rechts —
 * bisher war die Klasse nur in der Sidebar definiert. */
.row > .spacer { margin-left: auto; }

/* Aufklappzeilen direkt im Panel (Postfächer, Tarif-Historie): klickbare
 * Zeile mit ruhigem Hover — nicht für die Benutzerliste (.usr-list, tiefer
 * verschachtelt), die ihren eigenen Aufklapp-Stil hat. */
.card > details > summary:hover { color: var(--accent); }

/* Preset-Beträge (Aufladen): ein Segment-Band statt loser Knöpfe. */
.presets { display: inline-flex; border: 1px solid var(--rule-2); border-radius: 2px; background: var(--surface); }
.presets form + form { border-left: 1px solid var(--rule); }
.presets .btn { border: 0; border-radius: 0; font-family: var(--mono); }
.presets form:first-child .btn { border-radius: 2px 0 0 2px; }
.presets form:last-child .btn { border-radius: 0 2px 2px 0; }

/* === W4: Auth/Public === */

/* ------------------------------------------ Login-Karte: Perforationskante
 * Der Entwurf verlangt Bon-Glyph (die .signin-badge, schon vorhanden) UND
 * eine Perforationskante an der Login-Karte selbst — bislang trug nur die
 * öffentliche Formular-Karte (.login-card, public.html) den Abriss unten.
 * Dieselbe Technik (Maskierungsverlauf aus Halbkreisen) jetzt auch an
 * .signin-card: die Ecken werden oben eckig-abgerundet und unten gerade,
 * der Riss sitzt in der so freiwerdenden Lücke. Nur ergänzende Regeln,
 * .signin-card selbst bleibt unverändert stehen (Kaskade gewinnt).
 */
.signin-card {
  position: relative;
  border-radius: 2px 2px 0 0;
  border-bottom: 0;
}
.signin-card::after {
  content: "";
  position: absolute;
  top: 100%;
  left: -1px;
  right: -1px;
  height: 7px;
  background: var(--surface);
  -webkit-mask: conic-gradient(from 135deg at 50% 0, #000 90deg, #0000 0) top / 18px 7px repeat-x;
  mask: conic-gradient(from 135deg at 50% 0, #000 90deg, #0000 0) top / 18px 7px repeat-x;
}

/* ------------------------------------------------------- Rechtsseiten
 * Impressum und Datenschutz sind lange Lauftexte, keine Formulare — die
 * Beleg-Karte mit Schatten und Perforationskante wäre über zehn Abschnitte
 * hinweg nur wiederholte Dekoration, keine Signatur mehr. Eigener, ruhiger
 * Rahmen: schmale Lesespalte, klare Titel-/Abschnitts-Hierarchie, keine
 * Karte. public.html tauscht dafür den ganzen "aussen"-Block aus.
 */
.doc-main {
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(28px, 6vh, 64px) 20px 56px;
}
.doc-brand.brand {
  height: auto;
  padding: 0;
  margin-bottom: 30px;
  border-bottom: 0;
  display: inline-flex;
}
.doc-brand-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--ink);
}
.doc-brand-link:hover { text-decoration: none; color: var(--accent); }
.doc-title {
  margin: 6px 0 4px;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--ink);
}
.doc-body { margin-top: 22px; }
.doc-body h3 {
  margin: 30px 0 8px;
  padding-top: 16px;
  border-top: 1px solid var(--rule);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--ink);
}
.doc-body h3:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.doc-body p, .doc-body li { font-size: 13.5px; line-height: 1.65; }
.doc-body p + p { margin-top: 10px; }
.doc-foot {
  margin-top: 36px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
}
/* --------------------------------------------------- Rechnungen-Tab (Task 2) */

/* Die Filterleiste ist ein .row (flex, wrap) mit Label+Feld-Paaren. */
.rechnungen-filter { align-items: center; }
.rechnungen-filter label { white-space: nowrap; }
.rechnungen-filter select,
.rechnungen-filter input[type="date"] { font: inherit; }

/* Eine Checkbox mit ihrem Text in einer Zeile statt darunter (Standard bei
 * .small-Labels, die für Text-vor-Feld gebaut sind) — „Heute"/Status-Filter. */
.checkbox-inline { display: inline-flex !important; align-items: center; gap: 4px; width: auto; }
.checkbox-inline input[type="checkbox"] { margin: 0; }

/* Jede Zeile öffnet die Rechnungs-Box (Task 4) per Klick. */
.rechnungen-tabelle tbody tr { cursor: pointer; }

/* --------------------------------------------------- Bank-Tab (Task 6) */

/* Dieselbe Filterleisten-Optik wie .rechnungen-filter — eigene Klasse, damit
 * eine spätere Änderung an einer Liste die andere nicht versehentlich mit
 * verschiebt. */
.bank-filter { align-items: center; }
.bank-filter label { white-space: nowrap; }
.bank-filter select,
.bank-filter input[type="date"] { font: inherit; }

/* Jede Zeile öffnet die Zuordnungs-/Aktions-Box (Task 7) per Klick — dasselbe
 * Muster wie .rechnungen-tabelle. */
.bank-tabelle tbody tr { cursor: pointer; }

/* --------------------------------------------------- Rechnungen-Box (Task 4) */

/* #overlay steht leer in rechnungen.html; HTMX hängt fragments/rechnung_box.html
 * als einziges Kind hinein (hx-swap="innerHTML"). Leer -> unsichtbar,
 * befüllt -> abgedunkelter Backdrop mit zentrierter, scrollbarer .box.
 * Reines CSS, kein JS — die CSP (script-src 'self', kein unsafe-inline)
 * verbietet ohnehin ein <script>, das das sonst übernähme; derselbe Trick
 * wie die <details>-Zeitleisten von op_verfolgung.html.
 *
 * Fix-Runde 3, Critical 1: früher nur ``#overlay:empty { display: none }`` —
 * die OOB-Antwort von rechnung_speichern (die aktualisierte Listenzeile
 * fährt per hx-swap-oob an ihrer eigenen id vorbei, für #overlay bleibt
 * nichts zum Einsetzen übrig) ließ dabei einen Whitespace-Textknoten übrig
 * (Kommentar-Zeilenumbruch in fragments/rechnung_zeile.html, dort behoben),
 * und :empty greift schon bei einem einzigen Zeichen Inhalt nicht mehr —
 * der Backdrop blieb dann klick-tot ohne Box stehen. ``:has(> .box)`` prüft
 * stattdessen direkt auf das erwartete Kind-Element und ist damit robust
 * gegen jeden Whitespace/Text, der sonst noch übrig bleibt.
 *
 * Beide Regeln nebeneinander (nicht durch ein pauschales
 * ``#overlay { display: none }`` ersetzt) — fail-open statt fail-closed in
 * einem Browser ohne :has()-Unterstützung: eine ungültige Selektor-Regel
 * wird dort ignoriert, nicht als "immer verstecken" ausgewertet. Ohne
 * :has() bliebe dann nur die alte :empty-Regel aktiv — die Box erscheint
 * als normaler Block statt als zentrierter Backdrop (kein hübsches, aber
 * ein bedienbares Degradieren), statt dass die Box in so einem Browser nie
 * sichtbar würde. */
#overlay:empty { display: none; }
#overlay:not(:has(> .box)) { display: none; }
#overlay:has(> .box) {
  position: fixed;
  inset: 0;
  background: rgba(20, 23, 26, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 20;
}
#overlay > .box {
  background: var(--surface);
  border: 1px solid var(--rule-2);
  border-radius: 2px;
  padding: var(--pad);
  width: min(640px, 100%);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}
#overlay > .box h3 {
  margin: 20px 0 6px;
  padding-top: 10px;
  border-top: 1px solid var(--rule);
  font-size: 13px;
}
#overlay > .box h3:first-of-type { border-top: none; padding-top: 0; }

@media (max-width: 520px) {
  .doc-main { padding: 24px 16px 40px; }
  .doc-title { font-size: 21px; }
}
