/* CRM version.blue — die Oberfläche, eine Datei
 *
 * Diese Datei ersetzt `app.css` + `marke.css` + `modern.css` für alles **hinter** der
 * Anmeldung. Drei Stylesheets übereinander waren 2.253 Zeilen, von denen sich 23 Regeln
 * vollständig gegenseitig aufhoben; auf der Anmeldeseite stritten alle drei um dieselbe
 * Fläche, und zwanzig `!important` kämpften allein um ein Auswahlfeld. Was hier steht, steht
 * einmal.
 *
 * Grundlage ist das Gestaltungssystem **Broadsheet**: 51 Marken, in OKLCH auf einer
 * gemeinsamen Helligkeitsleiter erzeugt, dazu fünf, die im Entwurf nur im JavaScript
 * standen (`--color-panel`, `--color-scrim`, `--color-success/warning/danger`).
 *
 * Aufbau, und in dieser Reihenfolge gelesen auch verständlich:
 *
 *   1. Schrift            — Source Serif 4, selbst gehostet
 *   2. Marken             — die Farben, Abstände, Rundungen, Schatten
 *   3. Alte Namen         — `--akzent` & Co. als Zuweisung, weil 545 Inline-Stile sie rufen
 *   4. Grundlagen         — Reset, Typografie, Fokus
 *   5. Die Hülle          — Seitenleiste, Kopfleiste, Inhalt
 *   6. Bauteile           — Karte, Knopf, Liste, Feld, Marke, Meldung, Fenster, Kennzahl
 *   7. Besondere Flächen  — Bauakte, Baukalender, LV, AGB, Befunde, Schnittstelle
 *   8. Dunkle Fassung     — abgeleitet, nicht erfunden: die Marken werden neu besetzt
 *   9. Kleine Schirme, Druck, Bewegung
 *
 * **Eine Farbe wird an einer Stelle entschieden.** Jedes Bauteil greift auf Marken zu, nie
 * auf einen Festwert — deshalb ist die dunkle Fassung dreißig Zeilen und nicht fünfzig
 * Regeln. Wer hier einen Hexwert schreibt, nimmt dem Umschalter eine Fläche.
 *
 * `php bin/console stil <selektor>` zeigt, ob eine Regel doppelt steht.
 */

/* ============================================================== 1. Schrift
 *
 * Source Serif 4 als veränderliche Schrift: **eine** Datei je Zeichenvorrat trägt 400 und
 * 600 — deshalb vier Dateien und nicht achtzehn. Google liefert sie in 18 Schnitten; davon
 * braucht ein deutsches Haus latin und latin-ext, und das sind 130 KB statt 1,2 MB.
 *
 * Selbst gehostet und nicht von fonts.gstatic.com: Die Anwendung soll ohne Verbindung nach
 * außen laufen — und eine Schriftanfrage an einen Dritten bei jedem Seitenaufruf ist eine
 * Datenweitergabe, die niemand bestellt hat.
 */
@font-face {
  font-family: "Source Serif 4"; font-style: normal; font-weight: 300 700;
  font-display: swap; src: url("schrift/source-serif-4-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Serif 4"; font-style: normal; font-weight: 300 700;
  font-display: swap; src: url("schrift/source-serif-4-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Source Serif 4"; font-style: italic; font-weight: 300 700;
  font-display: swap; src: url("schrift/source-serif-4-latin-italic.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Source Serif 4"; font-style: italic; font-weight: 300 700;
  font-display: swap;
  src: url("schrift/source-serif-4-latin-ext-italic.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* --------------------------------------------------------------- Die Symbole
 *
 * **Phosphor Duotone**, und nur die fünfundfünfzig, die dieses Haus benutzt.
 *
 * Die mitgelieferte Stilvorlage beschreibt 1.513 Symbole in 231 KB — ausgeliefert wird,
 * was im Menü steht. Jedes Symbol besteht aus zwei Zeichen: ein Umriss bei voller Deckung
 * und eine Füllung bei 20 % darunter. Deshalb zwei Regeln je Symbol und das
 * `margin-left: -1em`, das die zweite über die erste legt.
 *
 * Schriftzeichen statt Bildern: Sie erben Farbe und Größe vom Text, sie laden nicht je
 * Symbol eine Datei nach, und sie bleiben scharf. Vorher standen hier Unicode-Zeichen —
 * `◉`, `⇄`, `⚒` —, und die meisten Punkte bekamen mangels Treffer einen Mittelpunkt: Ein
 * Menü, in dem vierzig Einträge dasselbe Zeichen tragen, hat keine Zeichen.
 */
@font-face {
  font-family: "Phosphor-Duotone";
  src: url("schrift/phosphor-duotone.woff2") format("woff2");
  font-weight: normal; font-style: normal; font-display: block;
}
.ph-duotone {
  font-family: "Phosphor-Duotone" !important;
  speak: never; font-style: normal; font-weight: normal; font-variant: normal;
  text-transform: none; line-height: 1;
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}

.ph-duotone.ph-arrow-right:before { content: "\e06c"; opacity: 0.2; }
.ph-duotone.ph-arrow-right:after { content: "\e06d"; margin-left: -1em; }
.ph-duotone.ph-clock-counter-clockwise:before { content: "\e1a0"; opacity: 0.2; }
.ph-duotone.ph-clock-counter-clockwise:after { content: "\e1a1"; margin-left: -1em; }
.ph-duotone.ph-plus-circle:before { content: "\e3d6"; opacity: 0.2; }
.ph-duotone.ph-plus-circle:after { content: "\e3d7"; margin-left: -1em; }
.ph-duotone.ph-arrow-elbow-down-left:before { content: "\e044"; opacity: 0.2; }
.ph-duotone.ph-arrow-elbow-down-left:after { content: "\e045"; margin-left: -1em; }
.ph-duotone.ph-keyboard:before { content: "\e2d8"; opacity: 0.2; }
.ph-duotone.ph-keyboard:after { content: "\e2d9"; margin-left: -1em; }
.ph-duotone.ph-moon:before { content: "\e330"; opacity: 0.2; }
.ph-duotone.ph-moon:after { content: "\e331"; margin-left: -1em; }
.ph-duotone.ph-sun:before { content: "\e472"; opacity: 0.2; }
.ph-duotone.ph-sun:after { content: "\e473"; margin-left: -1em; }
.ph-duotone.ph-user-circle:before { content: "\e4c4"; opacity: 0.2; }
.ph-duotone.ph-user-circle:after { content: "\e4c5"; margin-left: -1em; }
.ph-duotone.ph-sign-out:before { content: "\e42a"; opacity: 0.2; }
.ph-duotone.ph-sign-out:after { content: "\e42b"; margin-left: -1em; }
.ph-duotone.ph-bell:before { content: "\e0ce"; opacity: 0.2; }
.ph-duotone.ph-bell:after { content: "\e0cf"; margin-left: -1em; }
.ph-duotone.ph-magnifying-glass:before { content: "\e30c"; opacity: 0.2; }
.ph-duotone.ph-magnifying-glass:after { content: "\e30d"; margin-left: -1em; }
.ph-duotone.ph-house:before { content: "\e2c2"; opacity: 0.2; }
.ph-duotone.ph-house:after { content: "\e2c3"; margin-left: -1em; }
.ph-duotone.ph-bell-ringing:before { content: "\e5e8"; opacity: 0.2; }
.ph-duotone.ph-bell-ringing:after { content: "\e5e9"; margin-left: -1em; }
.ph-duotone.ph-arrow-up-right:before { content: "\e092"; opacity: 0.2; }
.ph-duotone.ph-arrow-up-right:after { content: "\e093"; margin-left: -1em; }
.ph-duotone.ph-repeat:before { content: "\e3f6"; opacity: 0.2; }
.ph-duotone.ph-repeat:after { content: "\e3f9"; margin-left: -1em; }
.ph-duotone.ph-pencil-simple-line:before { content: "\ebc6"; opacity: 0.2; }
.ph-duotone.ph-pencil-simple-line:after { content: "\ebc7"; margin-left: -1em; }
.ph-duotone.ph-arrow-down-left:before { content: "\e040"; opacity: 0.2; }
.ph-duotone.ph-arrow-down-left:after { content: "\e041"; margin-left: -1em; }
.ph-duotone.ph-hand-coins:before { content: "\ea8c"; opacity: 0.2; }
.ph-duotone.ph-hand-coins:after { content: "\ea8d"; margin-left: -1em; }
.ph-duotone.ph-scissors:before { content: "\eae0"; opacity: 0.2; }
.ph-duotone.ph-scissors:after { content: "\eae1"; margin-left: -1em; }
.ph-duotone.ph-percent:before { content: "\e3b6"; opacity: 0.2; }
.ph-duotone.ph-percent:after { content: "\e3b7"; margin-left: -1em; }
.ph-duotone.ph-warning-circle:before { content: "\e4e2"; opacity: 0.2; }
.ph-duotone.ph-warning-circle:after { content: "\e4e3"; margin-left: -1em; }
.ph-duotone.ph-bank:before { content: "\e0b4"; opacity: 0.2; }
.ph-duotone.ph-bank:after { content: "\e0b5"; margin-left: -1em; }
.ph-duotone.ph-arrows-left-right:before { content: "\e0a0"; opacity: 0.2; }
.ph-duotone.ph-arrows-left-right:after { content: "\e0a1"; margin-left: -1em; }
.ph-duotone.ph-piggy-bank:before { content: "\ea04"; opacity: 0.2; }
.ph-duotone.ph-piggy-bank:after { content: "\ea05"; margin-left: -1em; }
.ph-duotone.ph-tray:before { content: "\e4aa"; opacity: 0.2; }
.ph-duotone.ph-tray:after { content: "\e4ab"; margin-left: -1em; }
.ph-duotone.ph-arrows-down-up:before { content: "\e098"; opacity: 0.2; }
.ph-duotone.ph-arrows-down-up:after { content: "\e099"; margin-left: -1em; }
.ph-duotone.ph-cube:before { content: "\e1da"; opacity: 0.2; }
.ph-duotone.ph-cube:after { content: "\e1db"; margin-left: -1em; }
.ph-duotone.ph-cash-register:before { content: "\ed80"; opacity: 0.2; }
.ph-duotone.ph-cash-register:after { content: "\ed81"; margin-left: -1em; }
.ph-duotone.ph-clipboard-text:before { content: "\e198"; opacity: 0.2; }
.ph-duotone.ph-clipboard-text:after { content: "\e199"; margin-left: -1em; }
.ph-duotone.ph-receipt:before { content: "\e3ec"; opacity: 0.2; }
.ph-duotone.ph-receipt:after { content: "\e3f1"; margin-left: -1em; }
.ph-duotone.ph-hourglass:before { content: "\e2b2"; opacity: 0.2; }
.ph-duotone.ph-hourglass:after { content: "\e2b3"; margin-left: -1em; }
.ph-duotone.ph-arrow-u-up-left:before { content: "\e08a"; opacity: 0.2; }
.ph-duotone.ph-arrow-u-up-left:after { content: "\e08b"; margin-left: -1em; }
.ph-duotone.ph-lock-simple:before { content: "\e308"; opacity: 0.2; }
.ph-duotone.ph-lock-simple:after { content: "\e309"; margin-left: -1em; }
.ph-duotone.ph-currency-eur:before { content: "\e554"; opacity: 0.2; }
.ph-duotone.ph-currency-eur:after { content: "\e555"; margin-left: -1em; }
.ph-duotone.ph-arrows-clockwise:before { content: "\e094"; opacity: 0.2; }
.ph-duotone.ph-arrows-clockwise:after { content: "\e095"; margin-left: -1em; }
.ph-duotone.ph-link-simple:before { content: "\e2e6"; opacity: 0.2; }
.ph-duotone.ph-link-simple:after { content: "\e2e7"; margin-left: -1em; }
.ph-duotone.ph-calculator:before { content: "\e538"; opacity: 0.2; }
.ph-duotone.ph-calculator:after { content: "\e539"; margin-left: -1em; }
.ph-duotone.ph-buildings:before { content: "\e102"; opacity: 0.2; }
.ph-duotone.ph-buildings:after { content: "\e105"; margin-left: -1em; }
.ph-duotone.ph-calendar-blank:before { content: "\e10a"; opacity: 0.2; }
.ph-duotone.ph-calendar-blank:after { content: "\e10b"; margin-left: -1em; }
.ph-duotone.ph-ruler:before { content: "\e6b8"; opacity: 0.2; }
.ph-duotone.ph-ruler:after { content: "\e6b9"; margin-left: -1em; }
.ph-duotone.ph-hard-hat:before { content: "\ed46"; opacity: 0.2; }
.ph-duotone.ph-hard-hat:after { content: "\ed47"; margin-left: -1em; }
.ph-duotone.ph-package:before { content: "\e390"; opacity: 0.2; }
.ph-duotone.ph-package:after { content: "\e391"; margin-left: -1em; }
.ph-duotone.ph-handshake:before { content: "\e582"; opacity: 0.2; }
.ph-duotone.ph-handshake:after { content: "\e583"; margin-left: -1em; }
.ph-duotone.ph-flag:before { content: "\e244"; opacity: 0.2; }
.ph-duotone.ph-flag:after { content: "\e245"; margin-left: -1em; }
.ph-duotone.ph-address-book:before { content: "\e6f8"; opacity: 0.2; }
.ph-duotone.ph-address-book:after { content: "\e6f9"; margin-left: -1em; }
.ph-duotone.ph-seal-check:before { content: "\e606"; opacity: 0.2; }
.ph-duotone.ph-seal-check:after { content: "\e607"; margin-left: -1em; }
.ph-duotone.ph-shield-check:before { content: "\e40c"; opacity: 0.2; }
.ph-duotone.ph-shield-check:after { content: "\e40f"; margin-left: -1em; }
.ph-duotone.ph-envelope-simple:before { content: "\e218"; opacity: 0.2; }
.ph-duotone.ph-envelope-simple:after { content: "\e219"; margin-left: -1em; }
.ph-duotone.ph-paper-plane-tilt:before { content: "\e398"; opacity: 0.2; }
.ph-duotone.ph-paper-plane-tilt:after { content: "\e399"; margin-left: -1em; }
.ph-duotone.ph-queue:before { content: "\e6ac"; opacity: 0.2; }
.ph-duotone.ph-queue:after { content: "\e6ad"; margin-left: -1em; }
.ph-duotone.ph-file-text:before { content: "\e23a"; opacity: 0.2; }
.ph-duotone.ph-file-text:after { content: "\e23b"; margin-left: -1em; }
.ph-duotone.ph-wave-sine:before { content: "\ea9a"; opacity: 0.2; }
.ph-duotone.ph-wave-sine:after { content: "\ea9b"; margin-left: -1em; }
.ph-duotone.ph-chart-bar:before { content: "\e150"; opacity: 0.2; }
.ph-duotone.ph-chart-bar:after { content: "\e151"; margin-left: -1em; }
.ph-duotone.ph-folder-simple:before { content: "\e25a"; opacity: 0.2; }
.ph-duotone.ph-folder-simple:after { content: "\e25b"; margin-left: -1em; }
.ph-duotone.ph-gear-six:before { content: "\e272"; opacity: 0.2; }
.ph-duotone.ph-gear-six:after { content: "\e273"; margin-left: -1em; }
.ph-duotone.ph-users:before { content: "\e4d6"; opacity: 0.2; }
.ph-duotone.ph-users:after { content: "\e4d7"; margin-left: -1em; }
.ph-duotone.ph-copy:before { content: "\e1ca"; opacity: 0.2; }
.ph-duotone.ph-copy:after { content: "\e1cb"; margin-left: -1em; }
.ph-duotone.ph-scales:before { content: "\e750"; opacity: 0.2; }
.ph-duotone.ph-scales:after { content: "\e751"; margin-left: -1em; }
.ph-duotone.ph-export:before { content: "\eaf0"; opacity: 0.2; }
.ph-duotone.ph-export:after { content: "\eaf1"; margin-left: -1em; }
.ph-duotone.ph-list-checks:before { content: "\eadc"; opacity: 0.2; }
.ph-duotone.ph-list-checks:after { content: "\eadd"; margin-left: -1em; }
.ph-duotone.ph-terminal-window:before { content: "\eae8"; opacity: 0.2; }
.ph-duotone.ph-terminal-window:after { content: "\eae9"; margin-left: -1em; }
.ph-duotone.ph-squares-four:before { content: "\e464"; opacity: 0.2; }
.ph-duotone.ph-squares-four:after { content: "\e465"; margin-left: -1em; }
.ph-duotone.ph-plugs-connected:before { content: "\eb5a"; opacity: 0.2; }
.ph-duotone.ph-plugs-connected:after { content: "\eb5b"; margin-left: -1em; }
.ph-duotone.ph-phone:before { content: "\e3b8"; opacity: 0.2; }
.ph-duotone.ph-phone:after { content: "\e3b9"; margin-left: -1em; }
.ph-duotone.ph-sign-in:before { content: "\e428"; opacity: 0.2; }
.ph-duotone.ph-sign-in:after { content: "\e429"; margin-left: -1em; }
.ph-duotone.ph-dot-outline:before { content: "\ece0"; opacity: 0.2; }
.ph-duotone.ph-dot-outline:after { content: "\ece1"; margin-left: -1em; }

/* =============================================================== 2. Marken
 *
 * Die Tonleitern sind in OKLCH auf **einer** Helligkeitsleiter erzeugt: Die Stufe 700 eines
 * Tons hat denselben Helligkeitswert wie die 700 jedes anderen. Deshalb lässt sich eine
 * Statusmarke von Grün auf Rot umstellen, ohne dass sie plötzlich schreit — und deshalb
 * entsteht die dunkle Fassung durch Umdrehen der Leiter und nicht durch neues Raten.
 */
:root {
  --color-bg:       #f3f2f2;   /* der Grund, auf dem alles liegt */
  --color-surface:  #eae9e9;   /* eine abgesetzte Fläche: Tabellenkopf, Fuß, Hover */
  --color-panel:    #fbfafa;   /* die Tafel: Karte, Fenster, Feld — die häufigste Fläche */
  --color-text:     #201e1d;
  --color-accent:   #0088b0;
  --color-accent-2: #d6006c;
  --color-divider:  color-mix(in srgb, #201e1d 16%, transparent);
  --color-scrim:    rgba(32,30,29,.42);

  --color-neutral-100: #f8f4f4;
  --color-neutral-200: #eae7e7;
  --color-neutral-300: #d7d3d3;
  --color-neutral-400: #bab6b6;
  --color-neutral-500: #9b9797;
  --color-neutral-600: #7d7979;
  --color-neutral-700: #605d5d;
  --color-neutral-800: #444141;
  --color-neutral-900: #2d2b2b;

  --color-accent-100: #e9f8ff;
  --color-accent-200: #cbeeff;
  --color-accent-300: #99e0ff;
  --color-accent-400: #62c5ee;
  --color-accent-500: #38a6cf;
  --color-accent-600: #1186ac;
  --color-accent-700: #006786;
  --color-accent-800: #004961;
  --color-accent-900: #0a303e;

  --color-accent-2-100: #fff1f4;
  --color-accent-2-200: #ffdee6;
  --color-accent-2-300: #ffc0d0;
  --color-accent-2-400: #ff90b1;
  --color-accent-2-500: #ff458e;
  --color-accent-2-600: #d82071;
  --color-accent-2-700: #aa0b56;
  --color-accent-2-800: #790e3d;
  --color-accent-2-900: #4b1528;

  /* Zustände. Im Entwurf standen sie nur im JavaScript; ohne sie verliert fast jede Marke
     ihre Fläche. Drei Stufen genügen: die Fläche (100), die Schrift darauf (700), und der
     Ton selbst für Kanten und Punkte. */
  /* Die dritte Druckfarbe. Cyan und Magenta sind die beiden Akzente des Hauses; dieses
     Gelb vervollständigt den Vierfarbsatz für die versetzten Druckplatten weiter unten.
     Eine Druckfarbe, keine Oberflächenfarbe — Fließtext und Bedienteile nehmen sie nie. */
  --color-process-yellow: #edbb00;

  --color-success:     #2f8f57;  --color-success-100: #e2f3e8;  --color-success-700: #1d6b3f;
  --color-warning:     #d99a00;  --color-warning-100: #fcefd2;  --color-warning-700: #7f5400;
  --color-danger:      #d23c3c;  --color-danger-100:  #fbe3e3;  --color-danger-700:  #a01f1f;

  --font-heading: "Source Serif 4", Georgia, "Times New Roman", serif;
  --font-heading-weight: 600;
  /* Überschriften in Serif, Tabellen und Formulare in der Systemschrift: Eine Buchhaltung
     wird gelesen, nicht betrachtet — und eine Zahlenspalte in Serif liest sich zäh. */
  --font-body: system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI", Roboto,
               "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  --space-1: 5px;  --space-2: 10px; --space-3: 15px;
  --space-4: 20px; --space-6: 30px; --space-8: 40px;

  /* Rundung „weich": Das ist, was der Entwurf zur Laufzeit setzt — die scharfen 1/2/4 px
     seines Stylesheets bekommt man dort nie zu sehen. */
  --radius-sm:  6px;
  --radius-md: 10px;
  --radius-lg: 16px;

  /* Tinte, nicht Grau: Der Schatten ist aus dem Schriftton gemischt. */
  --shadow-sm: 0 1px 2px color-mix(in srgb, #2d2b2b 14%, transparent);
  --shadow-md: 0 3px 10px color-mix(in srgb, #2d2b2b 16%, transparent);
  --shadow-lg: 0 12px 32px color-mix(in srgb, #2d2b2b 22%, transparent);

  /* Die Schrift **auf** einer vollflächig eingefärbten Fläche — Hauptknopf, aktiver
     Schritt, Verb der Schnittstelle. Hell liegt dort Weiß auf einem tiefen Ton; dunkel
     dreht sich das um, weil die Tonleiter umgedreht ist und der Ton dann der helle ist.
     Ohne diese Marke stünde im dunklen Thema Weiß auf Hellblau. */
  --auf-akzent: #fff;
  --auf-ton:    #fff;

  --schnell: 120ms cubic-bezier(.2,0,.2,1);
  --ruhig:   220ms cubic-bezier(.2,0,.2,1);
}

/* ========================================================== 3. Alte Namen
 *
 * 545 Inline-Stile in 125 Ansichten rufen `--akzent`, `--rand`, `--flaeche`. Sie alle
 * umzuschreiben wäre 545 Gelegenheiten, etwas zu zerschlagen — und sie ins Leere laufen zu
 * lassen hieße: schwarzer Text auf schwarzem Grund an Stellen, die niemand noch einmal
 * ansieht. Also eine Zuweisung, und zwar **nur hier**: Jede dieser Marken zeigt auf eine
 * Broadsheet-Marke und hat keinen eigenen Wert.
 */
:root {
  --grund:        var(--color-bg);
  --flaeche:      var(--color-panel);
  --flaeche-alt:  var(--color-surface);
  --flaeche-aktiv: var(--color-accent-100);
  --rand:         var(--color-divider);
  --rand-stark:   var(--color-neutral-400);
  --rahmen:       var(--color-divider);
  --text:         var(--color-text);
  --text-leise:   var(--color-neutral-700);
  --akzent:       var(--color-accent-700);
  --akzent-hell:  var(--color-accent-100);
  --blau:         var(--color-accent-700);
  --blau-hell:    var(--color-accent-100);
  --gruen:        var(--color-success-700);
  --gruen-hell:   var(--color-success-100);
  --gelb:         var(--color-warning-700);
  --gelb-hell:    var(--color-warning-100);
  --rot:          var(--color-danger-700);
  --rot-hell:     var(--color-danger-100);
  --zeile-sperre: var(--color-danger-100);
  --zeile-abzug:  var(--color-warning-100);
  --eingabe-grund: var(--color-panel);
  --schrift-fest: var(--font-mono);

  /*
   * **Diese Seite ist hell** (29.10.2026).
   *
   * > „in den Inputs, bei beiden — im Web und in der App — ist der eingegebene Text
   * > weiß"
   *
   * Android und Chrome dunkeln Seiten von selbst ein, wenn das Gerät dunkel gestellt
   * ist und die Seite nichts anderes sagt („Auto Dark Theme"). Dann malt der Browser
   * die Schrift im Eingabefeld hell — den Grund gibt aber unser Stylesheet vor, und der
   * blieb hell. Weiß auf Weiß. Mit dieser Zeile sagt die Seite, in welchem Licht sie
   * gedacht ist; die dunkle Fassung schaltet man hier um, nicht das Betriebssystem.
   */
  color-scheme: light;

  --radius:    var(--radius-md);
  --radius-s:  var(--radius-sm);
  --radius-xl: var(--radius-lg);
  --schatten:   var(--shadow-sm);
  --schatten-m: var(--shadow-md);
  --schatten-l: var(--shadow-lg);
}

/* ========================================================== 4. Grundlagen */

/* `hidden` setzt display:none — aber nur, solange keine eigene Regel ein `display` vorgibt.
   Genau das tun die Reiterleiste (flex) und die Reiterfläche (grid): Ohne diese Zeile stünde
   die leere Leiste auf jeder Seite, und die Fläche legte sich über den Inhalt. */
[hidden] { display: none !important; }

* { box-sizing: border-box; }
html { font-size: 15px; }
body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Überschriften, Kennzahlen und Knöpfe in Serif — das ist der Griff, an dem man dieses
   Haus wiedererkennt. Der Rest bleibt Systemschrift. */
h1, h2, h3, h4, h5, .karte-kopf, .modal-kopf, .kopfleiste .titel, .kennzahl .wert,
.knopf, .fehlerseite .status, legend, .anmeldung h1 {
  font-family: var(--font-heading);
}
h1, h2, h3, h4, h5 { font-weight: var(--font-heading-weight); letter-spacing: -.01em; }
h1 { font-size: 1.45rem; margin: 0 0 .6rem; }
main h2 { font-size: 1.1rem; margin: 1.4rem 0 .6rem; }
main h3 { font-size: .98rem; margin: 1.1rem 0 .5rem; }
main p { line-height: 1.55; }
/* Nur freistehender Text bekommt eine Lesebreite. In einer Karte ist der Rahmen das Maß. */
main > p { max-width: 62rem; }

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

/* Ziffern fluchten. In einer Buchhaltung ist das keine Geschmacksfrage: Zwei Beträge
   untereinander, deren Kommas nicht auf einer Linie stehen, liest niemand als Spalte. */
table.liste td, table.liste th, .kennzahl .wert, .r, td.r, th.r, .zahl,
[data-betrag], .betrag, .rechenweg, code, .mono {
  font-variant-numeric: tabular-nums;
}

:focus-visible {
  outline: 2px solid var(--color-accent-600);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
::selection { background: color-mix(in srgb, var(--color-accent) 25%, transparent); }

.mono, [style*="ui-monospace"] {
  font-family: var(--font-mono) !important; font-size: .86em; letter-spacing: -.01em;
}
code {
  background: var(--color-surface); border: 1px solid var(--color-divider);
  border-radius: var(--radius-sm); padding: .05rem .3rem; font-size: .86em;
  font-family: var(--font-mono); overflow-wrap: anywhere;
}

/* Bildlaufleisten: dünn und aus dem Grund gemischt, damit sie keine eigene Farbe mitbringen. */
* { scrollbar-width: thin; scrollbar-color: var(--color-neutral-400) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--color-text) 25%, transparent);
  border-radius: 999px; border: 3px solid transparent; background-clip: content-box;
}
*:hover::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--color-text) 38%, transparent); background-clip: content-box;
}

/* „Zur Hauptsache springen" für die Tastatur: Wer mit der Tabulatortaste arbeitet, muss
   sonst durch sechzig Menüpunkte, bevor er auf der Seite ankommt. */
.sprungmarke {
  position: absolute; left: -999px; top: .5rem; z-index: 100;
  background: var(--color-panel); color: var(--color-text);
  border: 1px solid var(--color-accent-700); border-radius: var(--radius-sm);
  padding: .5rem .9rem; box-shadow: var(--shadow-lg);
}
.sprungmarke:focus { left: .5rem; text-decoration: none; }

/* =============================================================== 5. Die Hülle
 *
 * Leiste links, Kopf oben, Inhalt darunter. Die Inhaltsspalte nimmt **die ganze Breite**:
 * Der Entwurf hält sie bei 1.360 px an, und auf einem breiten Schirm bleibt rechts eine
 * tote Fläche neben jeder Karte, während eine Tabelle mit zwölf Spalten schieben muss.
 */
.rahmen {
  display: grid; grid-template-columns: 244px 1fr; min-height: 100vh;
  transition: grid-template-columns var(--ruhig);
}
.rahmen.schmal { grid-template-columns: 4.4rem 1fr; }

/* ---------------------------------------------------------------- Seitenleiste
 *
 * Sie ist im Entwurf kein Bauteil, sondern ein **eigener Markenblock auf dem Teilbaum**:
 * Dieselben Namen, andere Werte — tiefes Petrol statt hellem Grund, heller Akzent statt
 * dunklem. Alles darin (Knöpfe, Felder, Zähler) folgt dadurch von selbst, ohne eine
 * einzige Sonderregel.
 */
.seitenleiste {
  --color-surface: #0c2c38;
  --color-bg:      #1a4353;
  --color-panel:   #14384a;
  --color-text:    #f3f2f2;
  --color-accent:  #62c5ee;
  --color-accent-700: #99e0ff;
  --color-divider: color-mix(in srgb, #fff 18%, transparent);
  --color-neutral-200: color-mix(in srgb, #fff 9%, transparent);
  --color-neutral-700: #a9b9bf;
  --color-neutral-800: #dfe6e8;
  --flaeche: var(--color-panel);
  --flaeche-alt: var(--color-neutral-200);
  --rand: var(--color-divider);
  --text: var(--color-text);
  --text-leise: var(--color-neutral-700);
  --akzent: var(--color-accent);
  --akzent-hell: color-mix(in srgb, #62c5ee 18%, transparent);

  background: var(--color-surface); color: var(--color-text);
  display: flex; flex-direction: column; padding: 0;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
  scrollbar-color: color-mix(in srgb, #fff 18%, transparent) transparent;
}

.seitenmarke { display: flex; align-items: center; gap: .6rem; padding: .85rem .9rem; }
.seitenmarke-zeichen {
  width: 2.1rem; height: 2.1rem; border-radius: var(--radius-sm); display: grid;
  place-items: center; background: var(--color-bg); color: var(--color-accent);
  font-family: var(--font-heading); font-weight: 700; font-size: .85rem; flex: 0 0 auto;
  box-shadow: inset 0 0 0 1px var(--color-divider); overflow: hidden;
}
/* Mit Logo wird aus der Kachel ein Stempel auf Papier: Ein Logo ist für den Briefbogen
   gezeichnet, meist in einem dunklen Ton — auf dem Petrol der Leiste bliebe ein Schatten
   davon übrig. Das Weiß ist hier ein Festwert und keine Marke: Es ist das Papier, auf dem
   das Logo gedruckt wird, und bleibt es auch in der dunklen Fassung. */
.seitenmarke-zeichen.hat-logo { background: #fff; padding: 2px; }
.seitenmarke-zeichen img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  object-fit: contain; display: block;
}
.seitenmarke-text { display: flex; flex-direction: column; min-width: 0; }
.seitenmarke-text strong {
  color: var(--color-text); font-size: .95rem; font-family: var(--font-heading);
  letter-spacing: .01em;
}
.seitenmarke-text small {
  font-size: .71rem; color: var(--color-neutral-700);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.leiste-schmal {
  margin-left: auto; border: 0; background: none; color: var(--color-neutral-700);
  cursor: pointer; font-size: 1rem; border-radius: var(--radius-sm); padding: .1rem .35rem;
}
.leiste-schmal:hover { background: var(--color-neutral-200); color: var(--color-text); }

.menuesuche { padding: .1rem .8rem .5rem; }
.menuesuche input {
  width: 100%; background: var(--color-bg); color: var(--color-text);
  border: 1px solid var(--color-divider); border-radius: 999px;
  padding: .34rem .8rem; font: inherit; font-size: .82rem;
}
.menuesuche input::placeholder { color: var(--color-neutral-700); }
.menuesuche input:focus {
  outline: none; border-color: var(--color-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 20%, transparent);
}

.nav { flex: 1 1 auto; overflow-y: auto; overflow-x: hidden; padding: .2rem .45rem 1rem; }
.nav-gruppe {
  display: flex; align-items: center; gap: .4rem; cursor: pointer; user-select: none;
  padding: .8rem .6rem .3rem;
}
.nav-gruppe-name {
  flex: 1 1 auto; font-size: .68rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--color-neutral-700); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-weight: 600;
}
.nav-griff { opacity: 0; font-size: .78rem; cursor: grab; }
.nav-gruppe:hover .nav-griff { opacity: .5; }
.nav-pfeil { margin-left: auto; font-size: .62rem; transition: transform var(--schnell); }
.nav-gruppe-block.zu .nav-pfeil { transform: rotate(-90deg); }
.nav-gruppe-block.zu .nav-punkte { display: none; }
.nav-gruppe-block.zieht { opacity: .4; }
.nav-gruppe-block.ziel { box-shadow: inset 0 2px 0 var(--color-accent); }

.nav a {
  position: relative; display: flex; justify-content: space-between; align-items: center;
  gap: .55rem; padding: .38rem .6rem; color: var(--color-neutral-800); font-size: .87rem;
  border-radius: var(--radius-sm);
  transition: background var(--schnell), color var(--schnell);
}
.nav a:hover { background: var(--color-neutral-200); color: var(--color-text); text-decoration: none; }
.nav a.aktiv {
  background: var(--color-bg); color: var(--color-text); font-weight: 600;
  box-shadow: inset 2px 0 0 var(--color-accent);
}
/* Das Symbol: 1em breit, weil die Füllung mit `margin-left: -1em` unter dem Umriss liegt.
   Eine feste Spalte davor hält die Beschriftungen auf einer Flucht — auch die der Punkte,
   die (noch) kein eigenes Symbol haben. */
.nav-zeichen {
  display: inline-block; width: 1.15rem; flex: 0 0 auto; font-size: 1.15rem;
  line-height: 1; text-align: left; opacity: .8;
}
.nav a.aktiv .nav-zeichen { opacity: 1; color: var(--color-accent); }
.nav-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; }
.nav .zaehler {
  background: var(--color-neutral-200); color: var(--color-text); border-radius: 999px;
  padding: 0 .42rem; font-size: .7rem; min-width: 1.35rem; text-align: center;
  font-variant-numeric: tabular-nums;
}
.nav .zaehler.warn { background: var(--color-danger); color: var(--auf-ton); }

.leiste-fuss { padding: .6rem .8rem; border-top: 1px solid var(--color-divider); }
.leiste-fuss .knopf {
  width: 100%; background: transparent; color: var(--color-neutral-700);
  border-color: var(--color-divider); box-shadow: none;
}
.leiste-fuss .knopf:hover { background: var(--color-neutral-200); color: var(--color-text); }

/* Schmal: nur Zeichen, und der Name erscheint beim Überfahren daneben. */
.rahmen.schmal .seitenmarke-text, .rahmen.schmal .menuesuche,
.rahmen.schmal .nav-gruppe, .rahmen.schmal .nav-name,
.rahmen.schmal .leiste-fuss { display: none; }
.rahmen.schmal .nav a { justify-content: center; padding: .5rem 0; }
.rahmen.schmal .nav-zeichen { font-size: 1.1rem; }
.rahmen.schmal .zaehler { position: absolute; top: .15rem; right: .5rem; }
.rahmen.schmal .leiste-schmal { transform: rotate(180deg); margin: 0 auto; }
.rahmen.schmal .seitenleiste, .rahmen.schmal .nav { overflow: visible; }
.rahmen.schmal .nav-gruppe-block + .nav-gruppe-block {
  border-top: 1px solid var(--color-divider); margin-top: .4rem; padding-top: .4rem;
}
.rahmen.schmal .nav a::after {
  content: attr(data-titel); position: absolute; left: calc(100% + .5rem); top: 50%;
  transform: translateY(-50%) scale(.96); background: #0c2c38; color: #f3f2f2;
  padding: .3rem .6rem; border-radius: var(--radius-sm); font-size: .8rem; white-space: nowrap;
  box-shadow: var(--shadow-lg); opacity: 0; pointer-events: none; z-index: 60;
  transition: opacity var(--schnell), transform var(--schnell);
}
.rahmen.schmal .nav a:hover::after, .rahmen.schmal .nav a:focus-visible::after {
  opacity: 1; transform: translateY(-50%) scale(1);
}

/* ------------------------------------------------------------------- Kopfleiste */
.inhalt { display: flex; flex-direction: column; min-width: 0; }
.kopfleiste {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 1rem;
  padding: .5rem 1.4rem;
  background: color-mix(in srgb, var(--color-bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--color-divider);
}
.kopfleiste .titel {
  font-weight: var(--font-heading-weight); font-size: 1.08rem; margin-right: auto;
  letter-spacing: -.01em;
}
.kopfleiste .benutzer { font-size: .82rem; color: var(--color-neutral-700); }

/* Das Logo des Mandanten im Kopf — nicht in der Leiste: Dort ist der Grund tief, und ein
   Logo mit dunkler Schrift verschwindet darin. Hier liegt es auf der hellen Fläche, auf der
   es auch gedruckt wird. Ist keines hinterlegt, steht an seiner Stelle der Weg dorthin. */
.kopflogo { display: inline-flex; align-items: center; height: 2.1rem; flex: 0 0 auto; }
.kopflogo img { max-height: 2.3rem; max-width: 12rem; width: auto; display: block; }
.kopflogo-leer {
  font-size: .72rem; color: var(--color-neutral-600); border: 1px dashed var(--color-neutral-400);
  border-radius: var(--radius-sm); padding: .25rem .5rem; white-space: nowrap;
}
.kopflogo-leer:hover {
  border-color: var(--color-accent-600); color: var(--color-accent-700); text-decoration: none;
}

.mandantwahl { position: relative; }
.mandant-knopf {
  display: flex; align-items: center; gap: .5rem; border: 1px solid var(--color-divider);
  background: var(--color-panel); color: inherit; border-radius: 999px;
  padding: .2rem .65rem .2rem .25rem; font: inherit; cursor: pointer;
  transition: background var(--schnell), box-shadow var(--schnell);
}
.mandant-knopf:hover { background: var(--color-surface); box-shadow: var(--shadow-sm); }
.mandant-zeichen {
  width: 1.7rem; height: 1.7rem; border-radius: 50%; color: #fff; display: grid;
  place-items: center; font-size: .66rem; font-weight: 700; flex: 0 0 auto;
}
.mandant-text {
  display: flex; flex-direction: column; align-items: flex-start; min-width: 0; line-height: 1.15;
}
.mandant-text strong { font-size: .83rem; }
.mandant-text small {
  font-size: .69rem; color: var(--color-neutral-700); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; max-width: 11rem;
}
.mandant-pfeil { font-size: .68rem; color: var(--color-neutral-700); }
.mandant-liste {
  position: absolute; right: 0; top: calc(100% + .45rem); z-index: 40;
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg); padding: .3rem;
  min-width: 19rem; animation: auf var(--ruhig);
}
.mandant-titel {
  font-size: .67rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--color-neutral-700); padding: .45rem .6rem .3rem;
}
.mandant-eintrag {
  display: flex; align-items: center; gap: .55rem; width: 100%; border: 0; background: none;
  color: inherit; font: inherit; text-align: left; padding: .4rem .55rem;
  border-radius: var(--radius-sm); cursor: pointer;
}
.mandant-eintrag:hover { background: var(--color-surface); }
.mandant-eintrag.aktiv { background: var(--color-accent-100); }
.mandant-haken { margin-left: auto; color: var(--color-accent-700); font-weight: 700; }

/* ---- Der Auftritt unter seiner Gesellschaft (Kapitel 49.100)
 *
 * Ein eigenes Feld statt eingerückter Zeilen. Eine Einrückung allein las sich wie eine
 * Fortsetzung der Liste — als stünde dort ein weiterer Mandant, nur etwas weiter rechts.
 * Ein Geschäftsbereich ist aber kein zweiter Mandant: Er teilt Bücher und Steuernummer und
 * hat nur ein eigenes Gesicht. Das Feld sagt das, bevor jemand den Text liest. */
.mandant-sparten {
  margin: .15rem .1rem .35rem 2.45rem;
  padding: .15rem .25rem .25rem;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-sm);
}
.mandant-sparten .mandant-titel { padding: .3rem .45rem .2rem; }
.mandant-eintrag.sparte { padding: .3rem .45rem; gap: .5rem; }
.mandant-eintrag.sparte .mandant-text strong { font-size: .8rem; font-weight: 600; }
.mandant-eintrag.sparte .mandant-text small { font-size: .66rem; }
.mandant-eintrag.sparte:hover { background: var(--color-panel); }
.mandant-eintrag.sparte.aktiv { background: var(--color-accent-100); }

/* Ein Punkt statt eines Zeichens: Das runde Kürzel gehört der Gesellschaft, und zwei davon
 * übereinander sähen aus wie zwei Firmen. Der Punkt trägt dieselbe Farbe wie das
 * Briefpapier des Bereichs — mehr braucht es nicht, um sie auseinanderzuhalten. */
.sparte-punkt {
  width: .62rem; height: .62rem; border-radius: 50%; flex: 0 0 auto;
  background: var(--color-neutral-400); margin-left: .25rem;
  box-shadow: 0 0 0 2px var(--color-panel);
}
.mandant-eintrag.sparte.aktiv .sparte-punkt { box-shadow: 0 0 0 2px var(--color-accent-100); }

/* Steht man in einem Auftritt, trägt das Zeichen oben dessen Belegkürzel — dasselbe, das
 * später auf der Rechnung steht. Eckig, damit es sich vom runden Zeichen der Gesellschaft
 * unterscheidet, ohne eine zweite Farbe zu brauchen. */
.mandant-zeichen.sparte { border-radius: var(--radius-sm); }

/* ------------------------------------------------- Die rechte Seite der Kopfleiste
 *
 * Drei Dinge, und jedes so groß wie seine Häufigkeit: die Glocke (nur wenn etwas offen
 * ist), der Umschalter hell/dunkel, der eigene Name mit allem, was man selten braucht.
 */
.kopf-rund, .kopf-glocke {
  display: inline-flex; align-items: center; justify-content: center; gap: .3rem;
  height: 2.2rem; flex: 0 0 auto;
  border: 1px solid transparent; border-radius: 999px;
  background: none; color: var(--color-neutral-700); cursor: pointer;
  font-size: 1.2rem; line-height: 1; text-decoration: none;
  transition: background var(--schnell), color var(--schnell), border-color var(--schnell);
}
.kopf-rund { width: 2.2rem; }
/* Die Glocke trägt ihre Zahl und ist deshalb breiter als rund — eine dreistellige Zahl im
   Kreis wäre ein Kompromiss zwischen unlesbar und riesig. */
.kopf-glocke { padding: 0 .5rem; }
.kopf-rund:hover, .kopf-glocke:hover {
  background: var(--color-surface); color: var(--color-text);
  border-color: var(--color-divider); text-decoration: none;
}
.kopf-glocke .marke-status { font-size: .68rem; padding: 0 .35rem; }

/* Das Benutzermenü hängt rechts an der Kopfleiste — und seine Liste darf nicht über den
   rechten Rand hinauslaufen, sonst steht sie halb außerhalb des Bildschirms. */
.benutzermenue { margin-left: 0; }
.benutzermenue .klappliste { min-width: 17rem; }

.kopf-benutzer {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .3rem .7rem .3rem .5rem; border-radius: 999px;
  border: 1px solid var(--color-divider); background: var(--color-panel);
  cursor: pointer; font-size: .88rem; list-style: none;
  transition: background var(--schnell), box-shadow var(--schnell);
}
.kopf-benutzer::-webkit-details-marker { display: none; }
.kopf-benutzer::after { content: "▾"; font-size: .62rem; opacity: .6; }
.kopf-benutzer:hover { background: var(--color-surface); box-shadow: var(--shadow-sm); }
.kopf-benutzer .ph-duotone { font-size: 1.25rem; line-height: 1; color: var(--color-neutral-700); }
.benutzer-name { max-width: 11rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 62rem) { .benutzer-name { display: none; } }

/* Der Kopf einer Klappliste: wer man ist, bevor darunter steht, was man tun kann. */
.klappliste-kopf {
  padding: .6rem; border-bottom: 1px solid var(--color-divider); margin-bottom: .25rem;
}
.klappliste-kopf strong { display: block; font-family: var(--font-heading); }
.klappliste-kopf small {
  display: block; font-size: .78rem; color: var(--color-neutral-700);
  overflow: hidden; text-overflow: ellipsis;
}
.klappliste-kopf .marke-status { margin-top: .3rem; }

.hell-dunkel { font-size: .95rem; line-height: 1; }
.leiste-griff {
  display: none; border: 0; background: none; font-size: 1.15rem; cursor: pointer;
  color: inherit; padding: .2rem .4rem; border-radius: var(--radius-sm);
}
.leiste-griff:hover { background: var(--color-surface); }

/* ------------------------------------------------------------------- Inhalt */
main {
  padding: var(--space-6) var(--space-8); flex: 1; width: 100%; max-width: none;
  /* Der Bezugsrahmen für die Raster weiter unten: Sie richten sich nach dieser Breite und
     nicht nach der des Fensters — sonst entscheidet die Seitenleiste darüber mit, wie viele
     Spalten eine Karte bekommt. */
  container-type: inline-size; container-name: inhalt;
}
/*
 * Der Takt zwischen den Blöcken einer Seite — und **innerhalb eines Blattes**.
 *
 * Die Regel galt nur für die unmittelbaren Kinder von `main`. Seit lange Seiten in Blätter
 * zerfallen (`<section data-blatt>`), ist das genau ein Kind, und alles darin stand ohne
 * Abstand aufeinander: Die Stammdatenkarte endete, acht Pixel später begann die nächste.
 */
main > * + *,
main > [data-blatt] > * + * { margin-top: var(--space-6); }
main > .knopfreihe + *, main > [data-blatt] > .knopfreihe + * { margin-top: var(--space-3); }
/* Die Reiterleiste bringt ihren Abstand selbst mit. */
main > .reiter + *, main > [data-blatt] > .reiter + * { margin-top: 0; }

/* ============================================================== 6. Bauteile
 *
 * Die deutschen Klassennamen bleiben, was sie sind — die Ansichten werden dafür nicht
 * angefasst. Nach Verbreitung geordnet: Knopf (155 Ansichten), Karte (150), Liste (130),
 * Feld (118), Statusmarke (83), Meldung (46).
 */

/* ---------------------------------------------------------------- Die Tafelkarte
 *
 * Die häufigste Fläche des Entwurfs — dort achtzehnmal als Inline-Stil vorgeführt und nie
 * als Klasse. Hier ist sie eine: helle Tafel auf abgesetztem Grund, Haarlinie, weiche
 * Rundung, leiser Schatten.
 */
.karte {
  background: var(--color-panel);
  border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  margin-bottom: 0;
}
.karte > h2, .karte > .karte-kopf {
  margin: 0; padding: var(--space-3) var(--space-4);
  background: color-mix(in srgb, var(--color-surface) 55%, var(--color-panel));
  border-bottom: 1px solid var(--color-divider);
  font-family: var(--font-heading); font-size: 1rem; font-weight: var(--font-heading-weight);
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; position: relative;
}
.karte > .karte-kopf .rechts { margin-left: auto; display: flex; gap: .4rem; }
.karte-kopf .knopfreihe { margin-left: auto; }
.karte-kopf .knopf.klein { margin-left: auto; float: none !important; }
.karte-inhalt { padding: var(--space-4) var(--space-4) var(--space-4); }
.karte-inhalt.eng { padding: .6rem var(--space-4); }
.karte-inhalt > :first-child { margin-top: 0; }
.karte-inhalt > :last-child, .karte-inhalt > form > :last-child { margin-bottom: 0; }
.karte > .tabellenrahmen { border-radius: 0 0 var(--radius-lg) var(--radius-lg); }
.karte > .leer { padding: 2rem 1rem; text-align: center; }
.karte img, .karte-inhalt img { max-width: 100%; height: auto; }
.karte-inhalt hr { border: 0; border-top: 1px solid var(--color-divider); margin: 1.2rem 0; }
/* Mehrere Abschnitte in einer Karte: eine Linie dazwischen statt eines zweiten Kastens. */
.karte-inhalt.streifen-oben { border-top: 1px solid var(--color-divider); }

/* Der Nachsatz unter einer Tabelle: erklärt, was die Zeilen bedeuten, ohne sich als Zeile
   auszugeben. Gegenstück zum Kartenkopf, nur leiser. */
.karte-fuss {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-divider);
  background: color-mix(in srgb, var(--color-surface) 45%, var(--color-panel));
  font-size: .85rem; color: var(--color-neutral-700);
}

/* Takt innerhalb einer Karte: Geschwister rücken auseinander, das erste nicht. */
.karte-inhalt > * + *,
.karte-inhalt form > * + *,
.karte-inhalt details > * + *,
.karte-inhalt .abschnitt > * + * { margin-top: .85rem; }
/*
 * **Ein verstecktes Feld ist kein Geschwister, das Platz braucht** (Kapitel 49.174).
 *
 * Fast jedes Formular beginnt mit `Csrf::field()`, einem `input[type=hidden]`. Es steht
 * nirgends, zählt aber als erstes Kind — und was dahinter kommt, bekam den Takt der Karte
 * als Abstand nach oben. In einer Knopfreihe saß der Knopf im Formular dadurch zwölf Pixel
 * tiefer als seine Nachbarn daneben: „der erledigt Button ist auch ein wenig darunter".
 */
.karte-inhalt form > input[type="hidden"] + * { margin-top: 0; }
/* Felder bringen ihren Abstand selbst mit — sonst stünde zwischen zweien die doppelte Lücke. */
.karte-inhalt .feldreihe + .feldreihe, .karte-inhalt .feld + .feld,
.karte-inhalt .feld + .feldreihe, .karte-inhalt .feldreihe + .feld { margin-top: 0; }
.karte-inhalt p + p { margin-top: .6rem; }
.karte > .tabellenrahmen + *, .karte-inhalt > .tabellenrahmen { margin-top: .85rem; }
/* Ein Formular, das an die Stelle des Karteninhalts tritt: in fünf Ansichten steht es
   unmittelbar in der Karte und erbt deren Innenmaß nicht. */
.karte > form.formular { padding: var(--space-4); }
.karte > form.formular > * + * { margin-top: .85rem; }
.karte > form.formular > .feldreihe + .feldreihe,
.karte > form.formular > .feld + .feld { margin-top: 0; }
/* Lange Formulare zerfallen in Abschnitte. Der Zwischentitel ist wichtiger als der Rahmen. */
.karte-inhalt .abschnitt {
  margin-top: 1.4rem; padding-top: 1.1rem; border-top: 1px solid var(--color-divider);
}
.karte-inhalt .abschnitt:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.karte-inhalt .abschnitt > h3, .abschnitt-titel {
  font-family: var(--font-body); font-size: .72rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--color-neutral-700); margin: 0 0 .7rem; font-weight: 700;
}
.karte-inhalt > form, .karte-inhalt > .felder { max-width: none; }

/* Die Augenbraue: 11 px Versalien über einer Zahl oder einem Block. Im Entwurf zwanzigmal
   inline, nie als Klasse. */
.augenbraue, .kennzahl .beschriftung, .beschriftung {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--color-neutral-700); font-weight: 600;
}

/* ------------------------------------------------- Die Zahl in vier Druckfarben
 *
 * Eine große Ziffer, gesetzt wie eine Seite, die mit leicht verrutschten Druckplatten vom
 * Band läuft: Cyan, Magenta und Gelb liegen ein Haar auseinander, multiplizieren sich
 * aufeinander und ergeben in der Überlappung den dunklen Kern. Die Farbsäume außen sind der
 * Passerfehler — das, was eine gedruckte Zeitung von einem Bildschirm unterscheidet.
 *
 * Aufbau: `.cmyk-num` trägt eine `.paper`-Spanne mit dem **echten** Text (für Vorlese-
 * programme und zum Markieren) und drei `.plate`-Spannen mit demselben Text, die
 * `aria-hidden` sind. Die Papierspanne ist in der Farbe des Grundes gesetzt und wirft
 * versetzte Schlagschatten derselben Farbe — zusammen sind das Weiß des Bogens, auf das die
 * Platten multipliziert werden.
 *
 * Der eigene Grund (`--cmyk-num-ground`) ist kein Schmuck: `mix-blend-mode: multiply`
 * braucht eine Rückseite. Steht die Zahl in einem eigenen Stapelkontext — und das tut sie,
 * sobald irgendwo eine Animation läuft —, fände sie ohne ihn nichts zum Multiplizieren und
 * bliebe unsichtbar. Das Polster trägt weiter als jeder Plattenversatz, der negative Rand
 * gibt die Fläche dem Layout zurück.
 *
 * `.cmyk-head` ist dasselbe für eine Überschrift, mit **halbem** Versatz: Die Haarstriche
 * einer Serifenschrift sind dünner als die Striche einer Ziffer, und der volle Versatz
 * verschluckt sie.
 */
.cmyk-num {
  --cmyk-num-ground: var(--color-bg);
  position: relative; width: fit-content; line-height: .9;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-feature-settings: "pnum" 1;
  background: var(--cmyk-num-ground); padding: .12em; margin: -.12em;
}
.cmyk-num .paper {
  color: var(--color-bg);
  text-shadow: .036em .025em 0 var(--color-bg), -.031em -.023em 0 var(--color-bg);
}
.cmyk-num .plate {
  position: absolute; inset: .12em; mix-blend-mode: multiply;
  pointer-events: none; user-select: none;
}
.cmyk-num .plate-c { color: var(--color-accent); }
.cmyk-num .plate-m { color: var(--color-accent-2);       translate: .036em .025em; }
.cmyk-num .plate-y { color: var(--color-process-yellow); translate: -.031em -.023em; }

.cmyk-head { position: relative; font-family: var(--font-heading); }
.cmyk-head .paper {
  color: var(--color-bg);
  text-shadow: .018em .0125em 0 var(--color-bg), -.0155em -.0115em 0 var(--color-bg);
}
.cmyk-head .plate {
  position: absolute; inset: 0; mix-blend-mode: multiply;
  pointer-events: none; user-select: none;
}
.cmyk-head .plate-c { color: var(--color-accent); }
.cmyk-head .plate-m { color: var(--color-accent-2);       translate: .018em .0125em; }
.cmyk-head .plate-y { color: var(--color-process-yellow); translate: -.0155em -.0115em; }

/* Die Zahl und der Satz daneben: Sie stehen auf einer Grundlinie, nicht untereinander —
   die Ziffer ist die Aussage, der Satz ihre Erläuterung. */
.aufmerksamkeit {
  display: flex; align-items: flex-end; gap: var(--space-6);
  flex-wrap: wrap; margin: var(--space-6) 0 var(--space-4);
}
.aufmerksamkeit .cmyk-num { font-size: 7.5rem; }
.aufmerksamkeit p {
  margin: 0 0 .7rem; max-width: 28rem; font-size: 1.45rem; line-height: 1.3;
  font-style: italic; font-family: var(--font-heading);
}
/* Rechts, auf Augenhöhe mit der Zahl: die vier Wege, die am häufigsten gegangen werden. */
.schnellzugriff { margin-left: auto; padding-bottom: .7rem; }
.schnellzugriff .augenbraue { margin-bottom: .4rem; }
.schnellzugriff .knopfreihe { justify-content: flex-end; max-width: 26rem; }

@media (max-width: 40rem) {
  .aufmerksamkeit { gap: var(--space-3); }
  .schnellzugriff { margin-left: 0; width: 100%; }
  .schnellzugriff .knopfreihe { justify-content: flex-start; max-width: none; }
  .aufmerksamkeit .cmyk-num { font-size: 5rem; }
  .aufmerksamkeit p { font-size: 1.15rem; margin-bottom: .3rem; }
}

/* ------------------------------------------------------------------ Seitenkopf
 *
 * Was die Seite ist, wozu sie da ist, und der eine Handgriff — in einer Zeile, bevor
 * irgendetwas anderes kommt. Auf dem Telefon untereinander, der Knopf dann volle Breite:
 * Ein Hauptknopf, der am rechten Rand klebt, wird mit dem Daumen nicht getroffen.
 */
.seitenkopf {
  display: flex; align-items: flex-start; gap: var(--space-4);
  flex-wrap: wrap; margin-bottom: var(--space-4);
}
.seitenkopf-text { flex: 1 1 22rem; min-width: 0; }
.seitenkopf h1 {
  margin: 0; font-size: 1.75rem; line-height: 1.15; letter-spacing: -.02em;
}
.seitenkopf .augenbraue { margin-bottom: .25rem; }
.seitenkopf .nebensatz {
  margin: .35rem 0 0; color: var(--color-neutral-700); font-size: .95rem;
  line-height: 1.5; max-width: 54rem;
}
.seitenkopf-knoepfe { margin-left: auto; align-items: flex-start; padding-top: .2rem; }
@media (max-width: 40rem) {
  .seitenkopf-knoepfe { margin-left: 0; width: 100%; }
  .seitenkopf-knoepfe > .knopf, .seitenkopf-knoepfe > form, .seitenkopf-knoepfe > form > .knopf {
    flex: 1 1 100%; justify-content: center;
  }
  .seitenkopf h1 { font-size: 1.45rem; }
}

/* Der leere Zustand sagt, was zu tun ist — und bietet es an. */
.leer-titel {
  font-family: var(--font-heading); font-size: 1.05rem; color: var(--color-text);
  margin-bottom: .3rem;
}
.leer p { margin: 0; max-width: 34rem; margin-inline: auto; }
.leer-knopf { justify-content: center; margin-top: .9rem; }

/* --------------------------------------------------------------------- Raster */
.raster { display: grid; gap: var(--space-4); }
/* Ein Rasterfeld ist ab Werk `min-width: auto` — es schrumpft also nie unter den breitesten
   Inhalt, sondern wächst darüber hinaus. In einem Fenster stand die zweite Karte dadurch
   nicht neben, sondern neben und außerhalb. */
.raster > * { min-width: 0; }
/* Ein Raster mit **einem** Kind ist kein Raster.
   Die zweite Spalte eines `k2` erscheint nur unter Bedingungen — der Compliance-Kasten etwa
   nur bei Lieferanten. Fehlt sie, stand die verbliebene Karte auf der halben Breite und
   daneben eine leere Fläche so groß wie sie selbst. */
.raster > :only-child { grid-column: 1 / -1; }

/* **k2 heißt zwei Spalten.**
 *
 * Vorher stand hier `repeat(auto-fit, minmax(19rem, 1fr))`, und das hieß: so viele Spalten,
 * wie hineinpassen. Auf einem breiten Schirm wurden aus „zwei" drei — und in den drei
 * schmalen Karten der Startseite waren die Tabellen danach abgeschnitten, weil eine Spalte
 * mit Beträgen nicht schmaler wird, sondern verschwindet. Eine Zahl, die man nicht sieht,
 * ist schlimmer als eine Karte weniger nebeneinander.
 *
 * Umgebrochen wird nach der Breite des **Inhaltsbereichs**, nicht des Fensters: Dasselbe
 * Raster steht auch in einer Karte und in einem Fenster, und dort hat es weniger Platz,
 * obwohl der Schirm derselbe ist. */
.raster.k2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.raster.k3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.raster.k4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@container inhalt (max-width: 1000px) {
  .raster.k4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@container inhalt (max-width: 820px) {
  .raster.k3, .raster.k4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container inhalt (max-width: 620px) {
  .raster.k2, .raster.k3, .raster.k4 { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------- Kennzahlkachel
 *
 * Die Zahl ist die Aussage, alles andere ist Beiwerk. Die farbige Kante links trägt, ob
 * etwas zu tun ist — wer hinsieht, soll es in einer Sekunde wissen.
 */
.kennzahl {
  position: relative;
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: var(--space-3) var(--space-4) var(--space-3) 1.15rem;
  transition: transform var(--schnell), box-shadow var(--schnell);
}
.kennzahl:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.kennzahl::before {
  content: ""; position: absolute; left: 0; top: .7rem; bottom: .7rem; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--color-neutral-300);
}
.kennzahl.warn::before { background: var(--color-danger); }
.kennzahl.gut::before  { background: var(--color-success); }
.kennzahl .wert {
  font-size: 2rem; font-weight: var(--font-heading-weight);
  line-height: 1.1; letter-spacing: -.02em; margin-top: .25rem;
}
.kennzahl .zusatz { font-size: .8rem; color: var(--color-neutral-700); margin-top: .25rem; }
.kennzahl.warn .wert { color: var(--color-danger-700); }
.kennzahl.gut  .wert { color: var(--color-success-700); }
/* Zwei Kontonummern statt einer Zahl: Sie sind der Wert dieser Kachel, aber keine
   Kennzahl — also in Lesegröße und ohne die Zuspitzung der großen Ziffer. */
.kennzahl .wert.konten { font-size: 1.05rem; font-family: var(--font-mono); letter-spacing: -.02em; }
a.kennzahl { text-decoration: none; color: inherit; display: block; }
a.kennzahl:hover { text-decoration: none; border-color: var(--color-neutral-400); }

/* --------------------------------------------------------------------- Knöpfe */
.knopf {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .4rem .85rem; min-height: 2.25rem;
  border: 1px solid var(--color-neutral-400); border-radius: var(--radius-sm);
  background: var(--color-panel); color: var(--color-text);
  font-size: .9rem; font-weight: 600;
  cursor: pointer; white-space: nowrap; text-decoration: none;
  box-shadow: 0 1px 1px color-mix(in srgb, var(--color-text) 6%, transparent);
  transition: background var(--schnell), border-color var(--schnell),
              box-shadow var(--schnell), transform var(--schnell);
}
.knopf:hover {
  background: var(--color-surface); text-decoration: none;
  box-shadow: 0 2px 6px color-mix(in srgb, var(--color-text) 12%, transparent);
}
.knopf:active { transform: translateY(1px); box-shadow: none; }
.knopf.haupt {
  background: var(--color-accent-700); border-color: var(--color-accent-800);
  color: var(--auf-akzent);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--color-text) 18%, transparent),
              inset 0 1px 0 color-mix(in srgb, #fff 16%, transparent);
}
.knopf.haupt:hover { background: var(--color-accent-800); border-color: var(--color-accent-900); }
.knopf.gefahr { background: var(--color-danger-700); border-color: var(--color-danger-700);
                color: var(--auf-ton); }
.knopf.gefahr:hover { background: #8a1b1b; }
.knopf.gut { background: var(--color-success-700); border-color: var(--color-success-700);
             color: var(--auf-ton); }
.knopf.gut:hover { background: #185c35; }
.knopf.klein { padding: .22rem .55rem; font-size: .8rem; min-height: 1.85rem; }
.knopf:disabled { opacity: .5; cursor: not-allowed; }
/* Ein schlichter Knopf sieht aus wie ein Verweis, verhält sich aber wie ein Knopf. */
.knopf.schlicht {
  background: none; border-color: transparent; box-shadow: none;
  color: var(--color-accent-700); padding-left: .35rem; padding-right: .35rem;
}
.knopf.schlicht:hover { background: var(--color-accent-100); box-shadow: none; }
/* Ein Knopf, der gerade arbeitet, sagt es — und lässt sich nicht zweimal drücken. */
.knopf[disabled], .knopf[aria-busy="true"] { cursor: progress; }
.knopf[aria-busy="true"]::after {
  content: ""; width: .8rem; height: .8rem; margin-left: .45rem; display: inline-block;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  animation: dreht .7s linear infinite; vertical-align: -1px;
}
@keyframes dreht { to { transform: rotate(360deg); } }

.knopfreihe { display: flex; gap: .45rem; flex-wrap: wrap; align-items: center; }
/* In einer Zelle, die ohnehin nicht umbrechen soll, bricht auch die Knopfreihe nicht:
   Zwei Zeichenknöpfe standen dort untereinander und machten die Zeile doppelt hoch. */
td.nichtbrechen > .knopfreihe { flex-wrap: nowrap; }
.knopfreihe .rechts, .knopfreihe .nach-rechts { margin-left: auto; }
/* Ein Formular, das in einer Knopfreihe steht, ist kein Absatz: Es trägt genau einen Knopf
   und soll neben den anderen stehen, nicht darunter. */
.knopfreihe form, .karte-kopf form { margin: 0; display: inline-flex; }
form > .knopfreihe:last-child { margin-top: 1rem; }
.knopf + .knopf { margin-left: .4rem; }
table.liste .knopf + .knopf { margin-left: .25rem; }
.knopfpaar { display: flex; flex-wrap: nowrap; gap: .4rem; align-items: center; }
.knopfpaar > .knopf { white-space: nowrap; }
.formularknoepfe { margin-top: .4rem; }
.formularknoepfe .klein { margin-top: .25rem; }
.blaettern, .knopfreihe.blaettern { justify-content: center; gap: .5rem; }

/* -------------------------------------------------------------------- Listen
 *
 * Eine Liste wird gelesen, nicht betrachtet: enge Zeilen, Haarlinien, und die Kopfzeile
 * bleibt stehen, damit man nach zwanzig Zeilen noch weiß, welche Spalte man vor sich hat.
 */
.tabellenrahmen { overflow: auto; max-width: 100%; border-radius: var(--radius-md); }
table.liste {
  width: 100%; border-collapse: separate; border-spacing: 0; font-size: .88rem;
}
table.liste th {
  position: sticky; top: 0; z-index: 3; text-align: left;
  padding: .5rem .8rem;
  background: var(--color-surface); color: var(--color-neutral-700);
  font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  white-space: nowrap; border-bottom: 1px solid var(--color-divider);
  box-shadow: 0 1px 0 var(--color-divider);
}
table.liste td {
  padding: .55rem .8rem; vertical-align: middle; overflow-wrap: break-word;
  border-bottom: 1px solid color-mix(in srgb, var(--color-divider) 55%, transparent);
}
table.liste td.oben { vertical-align: top; }
table.liste tbody tr { transition: background var(--schnell); }
table.liste tbody tr:hover { background: color-mix(in srgb, var(--color-text) 4%, transparent); }
table.liste tbody tr:last-child td { border-bottom: 0; }
table.liste tbody tr:hover .knopf { border-color: var(--color-neutral-500); }
table.liste .r, table.liste th.r, table.liste td.r { text-align: right; white-space: nowrap; }
table.liste .z { text-align: center; width: 1%; }
table.liste td.klein { font-size: .82rem; color: var(--color-neutral-700); }
table.liste.klein th, table.liste.klein td { padding: .42rem .7rem; font-size: .84rem; }
table.liste td .knopf.klein { white-space: nowrap; }
table.liste td.nowrap, table.liste td .knopf { overflow-wrap: normal; }
/* Die erste Spalte trägt meist die Nummer und darf nicht umbrechen; die letzte trägt die
   Knöpfe und bleibt so schmal wie möglich. Beides nur bei **mehreren** Spalten: Hat eine
   Tabelle nur eine, ist deren Zelle zugleich erste und letzte — ein Befundsatz stand dann
   auf einer Zeile und die Kachel war dreimal so breit wie die Karte. */
table.liste td:first-child:not(:last-child),
table.liste th:first-child:not(:last-child) { white-space: nowrap; }
/* …außer die Tabelle sagt, dass dort Text steht und keine Nummer. In einer schmalen Karte
   schiebt „Unbedenklichkeitsbescheinigung Krankenkasse" sonst alles Übrige aus dem Bild. */
table.liste.umbruch td:first-child, table.liste.umbruch th:first-child { white-space: normal; }
table.liste td:first-child { font-variant-numeric: tabular-nums; }
/* Die letzte Spalte bleibt schmal — **wenn dort Knöpfe stehen.**
 *
 * Vorher galt das für jede letzte Spalte, und das war in jedem zweiten Fall falsch: Steht
 * dort ein Vorgang, ein Buchungstext oder ein Befund, wird er mit `width: 1%` und `nowrap`
 * auf eine Zeile gezwungen und am Kartenrand abgeschnitten. Gemeint war immer nur die
 * Spalte mit „Öffnen" und „Bearbeiten" — also wird auch nur die gefragt. */
table.liste td:last-child:not(:first-child):has(.knopf),
table.liste td:last-child:not(:first-child):has(form) { width: 1%; white-space: nowrap; }

/* **Die Spalte mit den Knöpfen bleibt stehen.**
 *
 * Eine Liste mit zehn Spalten ist irgendwann breiter als die Karte, und dann wird als
 * Erstes das abgeschnitten, was ganz rechts steht — ausgerechnet „Öffnen". Man sieht die
 * Zeile, kann sie aber nicht anfassen, ohne vorher waagerecht zu schieben.
 *
 * Also klebt diese Spalte am rechten Rand, wie die Kopfzeile oben klebt. Der schmale
 * Schatten links davon sagt, dass darunter noch etwas liegt. */
.tabellenrahmen table.liste td:last-child:not(:first-child):has(.knopf) {
  position: sticky; right: 0; z-index: 2;
  background: var(--color-panel);
  border-left: 1px solid var(--color-divider);
}
/* Die Kopfzelle darüber klebt nach oben **und** nach rechts, also in der Ecke — und liegt
   über beiden, sonst schöbe sich eine Zeile beim Scrollen darunter hervor. */
.tabellenrahmen table.liste th:last-child:not(:first-child) {
  position: sticky; right: 0; z-index: 4;
  background: var(--color-surface);
  border-left: 1px solid var(--color-divider);
}
/*
 * Eine **Trennlinie**, kein Schatten.
 *
 * Erst stand hier ein weicher Schatten nach links — er sollte sagen: „darunter liegt noch
 * etwas". Nur wird er auch dann gezeichnet, wenn die Tabelle gar nicht breiter ist als die
 * Karte, und dann steht mitten in einer ruhigen Liste ein dunkler Streifen, den niemand
 * erklären kann. Eine Haarlinie ist in beiden Fällen richtig: Sie trennt die Knopfspalte
 * vom Inhalt, ob geschoben wird oder nicht.
 */
.tabellenrahmen table.liste tbody tr:hover td:last-child:has(.knopf) {
  background: color-mix(in srgb, var(--color-text) 4%, var(--color-panel));
}
/* Dieselbe Falle noch einmal, und sie wog schwerer: Die Beschreibungstabelle
   `<tr><th>Feld</th><td>Wert</td></tr>` sieht für die Regel darüber aus wie eine Liste mit
   zwei Spalten — jeder längere Satz lief waagerecht aus der Karte heraus. Erkennbar ist der
   Fall daran, dass die Zeile mit einer Kopfzelle **beginnt**. */
table.liste tr > th:first-child + td:last-child { width: auto; white-space: normal; }
/* Eine angeklickte Zeile bleibt erkennbar — hilfreich beim Springen zwischen Liste und Beleg. */
table.liste tbody tr:target, table.liste tbody tr.hervor { background: var(--color-accent-100); }
/* **Die Beschreibungstabelle**: links die Bezeichnung, rechts der Wert.
 *
 * Es ist dieselbe `table.liste`, aber sie wird anders gelesen — nicht Zeile für Zeile von
 * links nach rechts, sondern als Paare. Die linke Spalte bleibt schmal und ruhig, die
 * rechte bekommt den Platz und darf umbrechen. */
table.liste.paare { max-width: 48rem; }
table.liste.paare th {
  position: static; width: 34%; background: transparent; box-shadow: none;
  text-transform: none; letter-spacing: 0; font-size: .82rem; font-weight: 600;
  color: var(--color-neutral-700); vertical-align: top; white-space: normal;
}
table.liste.paare td { white-space: normal; width: auto; }

/* Eine Erklärzeile unter der Zeile, auf die sie sich bezieht: keine obere Linie, damit sie
   als Fortsetzung gelesen wird und nicht als eigener Eintrag. */
table.liste tr.erklaerzeile > td { border-top: none; padding-top: 0; padding-bottom: .5rem; }
/* Zeilen, die etwas kosten: rot sperrt die Zahlung, gelb kostet 15 % Steuerabzug. */
.zeile-sperre > td { background: var(--color-danger-100); }
.zeile-abzug  > td { background: var(--color-warning-100); }
/* Eine Position, die wir nicht anbieten: sichtbar, aber erkennbar nicht im Angebot. */
tr.gestrichen td { color: var(--color-neutral-700); }
tr.gestrichen td:nth-child(-n+3) { text-decoration: line-through; }
.gekuerzt {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
  display: inline-block; vertical-align: bottom;
}
.nicht-umbrechen, .nowrap { white-space: nowrap; }

/* ------------------------------------------------------------------ Leerzustand
 * Eine leere Liste ist kein Fehler: ruhiger Text, mittig, mit Luft — und er sagt, was jetzt
 * zu tun ist, nicht „keine Daten".
 */
.leer, td.leer, table.liste .leer, .karte-inhalt > .leer {
  padding: 2.2rem 1rem; text-align: center; color: var(--color-neutral-700);
  font-size: .9rem; font-style: normal;
}
table.liste .leer a { font-weight: 600; }

/* --------------------------------------------------------------------- Felder
 *
 * Alle Eingabefelder, und ausgenommen wird, was wirklich anders ist. Die Aufzählung nach
 * `type` traf 73 Felder nicht: Wer kein `type` schreibt, bekommt vom Browser ein Textfeld —
 * aber `input[type=text]` greift dann nicht.
 */
.feld { display: flex; flex-direction: column; gap: .3rem; margin-bottom: .9rem; }
.feld > label, .feld > .beschriftung {
  font-family: var(--font-body); font-size: .78rem; font-weight: 600;
  color: var(--color-neutral-700); letter-spacing: .02em; text-transform: none;
}
.feld > label [aria-hidden="true"] { color: var(--color-danger-700); font-weight: 400; }
.feldreihe { display: flex; gap: .9rem; flex-wrap: wrap; align-items: flex-start; }
.feldreihe > .feld { flex: 1 1 12rem; min-width: 0; }
/* Ein Knopf in einem Feld bleibt so breit wie sein Wort.
   `.feld` ist eine Spalte (`flex-direction: column`), und ein Kind darin wird auf die volle
   Breite gezogen — bei einem Eingabefeld ist das richtig, bei einem Knopf sah es aus, als
   habe sich jemand vertan: „Einlesen" 250 Pixel breit. */
.feld > .knopf, .feld > button { align-self: flex-start; }

/* Ein Feld, das in seiner Reihe mehr Platz braucht — eine Leistungsbeschreibung neben zwei
   Datumsfeldern. Ohne die Regel lief der Text in einem Schlitz. */
.feldreihe > .feld.gross { flex: 2.5 1 20rem; }
/* Ein Feld, in das drei bis fünf Zeichen kommen — eine Postleitzahl, eine Hausnummer. */
.feldreihe > .feld.schmal { flex: 0 0 7rem; }
/* Ein Feld mit kurzem Inhalt soll nicht die ganze Zeile nehmen: zwei Wörter in einem Feld
   von Rand zu Rand sehen aus wie ein Fehler. */
.feld.kurz { max-width: 16rem; }
/* Ein Feld ohne Beschriftung soll unten fluchten, nicht oben. */
.feldreihe > .feld.unten, .feldreihe > .knopfreihe { align-self: flex-end; }

/* Der Liquiditätskalender (Kapitel 49.133): ein Monat als Gitter, sieben Spalten gleich
   breit. Die Zelle trägt oben den Tag, darunter Zu- und Abgang und unten den Stand —
   deshalb eine feste Mindesthöhe: Ein Gitter, dessen Zeilen unterschiedlich hoch sind,
   liest sich nicht als Kalender. */
table.kalender { width: 100%; border-collapse: collapse; table-layout: fixed; }
table.kalender th { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
  color: var(--color-neutral-700); padding: .3rem .4rem; text-align: left; }
table.kalender td { border: 1px solid var(--color-divider); vertical-align: top;
  padding: .35rem .45rem; height: 4.8rem; font-size: .78rem; }
table.kalender td.fremd { background: var(--color-neutral-100); border-color: transparent; }
table.kalender td.heute { outline: 2px solid var(--color-accent); outline-offset: -2px; }
table.kalender td.erwartet { background: repeating-linear-gradient(135deg,
  transparent, transparent 6px, var(--color-neutral-100) 6px, var(--color-neutral-100) 12px); }
table.kalender .kopf { font-weight: 600; font-size: .85rem; }
table.kalender .ein { color: var(--color-success-700); }
table.kalender .aus { color: var(--color-danger-700); }
table.kalender .saldo { margin-top: .2rem; font-variant-numeric: tabular-nums;
  color: var(--color-neutral-700); border-top: 1px dotted var(--color-divider); }

/* Eine abgehakte Zeile der Pickliste (Kapitel 49.123): leise, aber nicht unleserlich —
   sie bleibt stehen, damit man sieht, was man schon hat. */
table.liste tr.erledigt > td { color: var(--color-neutral-600); }
table.liste tr.erledigt > td:nth-child(3) { text-decoration: line-through; }

/* Mehrere Ausprägungen auf einmal (Kapitel 49.114).
   Je Ausprägung ein kleines Mengenfeld, in einer umbrechenden Reihe: Fünf Farben sind eine
   Zeile, zwanzig sind vier. Ein Feld je Zeile hätte den Vorschlag länger gemacht als die
   Positionsliste, über der er steht. */
.auspraegungen { display: flex; flex-wrap: wrap; gap: .4rem .5rem; }
.auspraegungen > label {
  display: inline-flex; align-items: center; gap: .4rem;
  border: 1px solid var(--color-neutral-300); border-radius: var(--radius-sm);
  background: var(--color-panel); padding: .2rem .3rem .2rem .55rem;
  font-size: .82rem; font-weight: 500; color: var(--color-text);
}
/* `flex-basis` statt `width`: Die Breite steht in der Sammelregel für alle Eingabefelder auf
   100 %, und die ist mit zwölf `:not()` nicht zu überbieten — in einem Flexkasten sticht die
   Basis sie ohne `!important`. */
.auspraegungen > label > input { flex: 0 0 4rem; text-align: right; }
.auspraegungen .frei {
  font-size: .72rem; color: var(--color-neutral-600); font-variant-numeric: tabular-nums;
}
/* Was nicht da ist, bekommt den Rand der Warnung — die Zahl allein las sich wie jede andere. */
.auspraegungen > label.nichts { border-color: var(--color-warning); }
.auspraegungen > label.nichts .frei { color: var(--color-warning-700); }
.feld .hinweis, .hinweis {
  font-size: .78rem; color: var(--color-neutral-700); line-height: 1.45; margin-top: .1rem;
}

/* Alles auf einer Zeile: Ein Zeilenumbruch zwischen zwei `:not()` wäre ein Leerzeichen —
   und damit ein Nachfahrenselektor. Die Regel griffe dann für nichts. */
input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=range]):not([type=file]):not([type=submit]):not([type=button]):not([type=reset]):not([type=image]):not([type=color]),
select, textarea, .auswahl-knopf {
  font: inherit; font-size: .88rem;
  color: var(--color-text); background: var(--eingabe-grund);
  border: 1px solid var(--color-neutral-400); border-radius: var(--radius-sm);
  padding: .46rem .62rem; min-height: 2.25rem; width: 100%;
  transition: border-color var(--schnell), box-shadow var(--schnell);
}
input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=range]):not([type=submit]):not([type=button]):not([type=reset]):focus,
select:focus, textarea:focus, .auswahl-knopf:focus-visible {
  border-color: var(--color-accent-600); outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 22%, transparent);
}
input:disabled, select:disabled, textarea:disabled {
  background: var(--color-surface); color: var(--color-neutral-600); cursor: not-allowed;
}
input[readonly], textarea[readonly] {
  background: var(--color-surface); border-style: dashed; color: var(--color-neutral-700);
}
textarea { min-height: 5rem; line-height: 1.5; resize: vertical; }
textarea[rows="2"] { min-height: 3.6rem; }
textarea[rows="3"] { min-height: 5rem; }
input::placeholder, textarea::placeholder { color: var(--color-neutral-600); }
/* Ein `size`-Attribut aus alten Ansichten darf die Breite bestimmen. */
input[size] { width: auto; min-width: 6rem; }
input.klein, select.klein, .auswahl-knopf.klein { font-size: .82rem; min-height: 1.95rem; padding: .3rem .5rem; }
input[type=date], input[type=month], input[type=time], input[type=datetime-local] { max-width: 12rem; }
input[type=date]::-webkit-calendar-picker-indicator,
input[type=month]::-webkit-calendar-picker-indicator { opacity: .55; cursor: pointer; }
input[type=date]:hover::-webkit-calendar-picker-indicator { opacity: 1; }
/* Zahlen stehen rechts und fluchten. */
input[type=number], input[data-betrag], input.betrag {
  text-align: right; font-variant-numeric: tabular-nums; max-width: 12rem;
}
/* Ein Zahlenfeld für zwei oder drei Ziffern — Tage, eine Reihenfolge. Es steht **hinter**
   der Regel darüber: Beide sind gleich stark, also entscheidet die Reihenfolge. */
input.zahlfeld { width: auto; max-width: 5.5rem; min-width: 0; }
table.liste td.r input, table.liste td.r select,
table.liste th.r input { text-align: right; font-variant-numeric: tabular-nums; }
input[type=color] {
  width: 2.6rem; height: 2.25rem; padding: .18rem; border: 1px solid var(--color-neutral-400);
  border-radius: var(--radius-sm); background: var(--color-panel); cursor: pointer;
}
/* ------------------------------------------------------- Dateien ziehen und ablegen
 *
 * Jedes Dateifeld ist zugleich eine Ablagefläche. Die Hülle wird von `app.js` um das Feld
 * gelegt — die Ansichten schreiben weiter nur `<input type="file">`.
 *
 * Solange eine Datei über dem Fenster schwebt (`body.datei-schwebt`), leuchten **alle**
 * Flächen auf, die sie annehmen würden: Ein 40 Pixel hohes Feld trifft man im Ziehen
 * sonst selten, und man sieht erst nach dem Loslassen, ob es geklappt hat.
 */
input[type=file] {
  font-size: .85rem; cursor: pointer; min-height: 2.6rem; width: 100%;
  border: 1px dashed var(--color-neutral-400); border-radius: var(--radius-sm);
  padding: .5rem; background: var(--color-surface);
}
/* Die Zeile unter einem IBAN-Feld: zu wem gehört dieses Konto, und stimmt die Nummer.
   Sie steht da, sobald genug Zeichen eingegeben sind — und sie sagt den Namen der Bank,
   nicht bloß „gültig": Die Frage, die man wirklich hat, ist „ist das die Bank, die ich
   meine?". */
.ibanhinweis {
  font-size: .78rem; line-height: 1.4; margin-top: .25rem;
  color: var(--color-neutral-700);
}
.ibanhinweis.stimmt { color: var(--color-success-700); }
.ibanhinweis.stimmt-nicht { color: var(--color-danger-700); font-weight: 600; }

.ablagefeld { position: relative; }
.ablagefeld-wort {
  display: block; margin-top: .3rem; font-size: .76rem; color: var(--color-neutral-600);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ablagefeld.hat-datei .ablagefeld-wort { color: var(--color-success-700); font-weight: 600; }
body.datei-schwebt .ablagefeld input[type=file] {
  border-color: var(--color-accent-500); background: var(--color-accent-100);
}
.ablagefeld.ablage-offen input[type=file] {
  border-color: var(--color-accent-600); border-style: solid;
  background: var(--color-accent-200);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 22%, transparent);
}
.ablagefeld.ablage-offen .ablagefeld-wort { color: var(--color-accent-800); }
input[type=file]::file-selector-button {
  font: inherit; font-size: .82rem; margin-right: .7rem; cursor: pointer;
  border: 1px solid var(--color-neutral-400); background: var(--color-panel);
  color: var(--color-text); border-radius: var(--radius-sm); padding: .3rem .7rem;
}
input[type=file]::file-selector-button:hover { background: var(--color-surface); }
input[type=range] { accent-color: var(--color-accent-600); width: 100%; }
input[type=checkbox], input[type=radio] {
  width: 1.05rem; height: 1.05rem; accent-color: var(--color-accent-600);
}
label:has(> input[type=checkbox]), label:has(> input[type=radio]) {
  display: inline-flex; align-items: center; gap: .45rem; font-size: .88rem;
}
/* Ein Feld, dessen Inhalt den Vorgang aufhält. */
input.fehlerfeld, textarea.fehlerfeld, .auswahl-knopf.fehlerfeld {
  border-color: var(--color-danger); color: var(--color-danger-700);
}
/* Ein Feld, das erst durch eine Eingabe zur Pflicht wird (Kapitel 49.52): Der Grund einer
   Preisänderung ist nur verlangt, wenn der Preis sich wirklich ändert. */
input.pflicht, textarea.pflicht, select.pflicht, .auswahl-knopf.pflicht {
  border-color: var(--color-danger); background: var(--color-danger-100);
}
input.pflicht:focus, textarea.pflicht:focus, select.pflicht:focus,
.auswahl-knopf.pflicht:focus-visible { outline-color: var(--color-danger); }
/* Ein Wert, den eine Maschine aus Handschrift gelesen hat: Ihm muss anzusehen sein, dass
   ihn noch niemand gegen das Blatt gehalten hat. */
input.ungeprueft { border-color: var(--color-warning); background: var(--color-warning-100); }
/* Der Text, der gleich hinausgeht — lesbar, aber erkennbar nicht zu ändern. */
textarea.vorschautext {
  font-family: var(--font-mono); font-size: .85rem; line-height: 1.5; background: var(--color-surface);
}

/* Fieldsets tragen ihre Überschrift als Zwischentitel, nicht als Rahmenunterbrechung.
 *
 * `min-inline-size: 0` ist kein Schönheitsstrich: Ein `fieldset` bekommt vom Browser ab Werk
 * `min-inline-size: min-content` und schrumpft deshalb nicht mit — in einem Fenster wuchs es
 * aus der Karte heraus nach rechts. */
fieldset {
  border: 0; border-top: 1px solid var(--color-divider); padding: 1rem 0 0; margin: 1.3rem 0 0;
  min-inline-size: 0; min-width: 0;
}
/* Das `float: left` ist kein Gestaltungsmittel, sondern der einzige verlässliche Weg, ein
   `<legend>` aus der Sonderbehandlung des Browsers in den normalen Fluss zu holen. Nur: Ein
   Float muss aufgehoben werden, sonst stellt sich die nächste `.feldreihe` **neben** die
   Überschrift statt darunter. */
fieldset > legend {
  padding: 0; color: var(--color-neutral-700); text-transform: uppercase;
  font-family: var(--font-body); font-size: .7rem; font-weight: 700; letter-spacing: .08em;
  float: left; width: 100%; margin-bottom: .6rem;
}
fieldset > legend + * { clear: both; }

/* Ein Häkchen mit Beschriftung ist eine Zeile, kein Feld: Es bekommt eine Fläche, damit man
   den ganzen Text anklicken kann und nicht das 16-Pixel-Kästchen treffen muss. */
.kontrollkaestchen {
  display: flex; align-items: flex-start; gap: .45rem; font-size: .88rem;
  padding: .35rem .5rem; margin: 0 -.5rem; border-radius: var(--radius-sm);
  cursor: pointer; transition: background var(--schnell); line-height: 1.45;
}
.kontrollkaestchen:hover { background: var(--color-surface); }
.kontrollkaestchen input { margin-top: .18rem; flex: 0 0 auto; }
.kontrollkaestchen:has(input:checked) { color: var(--color-text); font-weight: 500; }
.kontrollkaestchen .hinweis { font-weight: 400; margin-top: .15rem; }
.kaestchengruppe {
  display: grid; gap: .1rem; border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); padding: .5rem .8rem;
}

/* Ein Formular, das in eine Zeile passt: Beschriftung, Auswahl, Knopf nebeneinander — die
   kleine Schwester der Filterleiste, für eine Entscheidung statt für eine Suche. */
.formzeile { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.formzeile > label { font-size: .82rem; color: var(--color-neutral-700); white-space: nowrap; }
.formzeile .feld { margin-bottom: 0; }
.formzeile > select { flex: 0 1 300px; min-width: 180px; }

/* Filterleiste über den Listen: eine Zeile, die zusammengehört. */
.filterleiste {
  display: flex; flex-wrap: wrap; gap: .6rem; align-items: flex-end;
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); padding: .8rem 1rem; box-shadow: var(--shadow-sm);
  margin-bottom: 1rem;
}
.filterleiste .feld { margin-bottom: 0; min-width: 150px; }
.filterleiste .feld > label { font-size: .72rem; }
.filterleiste .feld.breit { flex: 1 1 16rem; }
.filterleiste .knopf { align-self: flex-end; }

/* -------------------------------------------------------------- Ändern in der Zeile
 * Eine Zelle, die sich ändern lässt, muss das zeigen — aber leise: Die Tabelle ist zuerst
 * zum Lesen da. Darum nur beim Überfahren eine Andeutung und der Zeiger, der es verrät.
 */
.zelle-aenderbar { cursor: text; }
.zelle-aenderbar:hover {
  background: color-mix(in srgb, var(--color-accent) 7%, transparent);
  box-shadow: inset 0 -1px 0 var(--color-accent-400);
}
.zelle-feld {
  width: 100%; min-width: 4rem; font: inherit; font-size: .86rem;
  padding: .15rem .3rem; margin: -.15rem -.3rem;
  border: 1px solid var(--color-accent-600); border-radius: var(--radius-sm);
  background: var(--color-panel); color: var(--color-text);
}
.zelle-feld.r { text-align: right; font-variant-numeric: tabular-nums; }
/* Ein änderbarer Wert mitten in einer Zelle, neben der eine Marke steht („läuft ab").
   Er braucht eine Breite, damit das Eingabefeld beim Doppelklick nicht auf die Breite des
   alten Textes zusammenfällt — „15.01.2027" ist lang, „—" ist es nicht. */
.zellwert { display: inline-block; min-width: 5.5rem; }
.zelle-laeuft { opacity: .5; }
/* Was sich geändert hat, leuchtet kurz auf — auch die Summen oben, die mitgewandert sind. */
.zelle-frisch { animation: zelle-frisch 1.2s ease-out; }
@keyframes zelle-frisch {
  from { background: color-mix(in srgb, var(--color-success) 35%, transparent); }
  to   { background: transparent; }
}
@media (prefers-reduced-motion: reduce) { .zelle-frisch { animation: none; } }

/* ------------------------------------------------------------------ Filterreihe
 * Pillen, keine Reiter. Ein Filter engt dieselbe Seite ein, ein Reiter wechselt sie —
 * standen beide untereinander und sahen gleich aus, führte eine der beiden Zeilen
 * scheinbar woandershin, als sie es tat.
 */
.filterreihe {
  display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
  margin-bottom: var(--space-4);
}
.filtermarke {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .25rem .7rem; border-radius: 999px;
  border: 1px solid var(--color-neutral-400); background: var(--color-panel);
  color: var(--color-neutral-800); font-size: .82rem; text-decoration: none;
  transition: background var(--schnell), border-color var(--schnell), color var(--schnell);
}
.filtermarke:hover { border-color: var(--color-accent-600); color: var(--color-text); }
.filtermarke.aktiv {
  background: var(--color-accent-700); border-color: var(--color-accent-700);
  color: #fff; font-weight: 600;
}
/* Eine Zahl neben dem Wort sagt vor dem Klick, ob er sich lohnt. */
.filterzahl {
  font-variant-numeric: tabular-nums; font-size: .74rem;
  padding: 0 .3rem; border-radius: 999px;
  background: var(--color-surface); color: var(--color-neutral-700);
}
.filtermarke.aktiv .filterzahl {
  background: color-mix(in srgb, #fff 26%, transparent); color: #fff;
}
/* Wo nichts ist, bleibt die Pille anwählbar — sie beweist, dass dort nichts ist.
   Steht sie gerade auf der Seite, bleibt sie voll: Wer hinsieht, ist dort. */
.filtermarke.leerlauf { opacity: .55; }
.filtermarke.leerlauf.aktiv { opacity: 1; }

/* ----------------------------------------------------------------- Statusmarken
 * Tonfläche 100 auf Schrift 700 — dieselbe Helligkeitsstufe in jedem Ton, deshalb schreit
 * keine der fünf lauter als die anderen.
 */
.marke-status {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .12rem .55rem; border-radius: 999px;
  font-size: .72rem; font-weight: 700; letter-spacing: .02em; white-space: nowrap;
  border: 1px solid transparent;
}
.marke-status + .marke-status { margin-left: .3rem; }
/* Eine Marke **ohne** Ton: Sie kommt vor — „Zuständig für: Angebote · Rechnungen" sind
   Marken ohne Bedeutungsfarbe. Ohne eigene Regel waren sie durchsichtig und liefen als
   Fließtext ineinander: „Angebote und Aufträge Rechnungen". */
.marke-status:not([class*="m-"]) {
  background: var(--color-surface); color: var(--color-neutral-800);
  border-color: var(--color-divider); font-weight: 600;
}
.m-grau  { background: var(--color-neutral-200);  color: var(--color-neutral-800);
           border-color: var(--color-neutral-300); }
.m-blau  { background: var(--color-accent-100);   color: var(--color-accent-800);
           border-color: var(--color-accent-200); }
.m-gruen { background: var(--color-success-100);  color: var(--color-success-700);
           border-color: color-mix(in srgb, var(--color-success) 30%, transparent); }
.m-gelb  { background: var(--color-warning-100);  color: var(--color-warning-700);
           border-color: color-mix(in srgb, var(--color-warning) 35%, transparent); }
.m-rot   { background: var(--color-danger-100);   color: var(--color-danger-700);
           border-color: color-mix(in srgb, var(--color-danger) 30%, transparent); }

.ampel {
  display: inline-block; width: .62rem; height: .62rem; border-radius: 50%; vertical-align: -1px;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 12%, transparent);
}
.ampel.gruen { background: var(--color-success); }
.ampel.gelb  { background: var(--color-warning); }
.ampel.rot   { background: var(--color-danger); }
.ampel.blau  { background: var(--color-accent); }
/* Ein kleiner Punkt in der Farbe der Kolonne: Vier Kolonnen unterscheidet man schneller
   nach Farbe als nach dem Lesen der Beschriftung. */
.farbtupfer {
  display: inline-block; width: .65rem; height: .65rem; border-radius: 50%;
  margin-right: .35rem; vertical-align: baseline;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-text) 20%, transparent);
}

/* --------------------------------------------------------------------- Meldungen */
.meldung {
  padding: .7rem 1rem; border-radius: var(--radius-md); margin-bottom: 1rem;
  border: 1px solid; border-left: 3px solid currentColor; font-size: .88rem;
  box-shadow: var(--shadow-sm);
}
.meldung.erfolg { background: var(--color-success-100); border-color: var(--color-success-700);
                  color: var(--color-success-700); }
.meldung.fehler { background: var(--color-danger-100);  border-color: var(--color-danger-700);
                  color: var(--color-danger-700); }
.meldung.warnung{ background: var(--color-warning-100); border-color: var(--color-warning-700);
                  color: var(--color-warning-700); }
.meldung.info   { background: var(--color-accent-100);  border-color: var(--color-accent-800);
                  color: var(--color-accent-800); }
.meldung ul { margin: .4rem 0 0; padding-left: 1.1rem; }

.leise { color: var(--color-neutral-700); }
.klein { font-size: .82rem; }
.gross { font-size: 1.1rem; }
.zahl { text-align: right; white-space: nowrap; }
/* Zwei Knöpfe in einer Tabellenzelle bleiben nebeneinander: untereinander liest man sie
   als zwei Zustände und nicht als zwei Wege. */
.nichtbrechen { white-space: nowrap; }
.negativ { color: var(--color-danger-700); font-variant-numeric: tabular-nums; }
.positiv { color: var(--color-success-700); }
.inaktiv { opacity: .5; }
.abstand-unten { margin-bottom: 1.1rem; }
/* Ein knapper Abstand nach oben — für das, was unmittelbar zur Zeile darüber gehört:
   ein Formular unter einem Wert, eine Marke unter einem Namen. */
.etwas-oben { margin-top: .4rem; }
.etwas-unten { margin-bottom: .5rem; }
.weiter-oben { margin-top: .9rem; }
.ohne-abstand { margin: 0 !important; }
.eng-unten { margin-bottom: 0 !important; }
/* Ein Element, das in einer Zeile mitläuft, statt eine eigene zu beanspruchen. */
.inzeile { display: inline-block; }
/* Ein Rasterfeld, das die ganze Reihe nimmt — eine Überschrift über vier Spalten. */
.ganze-reihe { grid-column: 1 / -1; }
/* Ein Feld, das nur so breit sein soll wie sein Inhalt. Eingaben nehmen sonst die ganze
   Zeile — in einer Tabellenzelle ist das die ganze Spalte. */
.breite-auto { width: auto !important; min-width: 0; }
/* Ein Vorschaubild in einer Tabellenzelle: quadratisch, beschnitten, klein genug, dass acht
   davon die Zeile nicht sprengen. */
.bildchen {
  width: 38px; height: 38px; object-fit: cover; margin: 1px;
  border-radius: 4px; border: 1px solid var(--color-divider); vertical-align: middle;
}
/* Ein Fortschrittsbalken in einer Tabellenzelle steht unter der Zahl, nicht neben ihr. */
.balken.schmal { max-width: 150px; margin-top: .25rem; }
.abstand-oben { margin: .9rem 0 .3rem; }
.eng-oben { margin-top: 0 !important; }
.weit-oben { margin-top: 1.5rem; }
.verborgen { display: none; }
.eingereiht { display: inline; }
.fenster-titel { font-family: var(--font-heading); font-size: 1.05rem; margin: 1.5rem 0 .6rem; }

/* -------------------------------------------------------------- Fortschrittsbalken */
.balken {
  height: 10px; border-radius: 999px; background: var(--color-surface);
  border: 1px solid var(--color-divider); overflow: hidden;
}
.balken > span {
  display: block; height: 100%; border-radius: 999px;
  background: var(--color-accent-600); transition: width var(--ruhig);
}
.balken.warn > span { background: var(--color-danger); }

/* ------------------------------------------------------------------ Schrittfolge
 * Ein mehrstufiger Vorgang muss zeigen, wo man steht und was noch kommt. Ohne das drückt
 * man am Ende auf „Absenden" und weiß nicht, ob noch eine Rückfrage kommt.
 */
.schrittfolge { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.schrittfolge .schritt {
  padding: .35rem .8rem; border-radius: 999px; font-size: .85rem;
  background: var(--color-surface); color: var(--color-neutral-700);
  border: 1px solid var(--color-divider);
}
.schrittfolge .schritt.aktiv {
  background: var(--color-accent-700); color: var(--auf-akzent);
  border-color: var(--color-accent-700); font-weight: 600;
}
.schrittfolge .schritt.erledigt { color: var(--color-accent-700); border-color: var(--color-accent-400); }

/* ---------------------------------------------------------------------- Reiter
 * Sie laufen um, statt zu scrollen. Die Verwaltung hat fünfzehn Reiter; waagerecht
 * geschoben lagen drei davon außerhalb des Bildes, und ein Reiter, den man nicht sieht, ist
 * keiner. Zwei Zeilen kosten acht Bildpunkte.
 */
/* **Keine Kästchen.**
 *
 * Der aktive Reiter trug eine helle Fläche mit Rundung — auf dem abgesetzten Grund der
 * Seite sah das aus, als sei ein Stück Papier hineingeklebt worden, und zwar schief: Die
 * Fläche begann am Text und hörte an ihm auf, während die Leiste darunter durchlief.
 *
 * Eine Reiterleiste ist eine **Zeile mit einer Unterstreichung**. Der Strich sagt, wo man
 * steht; mehr braucht es nicht. Der Abstand zwischen den Wörtern trennt sie, nicht ein
 * Rahmen um jedes.
 */
.reiter {
  display: flex; gap: var(--space-4); flex-wrap: wrap; overflow-x: visible;
  border-bottom: 1px solid var(--color-divider); margin-bottom: var(--space-4);
}
.reiter a {
  padding: .55rem 0 .5rem; font-size: .92rem; color: var(--color-neutral-700);
  white-space: nowrap; border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color var(--schnell), border-color var(--schnell);
}
.reiter a:hover {
  color: var(--color-text); text-decoration: none;
  border-bottom-color: var(--color-neutral-400);
}
.reiter a.aktiv {
  border-bottom-color: var(--color-accent-600);
  color: var(--color-text); font-weight: 600;
}

/* ================================= Die Schublade „Meldungen und Fristen"
 *
 * Von rechts, über die Seite gelegt, **ohne sie zu verlassen**. Sie ist schmaler als ein
 * Fenster und höher: Was darin steht, ist eine Liste, und eine Liste liest man von oben
 * nach unten, nicht von links nach rechts.
 *
 * Die Bewegung ist die eigentliche Auskunft: Sie kommt von dort, wo die Glocke steht, und
 * geht dorthin zurück. Ein Kasten, der aufblinkt, hinterlässt die Frage, wo er herkam.
 */
.schublade-hintergrund {
  position: fixed; inset: 0; z-index: 880;
  background: transparent; transition: background var(--ruhig);
  display: flex; justify-content: flex-end;
}
.schublade-hintergrund.offen { background: var(--color-scrim); }
.schublade {
  width: min(27rem, 100%); height: 100%; display: flex; flex-direction: column;
  background: var(--color-panel); border-left: 1px solid var(--color-divider);
  box-shadow: var(--shadow-lg);
  transform: translateX(100%); transition: transform var(--ruhig);
}
.schublade-hintergrund.offen .schublade { transform: none; }

.schublade-kopf {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-4);
  border-bottom: 1px solid var(--color-divider);
  background: color-mix(in srgb, var(--color-surface) 45%, var(--color-panel));
}
.schublade-kopf h2 { margin: .1rem 0 0; font-size: 1.2rem; }
.schublade-kopf .modal-schliessen { margin-left: auto; }

.schublade-inhalt { flex: 1 1 auto; overflow: auto; padding: 0 0 var(--space-4); }
.schublade-laedt {
  padding: var(--space-8) var(--space-4); text-align: center;
  color: var(--color-neutral-600); font-size: .9rem;
}

.schublade-gruppe { padding: var(--space-4) var(--space-4) 0; }
.schublade-gruppe .augenbraue {
  display: flex; align-items: center; gap: var(--space-2); margin-bottom: .4rem;
}
.schublade-gruppe .augenbraue form { margin-left: auto; }

/* Eine Zeile: links wann, rechts was — und die linke Kante trägt die Dringlichkeit, damit
   der Text selbst ruhig bleiben kann. */
.schublade-zeile {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: .6rem .7rem; margin-bottom: .3rem;
  border-left: 3px solid var(--color-divider);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--color-surface);
}
.schublade-zeile.wichtig { border-left-color: var(--color-warning); }
.schublade-zeile.ernst {
  border-left-color: var(--color-danger); background: var(--color-danger-100);
}
.schublade-datum {
  flex: 0 0 5.5rem; font-size: .8rem; font-weight: 600; line-height: 1.4;
  color: var(--color-neutral-700);
}
.schublade-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.schublade-text strong { font-size: .92rem; line-height: 1.3; }
.schublade-text small {
  font-size: .78rem; color: var(--color-neutral-700); line-height: 1.35;
}
.schublade-zeile form { flex: 0 0 auto; margin: 0; }

.schublade-fuss {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-divider); background: var(--color-surface);
}
.schublade-fuss .knopf { width: 100%; justify-content: center; }

@media (max-width: 30rem) { .schublade { width: 100%; } }
/* -------------------------------------------------------- Das Konto eines Partners
 *
 * „oben fett Kontostand:" — die Zahl, wegen der die Akte aufgemacht wird. Sie steht über
 * den Blättern, weil sie auf jedem gilt, und sie trägt ihre Richtung als Wort daneben:
 * Ein Vorzeichen allein beantwortet nicht, wer wem schuldet. */
.kontostreifen {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  align-items: baseline; justify-content: space-between;
  margin: var(--space-3) 0 var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-divider);
  border-left: 3px solid var(--color-neutral-400);
  border-radius: var(--radius-md);
  background: var(--color-panel);
}
.kontostreifen.plus  { border-left-color: var(--color-success-700); }
.kontostreifen.minus { border-left-color: var(--color-danger-700); }
.kontowort { font-family: var(--font-heading); font-weight: 600; }
.kontozahl {
  font-size: 1.5rem; font-variant-numeric: tabular-nums;
  font-family: var(--font-heading); margin: 0 .35rem;
}
.kontostreifen.plus  .kontozahl { color: var(--color-success-700); }
.kontostreifen.minus .kontozahl { color: var(--color-danger-700); }
.kontorichtung { color: var(--color-neutral-700); }
.kontoteile { display: flex; gap: var(--space-4); align-items: baseline; font-size: .85rem; }
.kontoteile strong { font-variant-numeric: tabular-nums; }

/* Blättern unter der Nachrichtenliste: zwei Knöpfe und die Seitenzahl dazwischen. */
.pf-blaettern {
  display: flex; align-items: center; justify-content: space-between; gap: .5rem;
  padding: .6rem .7rem; border-top: 1px solid var(--color-divider);
}

/* Eine Zahl, die unter null steht, soll man sehen, ohne das Vorzeichen zu suchen —
   Minusstunden und aufgebrauchter Urlaub (Kapitel 49.181). */
strong.minus, td.minus { color: var(--color-danger-700); }
/* Eine Zeile aus Feld und Knopf, die in eine Tabellenzelle passt. */
.reihe-eng { display: flex; gap: .3rem; align-items: center; justify-content: flex-end; }
.reihe-eng input { width: 4rem; }

/* Was zu einem Beleg gehört, rückt unter ihn ein: Abzüge, Verrechnungen, Zahlungen.
   Eingeklappt sind sie vom Skript, nicht vom HTML — ohne Skript steht alles da. */
table.konto .kontoteil td:nth-child(2) { padding-left: var(--space-5); }
table.konto .kontoteil td { color: var(--color-neutral-700); border-top: 0; padding-top: .15rem; }
table.konto .kontoteil + .kontogruppe td { border-top-width: 1px; }
table.konto td:nth-child(n+3) { font-variant-numeric: tabular-nums; }
table.konto .kontogruppe[data-konto-bereit] { cursor: pointer; }
table.konto .kontogruppe.offen > td { background: var(--color-surface); }

.kontopfeil {
  border: 0; background: none; cursor: pointer; padding: 0 .3rem 0 0;
  color: var(--color-neutral-700); font-size: .7rem; line-height: 1;
}
.kontopfeil:hover { color: var(--color-accent-700); }

.merkposten { display: grid; gap: .35rem; font-size: .85rem; }
.merkposten strong { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------ Der ausgestellte Unterlagenlink
 *
 * Er steht genau einmal da (gespeichert ist nur sein Abdruck) und ist hundert Zeichen lang.
 * Darum ein eigenes Feld statt eines Satzes mit einem Wurm darin: markierbar, kopierbar,
 * und mit `text-overflow` statt Umbruch — eine Adresse über drei Zeilen liest niemand. */
.neuerlink { border-color: var(--color-success-700); }
.neuerlink .karte-kopf { color: var(--color-success-700); }
.linkfeld {
  flex: 1 1 24rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .85rem;
  text-overflow: ellipsis;
  background: var(--color-surface);
}

@media print { .schublade-hintergrund { display: none !important; } }

/* ============================================================== Sammelaktionen
 *
 * Die Leiste erscheint unten, sobald etwas gewählt ist, und verschwindet, sobald nichts
 * mehr gewählt ist. Sie liegt **über** dem Inhalt und nicht darin: Wer dreißig Zeilen
 * durchgeht, soll nicht nach jeder Auswahl ans Ende scrollen müssen, um zu handeln.
 */
.sammel-spalte { width: 1%; white-space: nowrap; padding-right: 0 !important; }
.sammel-spalte input[type=checkbox] { vertical-align: middle; cursor: pointer; }
/* Eine gewählte Zeile ist unübersehbar — sonst zählt man die Kästchen. */
table.liste tbody tr.gewaehlt { background: var(--color-accent-100); }
table.liste tbody tr.gewaehlt td:first-child { box-shadow: inset 3px 0 0 var(--color-accent-600); }
.tabellenrahmen table.liste tbody tr.gewaehlt td:last-child:has(.knopf) {
  background: var(--color-accent-100);
}

.sammelleiste {
  position: fixed; left: 50%; bottom: var(--space-4); transform: translateX(-50%);
  z-index: 800; display: flex; align-items: center; gap: var(--space-3);
  max-width: calc(100vw - 2 * var(--space-4)); flex-wrap: wrap;
  padding: var(--space-2) var(--space-3) var(--space-2) var(--space-4);
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: 999px; box-shadow: var(--shadow-lg);
  animation: hoch var(--ruhig);
}
.sammel-zahl { font-family: var(--font-heading); font-weight: 600; white-space: nowrap; }
.sammel-aktionen { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.sammel-vorrat { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.sammel-form { display: flex; align-items: center; gap: .35rem; margin: 0; }
/* Ein Auswahlfeld in der Leiste nimmt die Breite seines Inhalts, nicht die der Zeile. */
.sammel-form select, .sammel-form input {
  width: auto !important; min-width: 11rem; max-width: 18rem; min-height: 2rem;
  font-size: .85rem;
}
.sammel-form .knopf { white-space: nowrap; }

@media (max-width: 46rem) {
  .sammelleiste {
    left: 0; right: 0; bottom: 0; transform: none; max-width: none;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    justify-content: center;
  }
}
@media print { .sammelleiste, .sammel-spalte { display: none !important; } }

/* ============================================================ Die Befehlspalette
 *
 * Strg+K. Sie liegt über allem, nimmt die Mitte und beginnt weiter oben als ein Fenster —
 * man sieht beim Tippen die Liste wachsen, und die soll nicht nach unten aus dem Bild
 * laufen.
 *
 * Jede Zeile trägt **vier** Dinge, und die Reihenfolge ist die des Blicks: ein Symbol (was
 * ist das für ein Ding), der Name, darunter leise die Einordnung, rechts der Zustand. Der
 * Treffer selbst ist hervorgehoben — es ist der Unterschied zwischen „warum steht das
 * hier?" und „ach ja".
 *
 * Angewählt wird mit den Pfeiltasten, und was angewählt ist, trägt `.aktiv` — **nicht**
 * `:hover`: Beim Tippen liegt die Maus still, und eine Auswahl, die unter dem Zeiger
 * springt, verliert man aus dem Blick.
 */
.palette-hintergrund { align-items: flex-start; padding-top: 10vh; }
.palette {
  width: min(46rem, 100%); max-height: 74vh; display: flex; flex-direction: column;
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); overflow: hidden;
  animation: auf var(--schnell);
}
.palette-kopf {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-divider);
  background: color-mix(in srgb, var(--color-surface) 40%, var(--color-panel));
}
.palette-lupe { font-size: 1.3rem; color: var(--color-neutral-600); line-height: 1; }
.palette-feld {
  flex: 1 1 auto; border: 0 !important; background: none !important;
  font-family: var(--font-heading) !important;
  font-size: 1.25rem !important; padding: 0 !important; min-height: 2rem !important;
  box-shadow: none !important; outline: none;
}
.palette-feld::placeholder { color: var(--color-neutral-500); font-weight: 400; }
/* Das Kreuz des Browsers im Suchfeld: Es sitzt neben unserem eigenen und tut dasselbe. */
.palette-feld::-webkit-search-cancel-button { display: none; }

.palette-liste { overflow: auto; padding: var(--space-2) 0 var(--space-3); flex: 1 1 auto; }
.palette-gruppe {
  padding: var(--space-3) var(--space-4) .25rem;
  position: sticky; top: 0; z-index: 1;
  background: color-mix(in srgb, var(--color-panel) 92%, transparent);
  backdrop-filter: blur(4px);
}
.palette-zeile {
  display: flex; align-items: center; gap: var(--space-3); width: 100%;
  border: 0; background: none; cursor: pointer; text-align: left;
  font: inherit; color: inherit;
  padding: .5rem var(--space-4);
  border-left: 3px solid transparent;
}
.palette-symbol {
  flex: 0 0 auto; width: 1.3rem; font-size: 1.3rem; line-height: 1;
  color: var(--color-neutral-600);
}
.palette-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.palette-titel {
  font-family: var(--font-heading); font-weight: 600; font-size: 1rem; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.palette-zusatz {
  font-size: .8rem; color: var(--color-neutral-700); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.palette-zeile mark {
  background: color-mix(in srgb, var(--color-accent) 24%, transparent);
  color: inherit; border-radius: 3px; padding: 0 .05em;
}
.palette-zeile .marke-status { flex: 0 0 auto; }
.palette-pfeil {
  flex: 0 0 auto; width: 1.2rem; text-align: center;
  color: var(--color-accent-700); opacity: 0; font-size: .95rem;
}

.palette-zeile.aktiv {
  background: var(--color-accent-100); border-left-color: var(--color-accent-600);
}
.palette-zeile.aktiv .palette-titel { color: var(--color-accent-800); }
.palette-zeile.aktiv .palette-symbol { color: var(--color-accent-700); opacity: 1; }
.palette-zeile.aktiv .palette-pfeil { opacity: 1; }
.palette-zeile.aktiv mark {
  background: color-mix(in srgb, var(--color-accent) 36%, transparent);
}

.palette-leer {
  padding: var(--space-6) var(--space-8); text-align: center;
  color: var(--color-neutral-700); font-size: .9rem;
}
.palette-leer strong {
  display: block; font-family: var(--font-heading); font-size: 1.05rem;
  color: var(--color-text); margin-bottom: .4rem;
}
.palette-leer p { margin: 0; max-width: 30rem; margin-inline: auto; line-height: 1.5; }

.palette-fuss {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-2) var(--space-4);
  background: var(--color-surface); border-top: 1px solid var(--color-divider);
  font-size: .76rem; color: var(--color-neutral-700);
}
.palette-fuss .rechts { margin-left: auto; font-style: italic; }
kbd {
  display: inline-block; font-family: var(--font-body); font-size: .72rem;
  line-height: 1.3; padding: .1rem .35rem; margin-right: .2rem;
  border: 1px solid var(--color-divider); border-bottom-width: 2px;
  border-radius: 4px; background: var(--color-panel); color: var(--color-neutral-700);
}

@media (max-width: 36rem) {
  .palette-hintergrund { padding-top: 0; align-items: stretch; }
  .palette { width: 100%; max-height: 100%; border-radius: 0; }
  .palette-zusatz, .palette-fuss .rechts { display: none; }
}

/* Der Auslöser in der Kopfleiste. Er sieht aus wie ein Suchfeld, weil er eines öffnet —
   ein Tastengriff, den niemand kennt, ist keiner. */
.palette-knopf {
  display: flex; align-items: center; gap: var(--space-2);
  min-width: 13rem; max-width: 22rem; flex: 0 1 auto;
  padding: .35rem .5rem .35rem .7rem;
  border: 1px solid var(--color-divider); border-radius: 999px;
  background: var(--color-panel); color: var(--color-neutral-600);
  font: inherit; font-size: .88rem; cursor: text; text-align: left;
  transition: border-color var(--schnell), box-shadow var(--schnell), color var(--schnell);
}
.palette-knopf:hover {
  border-color: var(--color-accent-400); box-shadow: var(--shadow-sm);
  color: var(--color-text);
}
.palette-knopf .wort { flex: 1 1 auto; }
.palette-knopf .nav-zeichen { opacity: 1; width: 1.1rem; font-size: 1.05rem; }
@media (max-width: 70rem) {
  .palette-knopf { min-width: 0; }
  .palette-knopf .wort, .palette-knopf kbd { display: none; }
}

/* ----------------------------------------------------------------- Klappknopf
 *
 * Ein Knopf, hinter dem mehrere Wege liegen. Gebaut aus `<details>`, damit ohne JavaScript
 * nichts verlorengeht — der Browser klappt es dann selbst auf.
 *
 * Die zweite Zeile eines Eintrags (`<small>`) sagt, **wann** man ihn nimmt. Das ist der
 * eigentliche Gewinn gegenüber drei Knöpfen nebeneinander: Dort steht nur, wie etwas heißt.
 */
.klappknopf { position: relative; display: inline-block; }
.klappknopf > summary.knopf::after { content: "▾"; font-size: .7rem; opacity: .7; }
.klappknopf[open] > summary.knopf::after { transform: rotate(180deg); }
.klappknopf[open] { background: none; border: 0; padding: 0; margin: 0; }
.klappliste {
  position: absolute; right: 0; top: calc(100% + .35rem); z-index: 50;
  min-width: 20rem; max-width: 26rem; padding: .3rem;
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  animation: auf var(--schnell);
}
.klappliste > a, .klappliste button {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  font: inherit; color: inherit; cursor: pointer;
  padding: .5rem .6rem; border-radius: var(--radius-sm); text-decoration: none;
  font-family: var(--font-heading); font-weight: 600; font-size: .92rem;
}
.klappliste > a:hover, .klappliste button:hover {
  background: var(--color-accent-100); color: var(--color-accent-800); text-decoration: none;
}
.klappliste small {
  display: block; margin-top: .1rem; font-family: var(--font-body);
  font-size: .76rem; font-weight: 400; line-height: 1.35; color: var(--color-neutral-700);
}
.klappliste > a:hover small, .klappliste button:hover small { color: inherit; opacity: .8; }
.klappliste form { margin: 0; display: block; }

/* Die allgemeine Regel für aufgeklappte `<details>` mit Knopf gilt hier nicht: Der
   Klappknopf trägt seine Liste schwebend, nicht als Fläche darunter. */
details.klappknopf[open] { background: none; border: 0; padding: 0; margin: 0; }
details.klappknopf[open] > summary.knopf { margin-bottom: 0; }

/* ---------------------------------------------------------------------- Fenster
 *
 * Ein Fenster ist kein kleiner Bildschirm, sondern **eine Frage an einer Stelle**: Es legt
 * sich über die Seite, weil die Antwort hierher gehört und nicht auf eine neue Adresse.
 *
 * Deshalb drei Maße und nicht mehr: die Rückfrage (schmal, zwei Knöpfe), das Formular
 * (weit, scrollt), die Liste (breit). Alles andere wäre ein Fenster, das aussieht wie eine
 * Seite — und dann hätte man besser eine Seite genommen.
 *
 * Auf dem Telefon kommt es von unten und nimmt die ganze Breite: Ein zentriertes Kästchen
 * mit 8 % Rand an jeder Seite ist auf 390 Pixeln kein Fenster mehr, sondern ein Schlitz.
 */
.modal-hintergrund {
  position: fixed; inset: 0; background: var(--color-scrim); backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center; z-index: 900;
  padding: var(--space-4); animation: ein var(--schnell);
}
.modal-fenster {
  background: var(--color-panel); border-radius: var(--radius-lg);
  width: min(28rem, 100%); box-shadow: var(--shadow-lg); overflow: hidden;
  max-height: min(92vh, 56rem); display: flex; flex-direction: column;
  animation: auf var(--ruhig);
}
/* Ein Formular ist breiter als eine Rückfrage — und länger, also scrollt sein Inhalt. */
.modal-fenster.weit { width: min(58rem, 100%); }
/* Ein Fenster, in dem eine Liste steht, braucht mehr Platz als zwei Knöpfe. */
.modal-fenster.breit { width: min(46rem, 100%); }
.modal-kopf {
  display: flex; align-items: center; gap: .6rem;
  padding: var(--space-3) var(--space-4);
  font-weight: var(--font-heading-weight); font-size: 1.1rem;
  background: color-mix(in srgb, var(--color-surface) 55%, var(--color-panel));
  border-bottom: 1px solid var(--color-divider);
}
.modal-kopf .rechts { margin-left: auto; }
/* Das Kreuz schließt, und es sagt das ohne Wort. Der Knopf daneben hieß „Schließen", stand
   im Kopf neben dem Titel und sah aus wie eine Handlung — ein Kreuz wird nicht verwechselt. */
.modal-schliessen {
  margin-left: auto; flex: 0 0 auto; border: 0; background: none; cursor: pointer;
  width: 2rem; height: 2rem; border-radius: var(--radius-sm); line-height: 1;
  font-size: 1.15rem; color: var(--color-neutral-700);
  display: grid; place-items: center;
  transition: background var(--schnell), color var(--schnell);
}
.modal-schliessen:hover { background: var(--color-surface); color: var(--color-text); }
.modal-inhalt { padding: var(--space-4); overflow: auto; }
.modal-fenster .modal-inhalt { flex: 1 1 auto; }
/* Der Text einer Rückfrage: Zeilenumbrüche aus dem Quelltext bleiben stehen — sie sind dort
   gesetzt worden, weil der Satz sonst zu lang wäre. */
.modal-frage { margin: 0; white-space: pre-line; font-size: .95rem; line-height: 1.55; }

@media (max-width: 36rem) {
  .modal-hintergrund { align-items: flex-end; padding: 0; }
  .modal-fenster, .modal-fenster.weit, .modal-fenster.breit {
    width: 100%; max-height: 92vh;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    animation: hoch var(--ruhig);
  }
}
@keyframes hoch { from { transform: translateY(100%); } }
.modal-inhalt .karte { box-shadow: none; border: 0; margin: 0; }
.modal-inhalt .karte-kopf { display: none; }
/*
 * Hier standen zwei Regeln, die mehr kaputt machten, als sie richteten:
 *
 *   .modal-inhalt label  { display: block; … }
 *   .modal-inhalt select, .modal-inhalt input { width: 100%; }
 *
 * Beide sind **spezifischer** als die allgemeinen Feldregeln und haben sie deshalb
 * überstimmt — ausgerechnet dort, wo es keiner nachsieht. Ein `.kontrollkaestchen` ist ein
 * `label` und soll eine Flexzeile sein; als Block brach sein Text in eine zwei Zeichen
 * breite Spalte um. Und ein Häkchen ist ein `input`; auf 100 % Breite gezogen war es ein
 * leeres Rechteck über die halbe Maske.
 *
 * Die allgemeinen Regeln können beides längst richtig: Eingaben sind voll breit, Häkchen
 * und Auswahlknöpfe sind ausdrücklich ausgenommen. Also keine Sonderregel fürs Fenster.
 */
.modal-fuss {
  display: flex; gap: .5rem; justify-content: flex-end;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface); border-top: 1px solid var(--color-divider);
}

/* **Der Hauptknopf bleibt sichtbar, auch wenn das Formular lang ist.**
 *
 * Die Stammdaten eines Bauvorhabens sind zwanzig Felder. Im Fenster stand „Speichern"
 * darunter — also außerhalb des Bildes, bis man ganz nach unten gescrollt hatte. Wer ein
 * Feld oben ändert, sieht keinen Weg, das zu sichern, und schließt im Zweifel das Fenster.
 *
 * Die Knopfreihe am Fuß eines Formulars klebt deshalb am unteren Rand des Fensters. Die
 * negativen Ränder holen sie über das Polster des Inhalts hinweg bis an die Kanten — sonst
 * stünde sie auf einer Insel, durch die man den Text darunter durchscheinen sieht. */
.modal-inhalt form > .knopfreihe:last-child,
.modal-inhalt > .knopfreihe:last-child {
  position: sticky; bottom: calc(var(--space-4) * -1); z-index: 3;
  margin: var(--space-4) calc(var(--space-4) * -1) calc(var(--space-4) * -1);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border-top: 1px solid var(--color-divider);
  justify-content: flex-end;
}
/* Was nur auf der Seite gilt, nicht im Fenster: Der Fensterkopf trägt die Überschrift schon. */
.modal-inhalt .nur-seite { display: none; }
@keyframes ein { from { opacity: 0; } }
@keyframes auf { from { opacity: 0; transform: translateY(12px) scale(.985); } }

/* Das Bearbeitungsformular stand bisher zweimal auf der Seite: einmal als Ansicht oben und
   einmal als Formular unten. Versteckt wird es ausschließlich, wenn JavaScript läuft — ohne
   Skript gibt es kein Fenster, und dann muss es erreichbar bleiben. */
html.js [data-nur-fenster] { display: none; }
html.js .modal-inhalt [data-nur-fenster] { display: block; }

/* ------------------------------------------------------------------- Hinweise
 * Unten rechts — für den Anruf, der gerade hereinkommt, und für die Meldung nach einer
 * Handlung, die über die Warteschlange läuft.
 */
.hinweise {
  position: fixed; right: 1rem; bottom: 1rem; z-index: 950;
  display: flex; flex-direction: column; gap: .5rem; max-width: 22rem;
}
.hinweis-kasten {
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-left: 3px solid var(--color-accent-600); border-radius: var(--radius-md);
  padding: .7rem .85rem; box-shadow: var(--shadow-lg); cursor: pointer; font-size: .9rem;
  animation: hinweis-auf .2s ease-out;
}
.hinweis-kasten.erfolg { border-left-color: var(--color-success); }
.hinweis-kasten.fehler { border-left-color: var(--color-danger); }
@keyframes hinweis-auf { from { opacity: 0; transform: translateY(.5rem); } }

.hoerer {
  border: 0; background: none; cursor: pointer; padding: 0 .25rem; font-size: 1rem;
  line-height: 1; color: var(--color-accent-700); opacity: .55;
}
.hoerer:hover { opacity: 1; }
.feld-mit-hoerer { display: flex; align-items: center; gap: .25rem; }
.feld-mit-hoerer input { flex: 1 1 auto; min-width: 0; }
.feld-mit-hoerer .hoerer { flex: 0 0 auto; font-size: 1.1rem; padding: 0 .35rem; }
.telefon-ziel { font-size: 1.05rem; margin-bottom: .2rem; }
.telefon-meldung { margin: .7rem 0 0; color: var(--color-danger-700); font-size: .88rem; }

/* ------------------------------------------------- Aufklappbares als Bedienteil
 * `<details><summary class="knopf">` steckt in zwei Dutzend Ansichten: „Neues Dokument",
 * „Bankverbindung", „Token". Aufgeklappt bekommt das Formular eine eigene Fläche — dann ist
 * zu sehen, wo es anfängt und wo es aufhört.
 */
details > summary { cursor: pointer; list-style: none; }
details > summary::-webkit-details-marker { display: none; }
details[open] > summary { margin-bottom: .5rem; }
details > summary.knopf { display: inline-flex; align-items: center; gap: .35rem; }
/* Ein Kartenkopf, der aufklappt, muss das zeigen. Ohne Zeichen sah die zugeklappte Karte
   aus wie eine Überschrift ohne Inhalt — also wie eine halbfertige Seite. */
details > summary.karte-kopf::after {
  content: "▾"; margin-left: auto; font-size: .8rem; opacity: .6;
  transition: transform var(--schnell);
}
details[open] > summary.karte-kopf::after { transform: rotate(180deg); }
details > summary.karte-kopf:hover { color: var(--color-accent-700); }
details[open] > summary.karte-kopf { margin-bottom: 0; }
details > summary.knopf::after {
  content: "▾"; font-size: .7rem; opacity: .6; transition: transform var(--schnell);
}
details[open] > summary.knopf::after { transform: rotate(180deg); }
details:has(> summary.knopf)[open] {
  background: var(--color-surface); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); padding: .7rem .8rem; margin: .3rem 0 .6rem;
}
details:has(> summary.knopf)[open] > form { margin-top: .6rem; }
details:has(> summary.knopf)[open] .feld:last-of-type { margin-bottom: .6rem; }
/* In einer Tabellenzelle darf das Aufklappbare die Zeile nicht sprengen — und auch nicht
   aus ihr herauslaufen: Die letzte Spalte ist auf Knöpfe eingestellt (`width: 1%`,
   `nowrap`), und ein Auswahlfeld darin stand außerhalb des Rahmens, wo es niemand
   anklicken konnte. Aufgeklappt gilt deshalb die umgekehrte Regel. */
table.liste details:has(> summary.knopf)[open] {
  background: transparent; border: 0; padding: 0; margin: .2rem 0 0;
}
table.liste td details:has(> summary.knopf)[open] { white-space: normal; }
table.liste td details:has(> summary.knopf)[open] > form {
  display: flex; flex-wrap: wrap; gap: .4rem; align-items: center;
}
table.liste td details:has(> summary.knopf)[open] > form select { min-width: 0; max-width: 100%; }

/* ------------------------------------------------------------------ Rechenweg
 * Der Weg von der Auftragssumme zum Zahlbetrag. Beträge brechen nicht um: Sobald links eine
 * Erläuterung steht, wird die Spalte sonst schmal und „1.000,00 €" rutscht auf zwei Zeilen.
 */
.rechenweg { width: 100%; font-size: .9rem; }
.rechenweg td { padding: .22rem .4rem; }
.rechenweg td.r { text-align: right; white-space: nowrap; }
.rechenweg tr.summe td { border-top: 1px solid var(--color-neutral-400); font-weight: 600; }
.rechenweg tr.gesamt td {
  border-top: 2px solid var(--color-text); font-weight: 700; font-size: .98rem;
}
.rechenweg tr.einzug td:first-child { padding-left: 1.6rem; color: var(--color-neutral-700); }

/* Dieselben Gewichte, wenn der Rechenweg im Fuß einer Liste steht (Kapitel 49.93):
   Unter der letzten Position einer Rechnung erwartet jeder Netto, Steuer und Brutto — und
   zwar so abgesetzt, dass der Bruttobetrag die letzte Zeile ist und nicht die zehnte. */
table.liste tfoot td { background: var(--color-panel); padding: .34rem .7rem; }
table.liste tfoot tr.summe td { border-top: 1px solid var(--color-neutral-400); font-weight: 600; }
table.liste tfoot tr.gesamt td {
  border-top: 2px solid var(--color-text); font-weight: 700; font-size: 1rem;
}
table.liste tfoot tr.einzug td:first-child {
  padding-left: 1.6rem; color: var(--color-neutral-700);
}

/* ----------------------------------------------------------------- Vertragstext
 * Der Wortlaut eines Vertrags steht auf Papierweiß und scrollt für sich: Er ist lang, und
 * wer ihn liest, soll die Seite darunter nicht verlieren.
 */
.vertragstext {
  background: #fff; border: 1px solid var(--color-divider); border-radius: var(--radius-sm);
  padding: 1.2rem; max-height: 60vh; overflow: auto;
}
body.dunkel .vertragstext { background: var(--color-panel); }

/* --------------------------------------------------------------- Vorschlagsliste
 * Beim Tippen einer Rechnungsposition. Die Liste hängt unter dem Feld und darf über die
 * Karte hinausragen — sonst müsste das Feld die halbe Zeile hoch sein.
 */
.vorschlagsliste {
  position: absolute; z-index: 40; left: 0; right: 0; top: 100%;
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  max-height: 16rem; overflow: auto;
}
.vorschlagsliste button {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  padding: .45rem .6rem; cursor: pointer; font: inherit; color: inherit;
}
.vorschlagsliste button:hover,
.vorschlagsliste button[aria-selected="true"] { background: var(--color-accent-100); }
.vorschlagsliste .vs-preis { float: right; font-variant-numeric: tabular-nums; }
.vorschlagsliste .vs-woher { font-size: .75rem; opacity: .65; }

/* Der handschriftliche Vermerk vom Blatt, als Zitat gesetzt. */
.handschrift {
  border-left: 3px solid var(--color-neutral-400); padding-left: .7rem; font-style: italic;
}
/* Das Feld, in das mit dem Finger unterschrieben wird. `touch-action: none` ist nicht
   Kosmetik: Ohne das scrollt ein Telefon die Seite, statt einen Strich zu zeichnen.
   Weiß bleibt es auch dunkel — der Namenszug wird in Schwarz gezeichnet und landet
   unverändert auf einem weißen Blatt. */
.zeichenflaeche {
  width: 100%; height: 200px; background: #fff; border: 1px dashed var(--color-neutral-400);
  border-radius: var(--radius-sm); touch-action: none; cursor: crosshair; display: block;
}

/* ===================================================== 7. Besondere Flächen */

/* ------------------------------------------------------------ Arbeitsfläche
 * Die Seite ist der erste Reiter, jedes geöffnete Dokument ein weiterer.
 */
/* Dieselbe Handschrift wie die Reiterleiste einer Seite: eine Zeile mit einer
   Unterstreichung, kein Kästchen. Hier bleibt etwas mehr Polster, weil jeder Reiter noch
   ein Kreuz zum Schließen trägt. */
.reiterleiste {
  display: flex; align-items: stretch; gap: var(--space-3); margin: 0 0 var(--space-4);
  border-bottom: 1px solid var(--color-divider); overflow-x: auto; scrollbar-width: thin;
}
.reiter-knopf {
  display: inline-flex; align-items: center; gap: .45rem; border: 0; background: none;
  font: inherit; font-size: .9rem; color: var(--color-neutral-700);
  padding: .55rem 0 .5rem; margin-bottom: -1px;
  cursor: pointer; white-space: nowrap;
  border-bottom: 2px solid transparent; max-width: 16rem;
  transition: color var(--schnell), border-color var(--schnell);
}
.reiter-knopf span { overflow: hidden; text-overflow: ellipsis; }
.reiter-knopf:hover { color: var(--color-text); border-bottom-color: var(--color-neutral-400); }
.reiter-knopf.aktiv {
  color: var(--color-text); font-weight: 600; border-bottom-color: var(--color-accent-600);
}
.reiter-knopf i {
  font-style: normal; font-size: 1rem; line-height: 1; opacity: .45;
  border-radius: 4px; padding: 0 .18rem;
}
.reiter-knopf i:hover { opacity: 1; background: color-mix(in srgb, var(--color-text) 10%, transparent); }
.reiter-teilen {
  margin-left: auto; border: 0; background: none; cursor: pointer; font-size: .95rem;
  color: var(--color-neutral-700); padding: .3rem .6rem; border-radius: var(--radius-sm);
}
.reiter-teilen:hover, .reiter-teilen.aktiv {
  background: var(--color-accent-100); color: var(--color-accent-800);
}
.reiterflaeche { display: grid; grid-template-columns: 1fr; gap: .8rem; height: calc(100vh - 11rem); }
.reiterflaeche.geteilt { grid-template-columns: 1fr 1fr; }
@media (max-width: 62rem) { .reiterflaeche.geteilt { grid-template-columns: 1fr; } }
.reiter-rahmen {
  display: flex; flex-direction: column; background: var(--color-panel);
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm); overflow: hidden; min-height: 0;
}
.reiter-kopf {
  display: flex; align-items: center; gap: .6rem; padding: .4rem .7rem;
  border-bottom: 1px solid var(--color-divider); font-size: .84rem; font-weight: 600;
  background: var(--color-surface);
}
.reiter-kopf .knopf { margin-left: auto; font-weight: 400; }
.reiter-rahmen iframe { flex: 1 1 auto; width: 100%; border: 0; background: var(--color-panel); }

/* ------------------------------------------------------------------- Bauakte
 * Ein Aktenschrank, kein Formular: links der Baum, rechts die Kacheln. Wer Dateien sucht,
 * sucht sie mit den Augen — deshalb Symbole und nicht eine weitere Tabelle.
 */
.explorer { display: grid; grid-template-columns: 17rem 1fr; gap: 1rem; align-items: start; }
@media (max-width: 62rem) { .explorer { grid-template-columns: 1fr; } }
.ex-baum, .ex-inhalt {
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm);
}
.ex-baum { padding: .5rem .35rem; position: sticky; top: 1rem; max-height: 82vh; overflow: auto; }
.ex-baum-kopf { font-weight: 600; padding: .3rem .6rem .5rem; font-size: .9rem; }
.ex-zweig {
  display: flex; align-items: center; gap: .4rem; padding: .3rem .5rem;
  border-radius: var(--radius-sm); text-decoration: none; color: inherit; font-size: .88rem;
}
.ex-zweig svg { width: 18px; height: 18px; flex: 0 0 auto; }
.ex-zweig span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ex-zweig em {
  margin-left: auto; font-style: normal; font-size: .76rem; color: var(--color-neutral-700);
}
.ex-zweig:hover { background: var(--color-surface); }
.ex-zweig.aktiv { background: var(--color-accent-100); font-weight: 600; }
.ex-inhalt { display: flex; flex-direction: column; min-height: 26rem; }
.ex-leiste {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .6rem .9rem; border-bottom: 1px solid var(--color-divider);
}
.ex-pfad { font-size: .95rem; display: flex; align-items: center; gap: .35rem;
           flex-wrap: wrap; min-width: 0; }
.ex-pfad a { text-decoration: none; color: inherit; padding: .1rem .3rem; border-radius: 4px; }
.ex-pfad a:hover { background: var(--color-surface); }
.ex-pfad a:last-child { font-weight: 600; }
.ex-trenner { color: var(--color-neutral-700); }
.ex-werkzeuge { margin-left: auto; display: flex; gap: .4rem; }
.ex-flaeche {
  flex: 1 1 auto; display: grid; gap: .5rem; padding: .9rem;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr)); align-content: start;
}
.ex-flaeche.ablage-offen {
  outline: 2px dashed var(--color-accent-600); outline-offset: -8px;
  background: var(--color-accent-100);
}
.ex-leer { grid-column: 1 / -1; color: var(--color-neutral-700); font-size: .9rem;
           margin: 2rem 0; text-align: center; }
.ex-kachel {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: .25rem;
  padding: .7rem .4rem .5rem; border-radius: var(--radius-md); text-align: center;
  text-decoration: none; color: inherit; border: 1px solid transparent;
  transition: background var(--schnell), border-color var(--schnell), transform var(--schnell);
}
.ex-kachel:hover {
  background: var(--color-surface); border-color: var(--color-divider); transform: translateY(-1px);
}
.ex-kachel a {
  display: flex; flex-direction: column; align-items: center; gap: .25rem;
  text-decoration: none; color: inherit; min-width: 0; width: 100%;
}
.ex-kachel svg { filter: drop-shadow(0 1px 1px color-mix(in srgb, var(--color-text) 12%, transparent)); }
.ex-name {
  font-size: .84rem; line-height: 1.25; word-break: break-word;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ex-zusatz { font-size: .74rem; color: var(--color-neutral-700); }
.ex-marke {
  font-size: .68rem; color: var(--color-accent-800); background: var(--color-accent-100);
  border-radius: 4px; padding: 0 .3rem;
}
.ex-entnehmen { position: absolute; top: .2rem; right: .2rem; margin: 0; opacity: 0; }
.ex-kachel:hover .ex-entnehmen { opacity: 1; }
.ex-x {
  border: 0; background: var(--color-panel); color: var(--color-danger-700); border-radius: 50%;
  width: 1.3rem; height: 1.3rem; line-height: 1; cursor: pointer;
  box-shadow: 0 1px 4px color-mix(in srgb, var(--color-text) 20%, transparent);
}
/* „Bearbeiten" auf einer Dateikachel: Es ist die zweite Handlung — die erste ist Öffnen,
   und die soll der Knopf nicht überschreien. */
.ex-bearbeiten {
  position: absolute; left: .4rem; bottom: .35rem; font-size: .68rem; padding: .1rem .35rem;
  border-radius: var(--radius-sm); color: var(--color-neutral-700); text-decoration: none; opacity: 0;
}
.ex-kachel:hover .ex-bearbeiten, .ex-bearbeiten:focus-visible { opacity: 1; }
/* Im Zuordnungsmodus ist „zuordnen" die Handlung der Seite und darf sich nicht erst
   beim Darüberfahren zeigen. */
.ex-flaeche.waehlen .ex-bearbeiten { opacity: 1; }
.ex-bearbeiten:hover { background: var(--color-accent-100); color: var(--color-accent-800); }
/* „Markieren" steht der zweiten Handlung gegenüber: links öffnen zum Ändern, rechts
   ansehen und anstreichen. */
.ex-markieren {
  position: absolute; right: .4rem; bottom: .35rem; font-size: .68rem; padding: .1rem .35rem;
  border: 0; background: none; cursor: pointer;
  border-radius: var(--radius-sm); color: var(--color-neutral-700); opacity: 0;
}
.ex-kachel:hover .ex-markieren, .ex-markieren:focus-visible { opacity: 1; }
.ex-flaeche.waehlen .ex-markieren { opacity: 1; }
.ex-markieren:hover { background: var(--color-accent-100); color: var(--color-accent-800); }
.ex-fuss {
  border-top: 1px solid var(--color-divider); padding: .45rem .9rem; font-size: .78rem;
  color: var(--color-neutral-700);
  /* Zähler links, Netzlaufwerk rechts. Vorher standen beide im Textfluss und lasen sich als
     ein Satz: „22 Ordner, 1 Datei Als Netzlaufwerk: \\…". */
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
}
.ex-fuss > .rechts { margin-left: auto; }
.ex-fuss code { font-size: .78rem; }

/* Das Blatt in der Dokumentenansicht: so hoch, dass eine A4-Seite lesbar ist, und nicht
   höher — darunter stehen die Angaben, und die sollen erreichbar bleiben. */
.dokumentblatt { height: 78vh; min-height: 24rem; margin-bottom: 1rem; }
.dokumentbild {
  flex: 1 1 auto; width: 100%; min-height: 0; object-fit: contain;
  background: var(--color-surface);
}

/* Das Laufwerk (Kapitel 49.97): dieselben Kacheln, zwei Zusätze.
 * Das Band sagt, dass gerade ein Ordner gewählt wird; „gehört zu" steht in der Leiste und
 * nicht an der Kachel, weil es den geöffneten Ordner betrifft und nicht einen darin. */
.zuordnungsband { display: flex; align-items: center; gap: 1rem; }
.zuordnungsband > :first-child { flex: 1 1 auto; min-width: 0; }
.ex-gehoert {
  display: flex; align-items: center; gap: .35rem; flex-wrap: wrap;
  font-size: .8rem; color: var(--color-neutral-700);
}
.ex-gehoert a { color: inherit; }

/* ----------------------------------------------- Leistungsverzeichnis und Kalkulation
 * Titel tragen die Struktur, Positionen den Inhalt. Ohne den Unterschied liest sich ein LV
 * mit 300 Zeilen wie eine Liste ohne Anfang.
 */
.lv-titel > td { font-weight: 600; background: var(--color-surface); }
.lv-langtext { max-width: 60ch; }
/* Zahlen in einer Kalkulation sind Felder, sehen aber aus wie Text — bis man hineinklickt.
   Ein Raster aus vierzig sichtbaren Kästen liest sich nicht mehr als Tabelle; ein Knopf
   „Ändern" hinter jeder Zeile kostet bei vierzig Positionen achtzig Klicks. */
input.zellfeld {
  width: 100%; max-width: 6.5rem; border: 1px solid transparent; background: transparent;
  text-align: right; padding: .1rem .25rem; border-radius: var(--radius-sm);
  font: inherit; color: inherit; font-variant-numeric: tabular-nums; min-height: 0;
}
input.zellfeld.schmal { max-width: 3.4rem; text-align: left; }
input.zellfeld:hover { border-color: var(--color-neutral-400); }
input.zellfeld:focus {
  border-color: var(--color-accent-600); background: var(--color-panel);
  outline: none; box-shadow: none;
}
/* Ein gesetzter Einheitspreis sieht anders aus als ein gerechneter — sonst unterscheidet
   später niemand mehr die Kalkulation vom Wunsch. */
.ep-zelle.ist-fest { background: var(--color-warning-100); }
.ep-zelle.ist-fest input.zellfeld { font-weight: 600; }
.ep-quelle {
  display: block; font-size: .62rem; color: var(--color-neutral-700);
  text-transform: uppercase; letter-spacing: .02em; line-height: 1.3;
}
.ep-zelle.ist-fest .ep-quelle { color: var(--color-warning-700); font-weight: 600; }
/* Der Positionstext: zugeklappt die Überschrift, aufgeklappt das Formular. */
.postext > summary { cursor: pointer; list-style: none; }
.postext > summary::-webkit-details-marker { display: none; }
.postext > summary:hover { color: var(--color-accent-700); }
.postext[open] > summary { font-weight: 600; margin-bottom: .4rem; }
.postext-form { min-width: 22rem; max-width: 34rem; }
.postext-form textarea { font-size: .8rem; }
.postext-lesen { white-space: normal; max-width: 34rem; }

/* ---- Woraus sich der Einheitspreis rechnet
 *
 * Der Auslöser ist **Text und kein Knopf**: Er steht unter dem Positionstext, mitten in
 * einer dichten Tabelle, und ein weiterer grauer Kasten dort wäre ein Fleck. Dass man
 * klicken kann, zeigt die gestrichelte Linie — dieselbe Sprache wie überall, wo etwas
 * aufklappt.
 */
.ansatz-knopf {
  display: inline-grid; place-items: center;
  width: 1.5rem; height: 1.5rem; margin: .15rem 0 0;
  background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
  font-size: 1.02rem; line-height: 1; color: var(--color-neutral-800); cursor: pointer;
}
.ansatz-knopf:hover {
  color: var(--color-accent-700); border-color: var(--color-neutral-300);
  background: var(--color-panel);
}
.ansatz-knopf:focus-visible { outline: 2px solid var(--color-accent-600); outline-offset: 1px; }
/* Offen: Das Zeichen bleibt angedrückt, solange der Rechenweg darunter steht. */
tr.ansatz-offen .ansatz-knopf {
  color: var(--color-accent-700); border-color: var(--color-accent-600);
  background: var(--color-accent-100);
}
tr[data-ansatzzeile] > td { padding: 0; background: var(--color-bg); }
.ansatz-zelle { font-size: .82rem; }
.ansatz { padding: .9rem 1.1rem; display: grid; gap: .7rem; max-width: 62rem; }
.ansatz-kopf { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline; }
.ansatz .liste { background: var(--color-panel); }
.ansatz .rechenweg { width: 100%; }

/* ---- Die drei Entscheidungen als Zeichen am Zeilenanfang
 *
 * Sie liegen etwas zurück und kommen beim Überfahren der Zeile ganz hervor: Vierzig
 * Positionen mit je drei vollen Zeichen wären ein Muster und keine Tabelle. Zurück heißt
 * aber nicht blass — mit .35 Deckkraft war nicht zu erkennen, was dort überhaupt steht.
 */
.zeilenzeichen { display: flex; gap: .15rem; margin-top: .25rem; }
.zeilenzeichen-knopf {
  display: inline-grid; place-items: center;
  width: 1.5rem; height: 1.5rem; padding: 0;
  background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
  font-size: 1.02rem; line-height: 1; color: var(--color-neutral-800);
  cursor: pointer; opacity: .72; transition: opacity .12s ease;
}
tr:hover .zeilenzeichen-knopf, .zeilenzeichen-knopf:focus-visible { opacity: 1; }
.zeilenzeichen-knopf:hover {
  opacity: 1; color: var(--color-accent-700);
  border-color: var(--color-neutral-300); background: var(--color-panel);
}
.zeilenzeichen-knopf.an {
  opacity: 1; color: var(--color-warning-700);
  border-color: var(--color-warning-700); background: var(--color-warning-100);
}
.zeilenzeichen-knopf:focus-visible { outline: 2px solid var(--color-accent-600); outline-offset: 1px; }

/* Eine Nur-Einheitspreis-Position ist angeboten — nicht durchgestrichen und nicht blass.
   Sie bekommt einen Strich am Zeilenanfang; die gelbe Fläche bleibt dem gesetzten Preis
   vorbehalten, sonst leuchtet eine halbe Tabelle. */
tr.nur-ep td:first-child { box-shadow: inset 3px 0 0 var(--color-warning-700); }
.nep-schalter { display: grid; gap: .2rem; margin: .3rem 0; }

/* ---------------------------------------------------------------- Baukalender
 * Ein Raster aus Tagen: Spalte 1 trägt den Namen der Kolonne, danach eine Spalte je Tag.
 * Die Balken liegen im selben Raster — so stehen sie zwangsläufig über dem richtigen Tag,
 * ohne dass irgendwo Pixel ausgerechnet werden.
 */
.kalenderraster {
  display: grid;
  grid-template-columns: 12.5rem repeat(var(--spalten), minmax(1.9rem, 1fr));
  align-items: stretch; min-width: 54rem; background: var(--color-panel);
}
.krs {
  border-right: 1px solid var(--color-divider); border-bottom: 1px solid var(--color-divider);
  padding: .35rem .3rem; font-size: .8rem;
}
.krs-kopf {
  background: var(--color-surface); font-weight: 600; position: sticky; top: 0; z-index: 3;
  border-bottom: 1px solid var(--color-neutral-400);
}
.krs-tag { text-align: center; white-space: nowrap; font-size: .72rem; }
.krs-tag .kw {
  display: block; font-size: .62rem; font-weight: 700; color: var(--color-accent-700);
  letter-spacing: .02em;
}
.krs-name {
  font-weight: 600; position: sticky; left: 0; z-index: 2; background: var(--color-panel);
  border-right: 1px solid var(--color-neutral-400);
}
.krs-feld { min-height: 3rem; }
.krs-leer { padding: 1.4rem; color: var(--color-neutral-700); }
/* Samstag und Sonntag abgesetzt — auf dem Bau wird in Werktagen geplant. */
.krs.wochenende { background: var(--color-surface); }
.krs.heute { box-shadow: inset 2px 0 0 var(--color-accent-600); }
/* Der Monatswechsel bekommt eine Fuge — sonst liest man „31. 1." als Zahlendreher. */
.krs.monatswechsel { border-left: 2px solid var(--color-neutral-400); }
/* Ein Tag, an dem jemand aus der Kolonne fehlt. Schraffur statt Farbe: Der Tag ist nicht
   verloren, die Kolonne ist nur kleiner — und das muss man sehen, ohne dass es schreit. */
.krs-feld.fehlt {
  background-image: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--color-warning) 22%, transparent) 0 4px, transparent 4px 8px);
}
.krs-feld.ziel {
  background: var(--color-accent-100); box-shadow: inset 0 0 0 1px var(--color-accent-600);
}
.einsatz {
  position: relative; margin: .25rem .2rem; padding: .3rem .8rem; border-radius: var(--radius-sm);
  font-size: .78rem; line-height: 1.3; overflow: hidden; align-self: center; z-index: 1;
  background: var(--balken, var(--color-accent-200));
  border: 1px solid color-mix(in srgb, var(--color-text) 14%, transparent);
  color: var(--color-accent-900); white-space: nowrap; text-overflow: ellipsis;
  box-shadow: var(--shadow-sm); transition: box-shadow var(--schnell), transform var(--schnell);
}
.einsatz:hover { box-shadow: var(--shadow-md); }
.einsatz a { color: inherit; font-weight: 600; text-decoration: none; }
.einsatz a:hover { text-decoration: underline; }
.einsatz .klein { opacity: .8; margin-left: .35rem; }
.einsatz .ex-x { float: right; margin-left: .3rem; position: relative; z-index: 2; }
.einsatz.st-bestaetigt { background: var(--balken, var(--color-success-100)); color: var(--color-success-700); }
.einsatz.st-laeuft     { background: var(--balken, var(--color-warning-100)); color: var(--color-warning-700); }
.einsatz.st-erledigt   { background: var(--balken, var(--color-surface)); color: var(--color-neutral-700); }
/* Zu wenig Tage für die Fläche: gestreift, damit es auffällt, ohne zu schreien. */
.einsatz.knapp {
  background-image: repeating-linear-gradient(135deg,
    color-mix(in srgb, var(--color-danger) 16%, transparent) 0 6px, transparent 6px 12px);
}
.knapp-marke { color: var(--color-danger-700); font-weight: 700; }
.konflikt { padding: .4rem 0; border-bottom: 1px solid var(--color-divider); }
.konflikt:last-child { border-bottom: 0; }
/* Ziehen: der Balken wird durchscheinend, das Zielfeld hebt sich ab. Während des Ziehens
   sind **alle** Balken durchlässig — sie liegen über den Tagesfeldern, und `dragover` trifft
   sonst sie statt des Feldes. */
.einsatz[draggable="true"] { cursor: grab; }
.kalenderraster.zieht .einsatz { pointer-events: none; }
.einsatz.zieht { opacity: .4; cursor: grabbing; }
.einsatz .griff {
  position: absolute; top: 0; bottom: 0; width: .6rem; cursor: ew-resize; opacity: 0;
  background: color-mix(in srgb, var(--color-text) 25%, transparent); z-index: 1;
  transition: opacity var(--schnell);
}
.einsatz:hover .griff { opacity: .5; }
.einsatz .griff-links  { left: 0;  border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.einsatz .griff-rechts { right: 0; border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
/* Gemeldete Stunden am Balken: die Wirklichkeit neben dem Plan. Rechts angeschlagen, sonst
   schiebt der Text sie bei schmalen Balken aus dem sichtbaren Bereich. */
.stunden-marke, .knapp-marke { float: right; margin-left: .35rem; position: relative; z-index: 2; }
.stunden-marke {
  padding: 0 .3rem; border-radius: 3px;
  background: color-mix(in srgb, var(--color-text) 8%, transparent);
  font-size: .7rem; font-weight: 600;
}

/* ------------------------------------------------------- Geschäftsbedingungen
 * Dieselbe Form wie im gedruckten Vertrag: Die Absatznummer hängt in einem festen Kasten
 * links, der Text läuft daneben. Wer „Ziffer 5 Absatz 3" zitiert, muss sie finden können,
 * ohne zu zählen.
 */
.agb-text { max-width: 52rem; }
.agb-text .agb-ziffer { font-family: var(--font-heading); font-size: 1.05rem; margin: 1.2rem 0 .4rem; }
.agb-text .agb-ziffer:first-child { margin-top: 0; }
.agb-text .agb-absatz {
  position: relative; padding-left: 2.4rem; margin: 0 0 .45rem; text-align: justify;
}
.agb-text .agb-absatz .zif {
  position: absolute; left: 0; width: 2.1rem; color: var(--color-neutral-700);
}

/* ------------------------------------------------------ Befunde vor dem Versand
 * Die farbige Kante links trägt die Dringlichkeit, nicht der Text: Rot sperrt den Versand,
 * Gelb geht hinaus und kostet später Geld, Grau ist ein Hinweis. Wer von oben nach unten
 * liest, arbeitet in der richtigen Reihenfolge.
 */
.befundliste { list-style: none; margin: 0; padding: 0; }
.befund {
  padding: .7rem 1rem .7rem .85rem; border-top: 1px solid var(--color-divider);
  border-left: 3px solid var(--color-neutral-600);
}
.befund:first-child { border-top: none; }
.befund.b-hindert { border-left-color: var(--color-danger);  background: var(--color-danger-100); }
.befund.b-wichtig { border-left-color: var(--color-warning); background: var(--color-warning-100); }
.befund-was   { font-weight: 600; }
.befund-warum { margin-top: .15rem; }
.befund-wo    { margin-top: .25rem; font-size: .82rem; color: var(--color-neutral-700); }
.befund.b-hindert .befund-warum, .befund.b-wichtig .befund-warum { color: inherit; }
/* Offene Punkte einer Baustellenabfrage: „4 Punkte offen" sagt niemandem, ob der Lkw fahren
   kann; „Meterriss fehlt" schon. */
.offene-punkte { margin: .3rem 0 0; padding-left: 1.1rem; }
.offene-punkte li { margin-bottom: .15rem; }

/* ----------------------------------------------------------------- Datenstand
 * Bis wann die Zahlen reichen. Das Band steht über der Auswertung und nur dann, wenn etwas
 * nicht stimmt — ein Hinweis, der immer da ist, wird nicht mehr gelesen.
 */
.datenstand {
  margin-bottom: 1rem; padding: .7rem .9rem; border-radius: var(--radius-sm);
  border-left: 3px solid var(--color-warning); background: var(--color-warning-100);
  color: var(--color-warning-700);
}
.datenstand.ds-ernst {
  border-left-color: var(--color-danger); background: var(--color-danger-100);
  color: var(--color-danger-700);
}
.datenstand .ds-titel { font-weight: 700; }
.datenstand .ds-text  { margin-top: .15rem; }
.datenstand .ds-weg   { margin-top: .3rem; font-size: .82rem; }
.datenstand .ds-weg a { color: inherit; }

/* --------------------------------------------------- Schnittstellenbeschreibung */
.doku h2 { margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--color-divider); }
.doku h3 { margin-top: 1.6rem; font-size: .95rem; font-family: var(--font-mono); }
.doku pre {
  background: var(--color-surface); border: 1px solid var(--color-divider);
  border-radius: var(--radius-sm); padding: .8rem 1rem; overflow-x: auto;
  font-size: .82rem; line-height: 1.5;
}
.doku code { font-size: .85em; }
/* Der Weg steht in der ersten Spalte und darf nicht umbrechen: `/api/v1/rechnungen/{id}` in
   drei Zeilen ist kein Weg mehr, sondern ein Rätsel. */
.doku table.liste td:first-child { white-space: nowrap; font-family: var(--font-mono); }
.verb {
  display: inline-block; min-width: 3.4rem; padding: .05rem .4rem; border-radius: 4px;
  font-size: .72rem; font-weight: 700; text-align: center; color: var(--auf-ton);
  letter-spacing: .02em;
}
.verb.get    { background: var(--color-accent-700); }
.verb.post   { background: var(--color-success-700); }
.verb.put    { background: var(--color-warning-700); }
.verb.delete { background: var(--color-danger-700); }

/* ------------------------------------------------------- Anmeldung und Fehlerseite
 * Dieselbe Handschrift wie drinnen: Der Kasten ist eine Tafelkarte, der Grund trägt einen
 * leisen Schein in der Hausfarbe. Das Partnerportal bleibt davon unberührt — es lädt
 * weiterhin `marke.css` und zeigt die Marke des Auftraggebers.
 */
.anmeldung {
  display: flex; align-items: center; justify-content: center; min-height: 100vh;
  padding: 1.5rem;
  background:
    radial-gradient(1100px 560px at 50% -10%,
      color-mix(in srgb, var(--color-accent) 14%, transparent), transparent),
    var(--color-bg);
}
.anmeldung .kasten {
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: 2rem; width: 100%; max-width: 25rem;
}
.anmeldung .logo { max-height: 2.2rem; margin-bottom: 1rem; display: block; }
.anmeldung h1 { margin: 0 0 .2rem; font-size: 1.45rem; letter-spacing: -.02em; }
.anmeldung .unterzeile, .anmeldung .unter {
  color: var(--color-neutral-700); font-size: .86rem; margin: .2rem 0 1.3rem;
}
.anmeldung .feld { margin-bottom: .9rem; }
/* Ein Anmeldeknopf, der nur so breit ist wie sein Wort, sieht auf einem Telefon aus wie ein
   Versehen. */
.anmeldung .knopf.haupt {
  width: 100%; justify-content: center; padding: .6rem; font-size: 1rem;
}
.fehlerseite { max-width: 40rem; margin: 4rem auto; text-align: center; }
.fehlerseite .status {
  font-size: 3.6rem; font-weight: 700; letter-spacing: -.04em;
  color: var(--color-neutral-400); line-height: 1;
}
.fehlerseite h1 { margin: .4rem 0 .6rem; font-size: 1.35rem; }
.fehlerseite p { color: var(--color-neutral-700); }
/* Die Einzelheiten unter einer Fehlerseite liest man von links nach rechts wie jeden Text —
   mittig gesetzte Aufzählungen liest niemand. */
.fehlerseite .fehlerdetails { text-align: left; margin-top: 1.2rem; }
.fehlerseite .fehlerdetails ul { margin: 0; padding-left: 1.1rem; }
/* Eine Knopfreihe, die in der Mitte steht — auf einer Seite, die selbst mittig steht. */
.knopfreihe.mittig { justify-content: center; }

/* ------------------------------------------------------ Das eigene Auswahlfeld
 * Vorher stand hier Select2 mit zwanzig `!important` — die Antwort auf die Inline-Stile,
 * die das Paket selbst setzte. Jetzt gehört das Feld uns, und keine einzige Regel muss
 * eine andere überstimmen.
 *
 * Der Knopf **ist** das Feld: Er nimmt die Grundregel für Eingaben mit (sie nennt
 * `.auswahl-knopf` oben mit) und liegt über dem echten `<select>`, das durchsichtig
 * darunter stehen bleibt, damit der Browser seine Pflichtprüfung anzeigen kann.
 */
.auswahl { position: relative; width: 100%; min-width: 0; }
.auswahl-echt {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; pointer-events: none; margin: 0;
}
.auswahl-knopf {
  display: flex; align-items: center; gap: .4rem; text-align: left; cursor: pointer;
}
.auswahl-knopf .auswahl-wert {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: .25rem;
  flex-wrap: wrap; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Solange nichts gewählt ist, steht dort ein Platzhalter — und der ist kein Wert. */
/* `leer` wäre der Leerzustand des Hauses — eine Fläche mit 2,2 rem Polster und Text in
   der Mitte. Der Platzhalter braucht einen eigenen Namen. */
.auswahl-knopf .auswahl-wert.auswahl-leer { color: var(--color-neutral-600); }
.auswahl-pfeil {
  flex: 0 0 auto; width: .6rem; height: .6rem; margin-right: .1rem;
  border-right: 1.5px solid var(--color-neutral-700);
  border-bottom: 1.5px solid var(--color-neutral-700);
  transform: translateY(-2px) rotate(45deg); transition: transform var(--schnell);
}
.auswahl.offen .auswahl-pfeil { transform: translateY(2px) rotate(225deg); }
.auswahl.offen .auswahl-knopf {
  border-color: var(--color-accent-600);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-accent) 22%, transparent);
}
/* Das Kreuz sitzt über dem Pfeil, nicht neben ihm: Zwei Zeichen am rechten Rand lassen
   das Feld aussehen wie eine Werkzeugleiste. */
.auswahl-ab {
  position: absolute; right: 1.5rem; top: 50%; transform: translateY(-50%);
  border: 0; background: none; cursor: pointer; padding: 0 .25rem; line-height: 1;
  font-size: .9rem; color: var(--color-neutral-600);
}
.auswahl-ab:hover { color: var(--color-danger); }
.auswahl-knopf.klein ~ .auswahl-ab { font-size: .8rem; }

/* Mehrfachauswahl: jeder Wert ein Span, jeder Span mit seinem eigenen Kreuz. */
.auswahl-span {
  display: inline-flex; align-items: center; gap: .3rem;
  background: var(--color-accent-100); color: var(--color-accent-800);
  border-radius: 999px; padding: .05rem .45rem; font-size: .82rem; max-width: 100%;
}
.auswahl-span-ab { cursor: pointer; opacity: .6; font-size: .72rem; }
.auswahl-span-ab:hover { opacity: 1; color: var(--color-danger); }

/* Der aufgeklappte Kasten hängt am `body` und wird mit festen Maßen gestellt: In einer
   Karte mit `overflow: auto` — und das ist jedes Fenster — wäre er sonst abgeschnitten.
   Darum auch `fixed` und nicht `absolute`. */
.auswahl-liste {
  position: fixed; z-index: 920; display: flex; flex-direction: column;
  max-height: min(22rem, 60vh); overflow: hidden;
  background: var(--color-panel); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); box-shadow: var(--shadow-lg);
  animation: ein var(--schnell);
}
.auswahl-suche { padding: .45rem; border-bottom: 1px solid var(--color-divider); }
.auswahl-suchfeld { width: 100%; }
.auswahl-treffer { overflow: auto; padding: .25rem; }
.auswahl-gruppe { padding: .45rem .55rem .2rem; }
.auswahl-eintrag {
  display: flex; align-items: flex-start; gap: .5rem;
  padding: .4rem .55rem; border-radius: var(--radius-sm); cursor: pointer;
  font-size: .88rem; line-height: 1.35;
}
/* Gewählt wird mit der Tastatur **und** mit der Maus — beide zeigen dasselbe an, sonst
   steht der Zeiger woanders als der Blick. */
.auswahl-eintrag.aktiv { background: var(--color-accent-100); }
.auswahl-eintrag.gewaehlt { font-weight: 600; }
.auswahl-eintrag.aus { opacity: .45; cursor: not-allowed; }
.auswahl-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.auswahl-titel { color: var(--color-text); }
.auswahl-titel mark {
  background: color-mix(in srgb, var(--color-accent) 28%, transparent);
  color: inherit; border-radius: 2px; padding: 0 1px;
}
/* Die zweite Zeile — Nummer, Ort, Preis. Sie macht aus einer Namensliste eine Auswahl, in
   der man den richtigen von zwei gleichnamigen Partnern erkennt. */
.auswahl-zusatz { font-size: .78rem; color: var(--color-neutral-700); }
.auswahl-zusatz mark {
  background: color-mix(in srgb, var(--color-accent) 22%, transparent);
  color: inherit; border-radius: 2px;
}
.auswahl-haken { flex: 0 0 auto; color: var(--color-accent-700); visibility: hidden; }
.auswahl-eintrag.gewaehlt .auswahl-haken { visibility: visible; }
.auswahl-nichts {
  padding: .9rem .6rem; text-align: center; font-size: .85rem;
  color: var(--color-neutral-700);
}

/* In einer Flexzeile nimmt das Feld seine eigene Breite und nicht die ganze Zeile —
   sonst rutschen Beschriftung und Knopf darunter. */
.formzeile > .auswahl { flex: 0 1 300px; min-width: 180px; width: auto; }
.sammel-form .auswahl { width: auto; min-width: 11rem; max-width: 18rem; }
table.liste td details:has(> summary.knopf)[open] > form .auswahl { max-width: 100%; }

/* ======================================================== 8. Dunkle Fassung
 *
 * **Abgeleitet, nicht erfunden.** Die Tonleitern sind auf einer gemeinsamen
 * Helligkeitsleiter erzeugt — also werden sie umgedreht: Was hell 100 war, ist dunkel 900.
 * Flächen kommen aus den tiefen Neutralstufen, der Schatten weicht einer Haarlinie, weil
 * ein Schatten auf dunklem Grund nicht zu sehen ist, sondern nur matscht.
 *
 * Fünfzig Einzelregeln standen hier vorher — für Tabellenköpfe, Knöpfe, Fenster,
 * Statusmarken, Meldungen, Eingabefelder. Sie sind weg: Jedes Bauteil greift auf Marken zu,
 * also genügt es, die Marken neu zu besetzen.
 *
 * Umgeschaltet wird von Hand und nicht nach der Tageszeit: Wer bei Tageslicht am Fenster
 * sitzt, will nicht um 18 Uhr eine andere Anwendung vor sich haben.
 */
body.dunkel {
  /* Umgekehrt dasselbe: Jetzt soll der Browser seine dunklen Bedienelemente nehmen. */
  color-scheme: dark;
  --color-bg:      #1a1918;
  --color-surface: #2c2b29;
  --color-panel:   #22211f;
  --color-text:    #ecebea;
  --color-accent:  #38a6cf;
  --color-divider: color-mix(in srgb, #ecebea 14%, transparent);
  --color-scrim:   rgba(0,0,0,.6);

  /* Die Neutralleiter umgedreht: 100 ist jetzt die dunkelste Stufe. */
  --color-neutral-100: #211f1f;
  --color-neutral-200: #2d2b2b;
  --color-neutral-300: #444141;
  --color-neutral-400: #4f4c4c;
  --color-neutral-500: #7d7979;
  --color-neutral-600: #9b9797;
  --color-neutral-700: #bab6b6;
  --color-neutral-800: #d7d3d3;
  --color-neutral-900: #f8f4f4;

  /* Die Akzentleiter ebenso — 700 bleibt die Stufe für Schrift und Kanten, trägt dunkel
     aber den helleren Wert. */
  --color-accent-100: #0a303e;
  --color-accent-200: #004961;
  --color-accent-300: #006786;
  --color-accent-400: #1186ac;
  --color-accent-500: #38a6cf;
  --color-accent-600: #62c5ee;
  --color-accent-700: #99e0ff;
  --color-accent-800: #cbeeff;
  --color-accent-900: #e9f8ff;

  --color-accent-2-100: #4b1528;
  --color-accent-2-200: #790e3d;
  --color-accent-2-300: #aa0b56;
  --color-accent-2-400: #d82071;
  --color-accent-2-500: #ff458e;
  --color-accent-2-600: #ff90b1;
  --color-accent-2-700: #ffc0d0;
  --color-accent-2-800: #ffdee6;
  --color-accent-2-900: #fff1f4;

  --color-success: #4cc27f;  --color-success-100: #163222;  --color-success-700: #8fdcae;
  --color-warning: #f0b429;  --color-warning-100: #382a0c;  --color-warning-700: #f4cd73;
  --color-danger:  #ef6363;  --color-danger-100:  #3b1919;  --color-danger-700:  #f5a3a3;

  /* Ein Eingabefeld ist dunkel **tiefer** als die Karte ringsum — läge es auf derselben
     Höhe, verschwände es darin. Hell ist es umgekehrt die hellste Fläche. */
  --eingabe-grund: #161514;
  --auf-akzent: #0a303e;
  --auf-ton:    #1a1918;

  /* Haarlinie statt Schatten. */
  --shadow-sm: 0 0 0 1px color-mix(in srgb, #ecebea 8%, transparent);
  --shadow-md: 0 0 0 1px color-mix(in srgb, #ecebea 10%, transparent),
               0 6px 18px rgba(0,0,0,.5);
  --shadow-lg: 0 0 0 1px color-mix(in srgb, #ecebea 12%, transparent),
               0 18px 44px rgba(0,0,0,.65);

  background: var(--color-bg); color: var(--color-text);
}
/* Die Seitenleiste ist auch dunkel eine Spur tiefer als die Fläche — damit die Gliederung
   erhalten bleibt und der Bildschirm nicht zu einer Fläche verläuft. Der Entwurf setzt für
   sie dunkel eigene Werte; sie überschreiben den Block oben. */
body.dunkel .seitenleiste {
  --color-surface: #111010;
  --color-bg:      #2a2928;
  --color-panel:   #1c1b1a;
  --color-text:    #f3f2f2;
}
/* Der Kalenderbalken trägt hell einen eigenen Hintergrund aus der Kolonnenfarbe; dunkel
   wird daraus eine tiefe Fläche mit heller Schrift. Die Tonmarken erledigen den Rest. */
body.dunkel .einsatz { color: var(--color-accent-800); }
/* Unterschrieben wird auf Weiß, auch dunkel: Der Namenszug landet unverändert auf einem
   weißen Blatt, und eine dunkle Fläche hier zeigte eine Unterschrift, die im PDF anders
   aussieht als beim Unterschreiben. */
body.dunkel .zeichenflaeche { background: #fff; border-color: var(--color-neutral-400); }
body.dunkel input[type=date]::-webkit-calendar-picker-indicator,
body.dunkel input[type=month]::-webkit-calendar-picker-indicator { filter: invert(.85); }

/* ============================================ 9. Kleine Schirme, Druck, Bewegung */

@media (max-width: 1200px) {
  main { padding: var(--space-4) var(--space-6); }
}

/* Bisher klappte die Seitenleiste unter 900 px einfach über den Inhalt — sechzig Menüpunkte
   vor jeder Seite. Jetzt wird sie zu einer Schublade, die nur auf Verlangen aufgeht. */
@media (max-width: 900px) {
  .rahmen { grid-template-columns: 1fr; }
  .seitenleiste {
    position: fixed; inset: 0 auto 0 0; width: min(19rem, 86vw); z-index: 80;
    height: 100vh; transform: translateX(-100%);
    transition: transform var(--ruhig); box-shadow: var(--shadow-lg);
  }
  .rahmen.leiste-offen .seitenleiste { transform: none; }
  .rahmen.leiste-offen::after {
    content: ""; position: fixed; inset: 0; background: var(--color-scrim); z-index: 70;
  }
  .leiste-griff { display: inline-flex !important; }
  .kopfleiste { gap: .5rem; padding: .6rem .8rem; flex-wrap: wrap; }
  .kopfleiste .titel { order: 2; flex: 1 1 100%; font-size: 1rem; }
  .kopflogo { order: 1; }
  .mandantwahl { order: 1; margin-left: auto; }
  .mandant-text small, .kopfleiste .benutzer { display: none; }
  main { padding: var(--space-3); }
  .reiterflaeche { height: calc(100vh - 13rem); }
  .filterleiste { padding: .7rem .8rem; }
  table.liste th, table.liste td { padding: .5rem .55rem; }
  .explorer { grid-template-columns: 1fr; }
}

/* Druck: Leiste, Reiter und Knöpfe fallen weg, die Karten werden flach.
   Die **erzeugten Blätter** — Rechnungen, Verträge, Protokolle — kommen hier nicht vorbei:
   Sie gehen durch `TemplateService::huelle()` und WeasyPrint und haben ihr eigenes CSS. */
@media print {
  .seitenleiste, .kopfleiste, .knopfreihe, .reiter, .filterleiste, .reiterleiste,
  .reiterflaeche, .hinweise, .mandantwahl, .menuesuche, .leiste-fuss, .hell-dunkel,
  .sprungmarke { display: none !important; }
  .rahmen { display: block; }
  body { background: #fff; }
  .karte { box-shadow: none; border-color: #ccc; }
  main > * + * { margin-top: .6rem; }
  main { padding: 0; }
}

/* Wer Bewegung nicht mag oder nicht verträgt, bekommt keine. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ------------------------------------------------------------------ Postfach (49.161)
 * Drei Spalten wie in jedem Mailprogramm: Fächer, Liste, Lesefläche. Unter 1100 Pixeln
 * fällt es auf eine Spalte zusammen — nebeneinander wären alle drei zu schmal zum Lesen.
 */
/*
 * Drei Spalten, aber nicht starr: Auf einem 15-Zoll-Bildschirm (1366 Pixel, abzüglich
 * Menü) blieben für die Lesefläche sonst 400 Pixel — „schau dir den auf einem 15 Zoll an".
 * Die Fächer werden schmaler, die Liste gibt nach, die Lesefläche bekommt den Rest.
 */
.postfach { display: grid; grid-template-columns: minmax(10rem, 13rem) minmax(20rem, 24rem) 1fr;
            gap: var(--space-3); align-items: start; }
/* Der Kasten um die Lesefläche reicht das Raster durch — getauscht wird er trotzdem
   als Ganzes (Kapitel 49.174). */
.pf-durchreichen { display: contents; }
/* Während nachgeladen wird, bleibt das Alte stehen und tritt einen Schritt zurück.
   Ein Platzhalter wäre ein Flackern für zweihundert Millisekunden. */
.pf-durchreichen.laedt { opacity: .55; }
@media (max-width: 1500px) {
  .postfach { grid-template-columns: minmax(9rem, 11rem) minmax(18rem, 21rem) 1fr;
              gap: var(--space-2); }
  .pf-kopfzeilen th { width: 5.5rem; }
}
/* Ohne geöffnete Nachricht fällt die dritte Spalte weg, und die Liste bekommt den Platz. */
.postfach.ohne-lesen { grid-template-columns: 13rem 1fr; }
@media (max-width: 1100px) {
  .postfach, .postfach.ohne-lesen { grid-template-columns: 1fr; }
}

.pf-faecher { position: sticky; top: var(--space-3); }
.pf-ueberschrift { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em;
                   color: var(--color-neutral-600); margin: var(--space-3) 0 .3rem .6rem; }
.pf-liste { display: flex; flex-direction: column; gap: 1px; }
.pf-eintrag { display: flex; justify-content: space-between; align-items: center; gap: .5rem;
              padding: .32rem .6rem; border-radius: var(--radius-sm);
              color: var(--color-text); text-decoration: none; font-size: .88rem; }
.pf-eintrag:hover { background: var(--color-accent-100); }
.pf-eintrag.aktiv { background: var(--color-accent-700); color: #fff; font-weight: 600; }
.pf-zahl { font-variant-numeric: tabular-nums; font-size: .74rem; padding: 0 .35rem;
           border-radius: 999px; background: var(--color-surface);
           color: var(--color-neutral-800); }
.pf-eintrag.aktiv .pf-zahl { background: color-mix(in srgb, #fff 26%, transparent); color: #fff; }

.pf-liste-spalte { background: var(--color-surface); border: 1px solid var(--rahmen);
                   border-radius: var(--radius-md); overflow: hidden; max-height: 78vh;
                   overflow-y: auto; }
.pf-suche { padding: .5rem; border-bottom: 1px solid var(--rahmen);
            position: sticky; top: 0; background: var(--color-surface); z-index: 1; }
.pf-suche input { width: 100%; }
.pf-sortierung { display: flex; gap: .6rem; padding: .35rem .6rem; font-size: .76rem;
                 border-bottom: 1px solid var(--rahmen); color: var(--color-neutral-700); }
.pf-sortierung a { color: inherit; text-decoration: none; }
.pf-sortierung a.aktiv { font-weight: 700; color: var(--color-accent-800); }

/* Eine Zeile ist drei Zeilen hoch und keine mehr (Kapitel 49.174): wer und wann, der
   Betreff, der Anfang des Textes. Vorher lief der Betreff über vier Zeilen, und auf den
   Bildschirm passten vier Nachrichten. */
.pf-zeile { display: block; padding: .45rem .6rem; border-bottom: 1px solid var(--color-divider);
            color: var(--color-text); text-decoration: none; }
.pf-zeile:hover { background: var(--color-accent-100); }
.pf-zeile.aktiv { background: var(--color-accent-100);
                  box-shadow: inset 3px 0 0 var(--color-accent-700); }
.pf-zeile.neu .pf-betreff, .pf-zeile.neu .pf-wer { font-weight: 700; }
/* Ungelesenes trägt einen Punkt am Rand — fett allein übersieht man in einer langen Liste. */
.pf-zeile.neu .pf-wer::before { content: "•"; color: var(--color-accent-700);
                                margin-right: .25rem; }
.pf-kopf { display: flex; justify-content: space-between; gap: .5rem; font-size: .8rem;
           align-items: baseline; }
.pf-wer { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-zeit { color: var(--color-neutral-600); white-space: nowrap; font-size: .74rem;
           font-variant-numeric: tabular-nums; }
.pf-betreff { margin: .05rem 0; font-size: .88rem; line-height: 1.3;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-vorschau { font-size: .76rem; overflow: hidden; text-overflow: ellipsis;
               white-space: nowrap; }
.pf-marken { margin-top: .25rem; display: flex; gap: .3rem; flex-wrap: wrap;
             align-items: center; }
.pf-marken .marke-status { font-size: .68rem; padding: 0 .3rem; }

/* Der Briefkopf der geöffneten Nachricht (Kapitel 49.174) — kein Tabellenblock mehr. */
.pf-brief-kopf { display: flex; gap: .7rem; align-items: flex-start; }
.pf-avatar { flex: 0 0 auto; width: 2.1rem; height: 2.1rem; border-radius: 999px;
             display: grid; place-items: center; font-weight: 700; font-size: .95rem;
             background: var(--color-accent-100); color: var(--color-accent-800); }
.pf-avatar.hinaus { background: var(--color-neutral-200); color: var(--color-neutral-700); }
.pf-brief-wer { min-width: 0; flex: 1 1 auto; }
.pf-brief-name { font-weight: 600; overflow-wrap: anywhere; }
.pf-brief-zeit { white-space: nowrap; color: var(--color-neutral-600); font-size: .82rem;
                 font-variant-numeric: tabular-nums; }
.pf-brief-marken { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center;
                   margin-top: .5rem; }
.pf-mehr > summary { cursor: pointer; font-size: .76rem; color: var(--color-neutral-700); }
.pf-mehr[open] { width: 100%; }
.pf-zuordnen > summary { cursor: pointer; font-size: .82rem;
                         color: var(--color-neutral-700); }
/* Die Lesefläche: eigene Spalte, eigener Scroll — die Liste daneben soll stehen bleiben. */
.pf-lesen { max-height: 78vh; overflow-y: auto; }
.pf-leer { padding: var(--space-4); }

/* Die HTML-Fassung läuft in einem abgeriegelten Rahmen — Höhe nach Augenmaß, nicht nach
   Inhalt: Ein `sandbox`-Rahmen verrät seine Höhe nicht, und raten wäre ein Sprung. */
.pf-html { margin-top: var(--space-3); padding-top: var(--space-3);
           border-top: 1px solid var(--rahmen); }
.pf-rahmen { width: 100%; height: 46vh; min-height: 18rem; border: 0; background: #fff;
             border-radius: var(--radius-sm); }
table.anhangliste td { padding: .25rem .4rem; }
table.anhangliste form { display: inline; }
.pf-kopfzeilen th { width: 7rem; }
.pf-text { margin-top: var(--space-3); padding-top: var(--space-3);
           border-top: 1px solid var(--rahmen); white-space: pre-wrap;
           line-height: 1.55; }

/* „Vom Laufwerk" (49.162) */
.laufwerkwahl { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
                margin: .3rem 0 .6rem; }
.lw-gewaehlt { display: flex; gap: .3rem; flex-wrap: wrap; }
.lw-chip { display: inline-flex; align-items: center; gap: .2rem; }
.lw-weg { border: 0; background: none; color: inherit; cursor: pointer; font-size: 1rem;
          line-height: 1; padding: 0 .1rem; }
.lw-liste { max-height: 50vh; overflow-y: auto; margin-top: .5rem; }
.lw-zeile { display: block; padding: .3rem .4rem; border-bottom: 1px solid var(--color-divider);
            color: var(--color-text); text-decoration: none; }
.lw-zeile:hover { background: var(--color-accent-100); }
.lw-ordner { font-weight: 600; }

/* Der einfache Satz im Nachrichtenfenster (49.163) */
.mail-satz { border: 1px solid var(--rahmen); border-radius: var(--radius-sm);
             background: var(--color-surface); }
.mail-werkzeuge { display: flex; gap: .3rem; align-items: center; padding: .3rem;
                  border-bottom: 1px solid var(--color-divider); flex-wrap: wrap; }
.mail-flaeche { min-height: 14rem; max-height: 46vh; overflow-y: auto; padding: .6rem .7rem;
                line-height: 1.55; outline: none; }
.mail-flaeche:focus { box-shadow: inset 0 0 0 2px var(--color-accent-600); }
.mail-satz.nurtext .mail-werkzeuge [data-satz] { opacity: .4; pointer-events: none; }

/* Kennfarbe je Postfach (49.163): ein Punkt im Menü, ein Streifen an der Zeile. */
.pf-punkt { display: inline-block; width: .55rem; height: .55rem; border-radius: 999px;
            margin-right: .35rem; vertical-align: baseline; }
.pf-zeile[style*="--fachfarbe"] { box-shadow: inset 3px 0 0 var(--fachfarbe); }
.pf-zeile.aktiv[style*="--fachfarbe"] {
  box-shadow: inset 3px 0 0 var(--fachfarbe), inset 0 0 0 1px var(--color-accent-700);
}
.pf-unter { padding-left: 1.5rem; font-size: .82rem; }

/* „Speichern als": erst wohin, dann das passende Feld (49.164) */
.zielkarten { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
              gap: .5rem; margin: .3rem 0 .8rem; }
.zielkarte { display: block; border: 1px solid var(--rahmen); border-radius: var(--radius-sm);
             padding: .55rem .7rem; cursor: pointer; background: var(--color-surface); }
.zielkarte:hover { border-color: var(--color-accent-600); }
.zielkarte:has(input:checked) { border-color: var(--color-accent-700);
             box-shadow: inset 0 0 0 1px var(--color-accent-700);
             background: var(--color-accent-100); }
.zielkarte input { margin-right: .4rem; }
.zielkarte-wort { font-weight: 600; }
.zielkarte-satz { display: block; font-size: .78rem; color: var(--color-neutral-700);
                  margin-top: .2rem; }

/* Bilder erst auf Nachfrage (49.165) */
.pf-bilderleiste { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap;
                   padding: .45rem .6rem; margin-bottom: .5rem;
                   background: var(--color-warning-100, #fdf6e3);
                   border: 1px solid var(--rahmen); border-radius: var(--radius-sm); }


/* =========================================================== Ladebalken
 *
 * > „und ggf. einen Ladebalken anzeigen, wenn er was lädt" (29.10.2026)
 *
 * Ein Strich am oberen Rand, zwei Pixel hoch: Er sagt „es läuft", ohne die Seite zu
 * verdecken oder den Blick zu fangen. Nach dem letzten Aufruf blendet er aus — nicht
 * sofort, sonst zuckt er bei schnellen Antworten nur.
 */
.ladebalken {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 200;
  background: transparent; pointer-events: none; opacity: 0;
  transition: opacity var(--schnell);
}
.ladebalken.laeuft { opacity: 1; }
.ladebalken > span {
  display: block; height: 100%; width: 30%;
  background: var(--color-accent-600);
  animation: ladebalken-lauf 1.1s ease-in-out infinite;
}
@keyframes ladebalken-lauf {
  0%   { margin-left: -30%; }
  100% { margin-left: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .ladebalken > span { animation: none; width: 100%; opacity: .5; }
}
