/*
 * ─────────────────────────────────────────────────────────────────────────
 *  Das Aussehen des DEH-Partnerportals — eine Datei für alle Ansichten
 * ─────────────────────────────────────────────────────────────────────────
 *
 * Bis hierher brachte jede der zwölf Ansichten ihren eigenen <style>-Block
 * mit: weitgehend dieselben Regeln, leicht auseinandergelaufen. Genau das war
 * der Grund, warum das Portal beliebig aussah — es gab kein gemeinsames
 * Aussehen, nur zwölf Annäherungen daran. Wer eine Farbe ändern wollte,
 * musste sie zwölfmal ändern und übersah dabei zuverlässig eine.
 *
 * Verbindliche Grundlage ist docs/gestaltung-deh.md: die Farben, die
 * Schriften und die Anmutung sind dort aus Logo und Website abgeleitet und
 * begründet. Was hier steht, setzt das um; was hier davon abweicht, sagt in
 * einem Kommentar warum.
 *
 * Drei Regeln aus jener Ableitung tragen fast jede Entscheidung unten:
 *
 *  1. **Das Rot ist sparsam.** Im Logo kommt es genau einmal vor, als
 *     schmaler senkrechter Balken. Im Portal kommt es deshalb je Seite genau
 *     einmal vor: als schmaler senkrechter Balken vor der Seitenüberschrift.
 *     Nicht in Knöpfen, nicht in Überschriften, nicht in Meldungstexten.
 *  2. **Kein Rundungsradius über 4 Pixel, keine Schatten.** Das Logo hat
 *     keine einzige runde Ecke und keinen Verlauf. Getrennt wird über Linien.
 *  3. **Großbuchstaben mit weiter Sperrung** bleiben der Wortmarke
 *     vorbehalten. Beschriftungen und Tabellenköpfe standen bisher in
 *     Versalien; das liest sich anstrengend und macht aus einer Beschriftung
 *     ein Schild.
 */

/* ══════════════════════════════════════════════════════════════════════════
   Schriften — mitgeliefert, nicht von Google geladen
   ══════════════════════════════════════════════════════════════════════════

   Ein <link> auf fonts.googleapis.com überträgt bei jedem Seitenaufruf die
   IP-Adresse des Nutzers an Google. In einem Portal, in dem Vertriebspartner
   Ausweiskopien fremder Menschen hochladen, ist das das falsche Signal — und
   in Deutschland abgemahnt worden (LG München I, 3 O 17493/20).

   Beide Familien stehen unter der SIL Open Font License 1.1 und dürfen
   mitgeliefert werden. Die Lizenztexte liegen daneben:
   app/schriften/OFL-Baskervville.txt und app/schriften/OFL-OpenSans.txt.
   Herkunft und Fassung stehen in app/schriften/HERKUNFT.md.

   Je Familie zwei Dateien, geschnitten nach Zeichenbereich: „latin" trägt
   alles, was deutsche Texte brauchen (ä ö ü ß, Anführungszeichen, €),
   „latin-ext" die Zeichen der übrigen europäischen Sprachen. Der Browser
   lädt den zweiten Schnitt nur, wenn ein Zeichen daraus wirklich vorkommt —
   etwa in einem tschechischen Firmennamen. Open Sans ist eine variable
   Schrift: eine Datei deckt 300 bis 700 ab, statt drei Dateien für drei
   Stärken. */

@font-face {
    font-family: 'Baskervville';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/schriften/baskervville-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: 'Baskervville';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/schriften/baskervville-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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Open Sans';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('/schriften/open-sans-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: 'Open Sans';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('/schriften/open-sans-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-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ══════════════════════════════════════════════════════════════════════════
   Werte
   ══════════════════════════════════════════════════════════════════════════ */

:root {
    /* ── Marke ──
       Der Balken im Logo, zugleich der häufigste Buntwert der Website. Er
       steht im Portal an genau einer Stelle je Seite (siehe main > h2). */
    --marke: #9b111e;
    /* Die Hausfarbe stark aufgehellt: die Fläche des Aufgabenkastens auf der
       Startseite.

       Warum nicht --fehler-flaeche, die fast gleich aussieht: „Zu tun" ist
       keine Fehlermeldung, sondern der Arbeitsvorrat des Hauses. Das ganze
       Stilblatt hält Warnung und Marke auseinander — bis hin zu einem Test,
       der ihren Farbabstand misst (tests/test_gestaltung.php). Den einen
       Kasten dann doch in die Fehlerfläche zu setzen, hiesse die Regel an
       ihrer sichtbarsten Stelle zu brechen.

       Kontrast gemessen, nicht geschätzt: schwarzer Text darauf 18,38:1, die
       Hausfarbe #9b111e darauf 7,37:1, Gemstone Blue 15,22:1. Auch der
       Hilfstext #6b6b6b bliebe mit 4,66:1 über der Grenze — er kommt in
       diesem Kasten allerdings nicht vor. */
    --marke-flaeche: #f9edee;

    /* ── Text ──
       Schwarz wie im Logo. Der gedämpfte Wert trägt Fließtext in Meldungen,
       der Hilfstext alles Beiläufige.

       Abweichung von docs/gestaltung-deh.md, mit Absicht: Dort steht #757575
       für Hilfstext. Auf Weiß erreicht der Wert 4,61:1, auf der Seitenfläche
       #f4f4f4 aber nur 4,19:1 — unter der Grenze von 4,5:1, und Hilfstext ist
       genau die Stelle, an der ein zu schwacher Kontrast zuerst wehtut.
       #6b6b6b liegt bei 5,33:1 bzw. 4,85:1 und ist von #757575 mit bloßem
       Auge nicht zu unterscheiden. */
    --text: #000000;
    --text-gedaempft: #2b2b2b;
    --hilfstext: #6b6b6b;

    /* ── Flächen und Linien ── */
    --grund: #ffffff;
    --flaeche: #f4f4f4;
    --flaeche-still: #efefef;
    --linie: #e8e8e8;
    --linie-zart: #f0f0f0;

    /* ── Zweitakzent ──
       Das Petrolblau der Website. Es trägt hier den Fokusrahmen: die
       Tastaturbedienung muss sichtbar sein, und das Rot ist dafür gesperrt. */
    --zweitakzent: #15779b;

    /* ── Zustände ──
       Hier liegt die eine Falle dieser Gestaltung: Die Hausfarbe #9b111e und
       die bisherige Fehlerfarbe #8a1c12 sind fast dasselbe Rot. Nebeneinander
       läse sich jede Überschrift wie eine Warnung.

       Auseinandergezogen wird das über die FORM, nicht über einen weiteren
       Rotton:

         - Die Marke erscheint ausschließlich als 3 Pixel schmaler,
           freistehender senkrechter Balken. Nie als Fläche, nie als Text.
         - Ein Zustand erscheint ausschließlich als gefülltes Band über die
           volle Breite, mit farbiger Kante links und SCHWARZEM Text.

       Damit gibt es im ganzen Portal keinen einzigen roten Buchstaben, mit
       dem sich die Hausfarbe verwechseln ließe. Die Kantenfarben sind
       zusätzlich deutlich heller und weniger gesättigt als die Hausfarbe
       (Fehler: H 12°/L 46 % gegen Marke H 354°/L 34 %). */
    --fehler-flaeche: #f8e6e1;
    --fehler-kante: #c0442a;
    --erfolg-flaeche: #e4efe6;
    --erfolg-kante: #3c7a4e;
    --warnung-flaeche: #f8eeda;
    --warnung-kante: #b8862a;

    /* ── Die beiden Basisfarben des Brand Guides ──
       „Colors: dark blue/anthracite as a base, ruby red as a separator"
       (Brand Guidelines 2026, Abschnitt Website). Bis zum 20.08.2026 kannte
       das Portal nur Schwarz und Grau; Gemstone Blue und Anthrazit standen im
       Guide, aber nirgends im Stilblatt. Sie tragen jetzt das Kennzahlenband
       und die Hauptknöpfe — die Flächen also, die der Guide „subtle color
       areas" nennt. */
    --tief: #0d1b2a;        /* GEMSTONE BLUE, Brand Guide */
    --anthrazit: #2f2f2f;   /* ANTHRACITE, Brand Guide */
    /* Die Hausfarbe, aufgehellt für dunklen Grund. Auf #0d1b2a käme
       --marke selbst nur auf 2,06:1 und wäre nicht lesbar; dieser Ton liegt
       bei 8,3:1 und bleibt erkennbar dieselbe Farbe. Er steht hier als Token
       und nicht als Hex im Regelwerk, weil jede andere Farbe dieses Blattes
       auch hier steht. */
    --marke-hell: #e8a0a8;

    /* ── Maße ──
       Der Radius ist 2 Pixel und nicht mehr. Das Logo hat keine runde Ecke;
       8 Pixel, wie sie bisher überall standen, machten aus einer Akte eine
       App-Kachel. */
    --radius: 2px;
    --kante: 1px solid var(--linie);

    --a1: 0.25rem;
    --a2: 0.5rem;
    --a3: 0.75rem;
    --a4: 1rem;
    --a5: 1.5rem;
    --a6: 2rem;

    --schrift-text: 'Open Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI',
        system-ui, sans-serif;
    --schrift-titel: 'Baskervville', 'Iowan Old Style', 'Palatino Linotype',
        Palatino, Georgia, 'Times New Roman', serif;
    --schrift-ziffern: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* ══════════════════════════════════════════════════════════════════════════
   Grundlage
   ══════════════════════════════════════════════════════════════════════════ */

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* box-sizing steht hier ein für alle Mal.

   In sieben der zwölf Ansichten stand derselbe Kommentar über derselben
   Regel: ohne border-box zählt das Innenmaß die Polsterung nicht mit, die
   Karte wird breiter als angegeben und läuft auf dem Telefon seitlich aus dem
   Bild. Siebenmal dieselbe Lehre aufzuschreiben heißt, sie beim achten Mal zu
   vergessen. Als Grundregel gilt sie für alles, was noch dazukommt. */

/* ── `hidden` heißt hidden ── (16.09.2026)

   Der Browser bringt diese Regel selbst mit, aber nur in seinem eigenen
   Grundblatt — und JEDE Regel aus diesem Blatt hier sticht sie, ganz gleich
   wie schwach ihr Selektor ist. Ein späteres `.kopierknopf { display: inline-flex }`
   machte damit einen Knopf sichtbar, der `hidden` trägt, und niemand suchte
   den Fehler im Stilblatt.

   Genau daran hängt seit dem 16.09.2026 der Rückfallweg des Kopierknopfes:
   Die Seite liefert Adresse UND Knopf aus, der Knopf steht mit `hidden` da,
   und app/kopieren.js dreht es um. Greift `hidden` nicht, sieht jeder ohne
   JavaScript beides — und mit JavaScript die Adresse doppelt.

   `!important`, weil die Regel keine Abwägung ist: Was verborgen sein soll,
   ist verborgen. Wer etwas zeigen will, nimmt das Attribut weg. */
[hidden] {
    display: none !important;
}

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

body {
    margin: 0;
    background: var(--flaeche);
    color: var(--text);
    font-family: var(--schrift-text);
    font-size: 0.9375rem;
    line-height: 1.55;
}

a {
    color: var(--text);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

a:hover {
    color: var(--marke);
}

/* Der Fokusrahmen ist Bedienung, nicht Zierrat: Wer mit der Tastatur durch
   ein Formular mit vierzig Feldern geht, muss sehen, wo er steht. */
:focus-visible {
    outline: 2px solid var(--zweitakzent);
    outline-offset: 2px;
}

img {
    max-width: 100%;
}

/* ══════════════════════════════════════════════════════════════════════════
   Kopfzeile mit dem Logo
   ══════════════════════════════════════════════════════════════════════════ */

header {
    background: var(--grund);
    border-bottom: var(--kante);
    padding: var(--a3) var(--a5);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--a2) var(--a4);
}

/* Das Logo trägt die Überschrift der Seite und führt zur Startseite. Der
   Alternativtext nennt den Namen, den die Kopfzeile vorher als Text trug —
   für Vorlesewerkzeuge und für den Fall, dass das Bild nicht lädt. */
header h1 {
    margin: 0;
    font-size: 0;
    line-height: 0;
}

header h1 a {
    display: inline-block;
}

header h1 img {
    display: block;
    height: 1.75rem;
    width: auto;
}

header span {
    font-size: 0.8125rem;
    color: var(--hilfstext);
}

header span a {
    color: var(--text-gedaempft);
}

/* ══════════════════════════════════════════════════════════════════════════
   Seitenkörper und Überschriften
   ══════════════════════════════════════════════════════════════════════════ */

main {
    padding: var(--a5);
    /* Entschieden am 16.08.2026: Auch kann es am Desktop gerne breiter sein.
       44rem waren an einer Textspalte bemessen — für Fließtext ist das die
       richtige Größe, für eine Akte mit zwei Spalten Stammdaten nicht. Dort
       stand rechts vom Inhalt mehr leere Fläche als Inhalt.

       Kein fester Wert, sondern min(): Bei einem schmalen Fenster gilt
       weiterhin die volle Breite abzüglich Rand, bei einem breiten die
       Obergrenze. Ein festes max-width erzwänge auf einem 1000-Pixel-Fenster
       denselben Rand wie auf einem 2000er, und der Inhalt bliebe schmal,
       obwohl Platz da ist. */
    max-width: min(100%, 58rem);
    margin: 0 auto;
}

/* Die Listen brauchen mehr Breite als die Formulare und Akten: Sie führen
   Spalten, keine Sätze. */
main.breit {
    max-width: min(100%, 76rem);
}

/* ── Die Seitenüberschrift und der eine rote Balken ──
   Hier — und ausschließlich hier — erscheint die Hausfarbe. Der Balken zitiert
   den Trenner im Logo: dieselbe Breite, dieselbe Haltung, einmal je Seite. */
main > h2 {
    font-family: var(--schrift-titel);
    font-size: 1.5rem;
    font-weight: 400;
    line-height: 1.25;
    margin: 0 0 var(--a4);
    padding-left: var(--a3);
    border-left: 3px solid var(--marke);
}

/* Steht eine Unterzeile unter der Überschrift, gehören beide zusammen; der
   Abstand darunter wandert dann an die Unterzeile. */
main > h2 + .unterzeile,
main > h2 + .unternummer {
    margin: calc(var(--a4) * -1 + var(--a2)) 0 var(--a5) calc(var(--a3) + 3px);
    color: var(--hilfstext);
    font-size: 0.8125rem;
}

/* ══════════════════════════════════════════════════════════════════════════
   Karten
   ══════════════════════════════════════════════════════════════════════════

   Flächen statt Schatten: Die Karte hebt sich vom Grund durch ihre weiße
   Fläche und eine Linie ab, nicht durch einen Schlagschatten. */

.karte {
    background: var(--grund);
    border: var(--kante);
    border-radius: var(--radius);
    padding: var(--a5);
    width: 100%;
    margin-bottom: var(--a4);
}

.karte:last-child {
    margin-bottom: 0;
}

/* Die Kartenüberschrift steht in der Antiqua, in gemischter Schreibweise und
   über einer Haarlinie. Bisher stand sie in gesperrten Versalien — das gab
   jeder Karte ein Schild statt einer Überschrift. */
.karte h2,
.karte h3 {
    font-family: var(--schrift-titel);
    font-size: 1.125rem;
    font-weight: 400;
    line-height: 1.3;
    margin: 0 0 var(--a4);
    padding-bottom: var(--a2);
    border-bottom: 1px solid var(--linie-zart);
    color: var(--text);
}

/* ══════════════════════════════════════════════════════════════════════════
   Meldungen und Zustände
   ══════════════════════════════════════════════════════════════════════════

   Alle drei Bänder sind gleich gebaut: gefüllte Fläche, farbige Kante links,
   schwarzer Text. Unterschieden werden sie über Farbton und Kante — nie über
   rote Schrift, die mit der Hausfarbe verwechselt werden könnte. */

.fehler,
.erfolg,
.eingegangen,
.warnung {
    padding: var(--a3) var(--a4);
    border-radius: var(--radius);
    border-left: 4px solid;
    margin: 0 0 var(--a5);
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--text-gedaempft);
}

.fehler {
    background: var(--fehler-flaeche);
    border-left-color: var(--fehler-kante);
}

.erfolg,
.eingegangen {
    background: var(--erfolg-flaeche);
    border-left-color: var(--erfolg-kante);
}

.warnung {
    background: var(--warnung-flaeche);
    border-left-color: var(--warnung-kante);
    margin: var(--a3) 0 0;
    font-size: 0.8125rem;
}

/* ── Der Schaumodus ──

   Das Band steht über der Kopfzeile und auf jeder Seite (app/views/_kopf.php).
   Es folgt der Zustandsform dieses Blattes: gefüllte Fläche, farbige Kante,
   schwarzer Text — kein roter Buchstabe, mit dem sich die Hausfarbe
   verwechseln ließe.

   Über die ganze Breite und ohne Radius: Es ist kein Hinweis IN der Seite,
   sondern eine Aussage ÜBER die Seite. Wer es einmal gesehen hat, erkennt am
   Rand des Fensters, dass die Zahlen darunter erfunden sind.

   Kein Knopf darin: In den Schaumodus kommt man nur über einen eigenen
   Zugang, hinaus nur durch Abmelden. */
.schauband {
    background: var(--warnung-flaeche);
    border-bottom: 3px solid var(--warnung-kante);
    color: var(--text);
    padding: var(--a2) var(--a5);
    font-size: 0.8125rem;
    line-height: 1.4;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--a2) var(--a4);
}

/* Die Warnung als Band über der Seite statt als Anmerkung darin.
   .warnung setzt margin-bottom auf 0 — richtig für eine Anmerkung innerhalb
   einer Karte, wo direkt darunter nichts mehr kommt (Partnerakte,
   Kundenakte). Steht sie oben auf der Seite, klebt der folgende Text am
   Band. Die Schriftgröße geht auf den Wert der übrigen Meldebänder zurück:
   Wer hier gerade gefragt wird, ob er etwas Unumkehrbares tut, soll nicht
   das Kleingedruckte lesen. */
.warnung.band {
    margin: 0 0 var(--a5);
    font-size: 0.875rem;
}

.warnung.band > :last-child {
    margin-bottom: 0;
}

.fehler p {
    margin: 0 0 var(--a1);
}

.fehler p:last-child {
    margin-bottom: 0;
}

.fehler ul {
    margin: 0;
    padding-left: 1.1rem;
    font-size: 0.875rem;
    line-height: 1.5;
}

.fehler li {
    margin: 0.15rem 0;
}

/* Erklärender Vorspann über einem Formular oder einer Liste. */
p.hinweis {
    font-size: 0.875rem;
    line-height: 1.6;
    margin: 0 0 var(--a5);
    color: var(--text-gedaempft);
    max-width: 38rem;
}

/* Der kleine Zusatz unter einem Feld oder einer Feldreihe. Er darf NICHT auf
   .feld eingeschränkt werden — mehrere dieser Zusätze stehen unter einer
   ganzen Reihe, und dort fielen sie sonst auf Absatzgröße zurück und läsen
   sich wie Fließtext. */
.zusatz {
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--hilfstext);
    margin: -0.35rem 0 var(--a4);
}

/* Steht der Zusatz unter einem Stammdatenraster oder einem Absatz statt unter
   einem Eingabefeld, ist der negative Anzug oben falsch: Er zieht den Text in
   die letzte Rasterzeile hinein, und „Land / Deutschland" klebt am ersten
   Satz. So gemessen in der Maske „Stammdaten ändern", auf 1280 wie auf 390
   Pixeln. */
.stamm + .zusatz,
.stand + .zusatz {
    margin-top: var(--a5);
}

/* display:block, weil dieser Hinweis auch als <span> in einem <label> steht
   (Zuordnungsentscheidung in der Kundenakte) — dort wirkte der Abstand
   sonst nicht. */
.schutzhinweis {
    display: block;
    color: var(--hilfstext);
    font-size: 0.8125rem;
    font-weight: 400;
    margin: 0 0 var(--a3);
}

.leer {
    color: var(--hilfstext);
    font-size: 0.875rem;
    margin: 0;
}

/* Die Kundenliste zeigt ihren Leertext ohne Karte darum; er bekommt sie hier.
   Ausdrücklich nur als DIREKTES Kind von main: In den Karten steht dieselbe
   Klasse (etwa „Noch kein Statuswechsel"), und dort sähe ein zweiter Kasten
   im Kasten wie ein Fehler aus. */
main > p.leer {
    background: var(--grund);
    border: var(--kante);
    border-radius: var(--radius);
    padding: var(--a4) var(--a5);
}

/* ══════════════════════════════════════════════════════════════════════════
   Formulare
   ══════════════════════════════════════════════════════════════════════════ */

label {
    display: block;
    font-size: 0.875rem;
    margin-bottom: var(--a4);
}

input,
select,
textarea {
    font-family: inherit;
    font-size: 0.9375rem;
    color: var(--text);
    background: var(--grund);
    border: 1px solid #cfcfcf;
    border-radius: var(--radius);
    padding: 0.5rem 0.6rem;
    width: 100%;
    margin-top: var(--a1);
}

input[type='checkbox'],
input[type='radio'] {
    width: auto;
    margin-top: 0;
}

input[type='file'] {
    padding: 0.4rem;
    font-size: 0.8125rem;
}

/* ══════════════════════════════════════════════════════════════════════════
   Das Datumsfeld als Datumswähler (Paul, 02.10.2026)
   ══════════════════════════════════════════════════════════════════════════
   Pauls Bildschirmfotos aus Safari: ein leeres Feld über die ganze Breite,
   ohne Hinweis, dass es ein Datum will; beim Stichtag der Abrechnung stand
   „02.10.2026" mittig in einem Balken. Er hat gezeichnet, was er erwartet:
   schmal, links, mit Kalendersymbol.

   ── Schmal ──
   So breit wie ein Datum plus Symbol. `max-width` und `min-width: 0` bleiben,
   weil Safari dem Feld sonst eine Mindestbreite aus seinem Inhalt gibt und es
   über die Karte hinausragte.

   ── Das Symbol ──
   Safari zeigt keines; Chrome ein eigenes, das je nach Version anders
   aussieht. Deshalb ein eigenes im Stil der Portal-Sinnbilder (20 × 20,
   Strich 1.4, keine Füllung, app/views/_icons.php). In Chrome wird dessen
   Schaltfläche unsichtbar über das Symbol gelegt — ein Klick dort öffnet
   weiter den Kalender. Safari öffnet ihn bei einem Klick ins Feld. Firefox
   zeichnet ein eigenes Symbol, das sich nicht ausblenden lässt; dort entfällt
   unseres (Regel am Ende), sonst stünden zwei nebeneinander. */
input[type='date'] {
    /* Eine eigene Zeile wie jedes andere Feld: Schmal geworden, rückte
       sonst der Knopf dahinter in dieselbe Zeile. */
    display: block;
    width: 11.5rem;
    min-width: 0;
    max-width: 100%;
    position: relative;
    text-align: left;
    padding-right: 2.4rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%23333' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4.5' width='14' height='12.5'/%3E%3Cpath d='M3 8.5h14M7 2.8v3.4M13 2.8v3.4'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.65rem center;
    background-size: 1.1rem 1.1rem;
}

/* Safari setzt den Wert mittig, wenn das Feld breiter ist als er. */
input[type='date']::-webkit-date-and-time-value {
    text-align: left;
}

input[type='date']::-webkit-calendar-picker-indicator {
    position: absolute;
    right: 0;
    top: 0;
    width: 2.4rem;
    height: 100%;
    margin: 0;
    padding: 0;
    opacity: 0;
    cursor: pointer;
}

@supports (-moz-appearance: none) {
    input[type='date'] {
        background-image: none;
        padding-right: 0.6rem;
    }
}

/* In der EIFE-Wahl und beim Wechsel der Vertragsart folgt „gilt ab" direkt
   auf die Auswahl. Die Beschriftung trägt nur Abstand nach unten; ohne
   diesen klebte sie an der Auswahl darüber und las sich wie deren
   Unterzeile (Paul, 02.10.2026: „mehr Abstand"). */
/* Nur nach einer Auswahl: `input + label` griff auch auf das versteckte
   Feld partner_id vor „Neue Vertragsart" (Prüfer, 02.10.2026). */
.mit-stichtag select + label {
    margin-top: var(--a4);
}

textarea {
    min-height: 4.5rem;
    resize: vertical;
}

input:focus,
select:focus,
textarea:focus {
    border-color: var(--zweitakzent);
}

/* Derselbe Ton wie .knopf, seit dem 20.08.2026. Vorher war der Absendeknopf
   schwarz und der Link-Knopf daneben blau — zwei Hauptknöpfe in zwei Farben
   auf derselben Maske. Eine halbe Umstellung fällt mehr auf als keine. */
button {
    font-family: inherit;
    font-size: 0.9375rem;
    padding: 0.6rem 1.2rem;
    border: 0;
    border-radius: var(--radius);
    background: var(--tief);
    color: var(--grund);
    cursor: pointer;
}

/* ── Luft zwischen Eingabe und Knopf ── (01.09.2026)

   Vorgabe: „Die Abstände zwischen Feldern und dem Button sind zu gering.
   Ändere das durchgehend."

   Der Knopf klebte am Feld darüber. Grund: `input`/`select` tragen nur
   `margin-top`, der Knopf gar keinen — zwischen beiden stand also nichts
   als der Zeilenabstand.

   Der Abstand hängt am KNOPF und nicht am Feld: Ein `margin-bottom` am Feld
   träfe auch die Fälle, in denen zwei Felder untereinander stehen, und dort
   ist der Abstand richtig. Der Geschwisterselektor greift genau dort, wo ein
   Knopf auf eine Eingabe folgt.

   `~` und nicht `+`: Zwischen Feld und Knopf steht oft noch ein Hinweistext
   oder ein weiteres Feld. */
input ~ button,
select ~ button,
textarea ~ button,
label ~ button,
input ~ .knopf,
select ~ .knopf,
textarea ~ .knopf {
    margin-top: var(--a4);
}

/* Steht der Knopf in einer eigenen Zeile unter einem Feldraster, gilt
   dasselbe. `.wege` fasst mehrere Knöpfe nebeneinander. */
form > .wege,
form > button:first-child {
    margin-top: var(--a4);
}

/* Und dahinter genauso viel: Der Erklärtext klebte am Knopf, das Formular
   an der Karte darunter. Ein Knopf braucht Luft auf beiden Seiten, sonst
   liest sich der Satz darunter wie seine Beschriftung. */
form + p,
form + .hinweis,
.wege + .wege {
    margin-top: var(--a4);
}

/* ── Luft zwischen Text und Knopf ── (02.10.2026)

   Vorgabe: „Überprüfe überall, der Abstand zwischen Text und Button ist oft
   passend, manchmal aber auch zu gering." Gemessen auf 47 gerenderten Seiten
   (WebKit, 1280 und 390 Pixel): zwischen 0 und 40 Pixel. 0 Pixel in der
   Partnerakte unter „Alle Buchungen dieses Partners …" und „Welche Sätze für
   diesen Partner gelten …": `.leer` hat keinen Rand, `.wege` auch nicht.
   40 Pixel unter dem Hinweis zum Stichtag: Hinweis 24 plus `input ~ button`
   16, weil sich der Rand eines inline-block-Knopfes mit dem des Absatzes
   darüber nicht zusammenlegt.

   Die Regel: Zwischen einem Text (Absatz, Liste) und dem Knopf darunter
   stehen 24 Pixel, var(--a5). Das ist der Abstand, den Paul vor „In
   OpenStreetMap öffnen" passend fand — dort trägt ihn `p.hinweis`.

   Den Abstand trägt der TEXT, der Knopf legt nichts drauf. Nur so gibt es ihn
   genau einmal, egal ob der Knopf als Block (`.wege`) oder inline (`button`,
   `a.knopf`) steht. Der Knopf allein könnte es nicht: Sein Rand addierte
   sich zu jedem Absatzrand, und der ist je nach Klasse 0, 16 oder 24 Pixel.

   Als Knopf zählt auch der Absatz, der nur einen Knopf trägt
   (`<p><button>…</button></p>`, so steht der Absendeknopf in den meisten
   Masken). Sein eigener Rand legt sich mit dem des Textes zusammen.

   Ein Formular, das mit dem Knopf beginnt (Partner löschen, Zugang
   sperren; davor nur versteckte Felder), zählt als Knopf. Eines, das mit
   einem Feld beginnt, nicht: Für Feld → Knopf gilt weiter var(--a4) von oben.

   Der Kopierknopf ist ausgenommen. Er gehört zu dem Link darüber und steht
   absichtlich dicht daran.

   `:has()` darf nicht in sich selbst stehen; ein verschachteltes `:has()`
   macht die ganze Regel ungültig. Deshalb erkennt `:not(:not(input[type=
   'hidden']) ~ *)` den ersten sichtbaren Knopf im Formular. `@supports`:
   Ein Browser ohne `:has()` bekäme sonst nur die zweite Regel, nähme dem
   Knopf den Rand und gäbe dem Text keinen. */
@supports selector(:has(+ *)) {
    :is(p, ul, ol, dl):not(.wege):has(
            + :is(button, .knopf, .wege):not(.kopierknopf),
            + p > :is(button, .knopf):only-child,
            + form > :is(button, .knopf, .wege):not(:not(input[type='hidden']) ~ *)
        ) {
        margin-bottom: var(--a5);
    }

    :is(p, ul, ol, dl):not(.wege) + :is(button, .knopf):not(.kopierknopf),
    :is(p, ul, ol, dl):not(.wege)
        + form
        > :is(button, .knopf):not(:not(input[type='hidden']) ~ *) {
        margin-top: 0;
    }
}

/* ── Luft zwischen Feld und Hinweis darunter ── (02.10.2026)

   Der Hinweis unter einem Feld zieht sich mit `.zusatz { margin-top:
   -0.35rem }` an das Feld heran. Das ist für den Fall gebaut, dass er unter
   einem `.feld` steht: Dessen Rand von 12 Pixeln minus 5,6 ergibt 6,4
   Pixel. Folgt er dem Eingabefeld aber DIREKT, fehlt dieser Rand, und der
   Text rückt 5,6 Pixel in das Feld hinein (Partner anlegen, Stammdaten).
   `p.hinweis` und `.schutzhinweis` hatten dort 0 Pixel (Stichtag in den
   Abrechnungsläufen, Vertriebsregionen).

   Die Regel: Ein Hinweis steht 0,4rem (6,4 Pixel) unter seinem Feld, überall
   gleich. Kästchen und Auswahlknöpfe sind ausgenommen; dort steht der
   Hinweis in der Beschriftung neben dem Kästchen. */
:is(input:not([type='checkbox'], [type='radio'], [type='hidden']), select, textarea)
    + :is(.zusatz, p.hinweis, .schutzhinweis) {
    margin-top: 0.4rem;
}

button:hover {
    background: var(--anthrazit);
}

/* Ein Weg, der wie ein Knopf aussieht (Startseite). */
/* Gemstone Blue statt Schwarz, seit dem 20.08.2026.
   Der Brand Guide nennt für die Website „dark blue/anthracite as a base";
   Schwarz kommt darin nur im Logo und in der Schrift vor. Der Unterschied ist
   auf einem einzelnen Knopf klein und über eine ganze Seite hinweg deutlich:
   Das Portal sah bis dahin aus wie ein Verwaltungswerkzeug von der Stange. */
.knopf {
    display: inline-block;
    padding: 0.6rem 1.2rem;
    border-radius: var(--radius);
    background: var(--tief);
    color: var(--grund);
    text-decoration: none;
    font-size: 0.875rem;
}

.knopf:hover {
    background: var(--anthrazit);
    color: var(--grund);
}

/* Der zweitrangige Knopf: umrandet statt gefüllt, für das, was nicht der
   Hauptweg der Maske ist (Zweitfaktor zurücksetzen neben Passwort zuteilen).

   Ausdrücklich NICHT rot, obwohl er den folgenreicheren Vorgang auslöst. Die
   Gestaltung dieses Portals kennt keinen einzigen roten Buchstaben — sonst
   ließe sich die Hausfarbe mit einer Warnung verwechseln (siehe :root,
   Abschnitt Zustände). Vor dem Vorgang warnt der Text und die Rückfrage, nicht
   die Farbe. Ein gefüllter Knopf neben einem gefüllten zöge das Auge ohnehin
   auf den falschen. */
.knopf-zweitrangig {
    background: var(--grund);
    /* Gemstone Blue statt Schwarz, wie beim gefüllten Knopf. Die Reiter der
       Bitrix-Liste setzen aktiv .knopf gegen inaktiv .knopf-zweitrangig; in
       zwei verschiedenen Farben las sich das als zwei Arten von Reiter. */
    color: var(--tief);
    border: 1px solid var(--tief);
}

.knopf-zweitrangig:hover {
    background: var(--flaeche);
    color: var(--tief);
}

/* Der gesperrte Knopf „Jetzt aus Drive holen" (04.10.2026): Solange ein
   Auftrag wartet oder läuft, lässt er sich nicht drücken — und soll auch
   nicht so aussehen. Bewusst nur dort: Die übrigen gesperrten Knöpfe des
   Portals (Teilen während des Ladens, Buchung in der Kundenakte) sehen heute
   aus wie freie; das zu ändern ist eine eigene Entscheidung. */
#holen button:disabled,
#holen button:disabled:hover {
    background: var(--flaeche);
    color: var(--text-gedaempft);
    cursor: not-allowed;
}

.wege {
    display: flex;
    flex-wrap: wrap;
    gap: var(--a2);
}

/* Ein Formular mit wenigen Feldern läuft sonst über die volle Breite der
   Maske. Bei drei Passwortfeldern sieht das aus, als fehlte etwas rechts.
   .schmal gibt es nur innerhalb body.mitte und .anmeldung-seite (Anmeldung, Registrierung) und
   wirkt auf den Seiten mit Kopfzeile nicht. */
.schmales-formular {
    max-width: 24rem;
}

/* Ein zugeteiltes Passwort wird abgeschrieben oder vorgelesen. Es steht
   genau einmal da und muss auf einen Blick lesbar sein — in Ziffernschrift,
   damit sich 0 und O nicht angleichen, und groß genug, dass niemand sich
   vorbeugen muss. Der Zeichenvorrat in Auth::passwortErzeugen() lässt die
   verwechselbaren Zeichen ohnehin weg; das hier ist die zweite Hälfte
   derselben Überlegung. */
.passwort-einmal {
    font-family: var(--schrift-ziffern);
    font-size: 1.5rem;
    color: var(--text);
    letter-spacing: .04em;
    margin: var(--a3) 0;
    user-select: all;
}

/* Der Abrechnungsblock in der Kundenakte: ein Formular INNERHALB der
   Geschäftsdarstellung. Es braucht eine sichtbare Kante nach oben, sonst
   liest es sich wie eine Fortsetzung der Stammdaten darüber — und jemand
   trägt etwas ein, ohne zu merken, dass er damit bucht. */
form.abrechnung {
    margin-top: var(--a5);
    padding-top: var(--a4);
    border-top: var(--kante);
}

form.abrechnung h4 {
    font-family: var(--schrift-titel);
    font-size: 1rem;
    font-weight: 400;
    margin: 0 0 var(--a2);
}

/* ── Die Rückabwicklung (Spec § 7.6) ──
   Derselbe Block, aber unmissverständlich anders: Sie ist der einzige Knopf
   im Portal, der einem Partner Geld wegnimmt. Die Fehlerfläche des Portals
   trägt ihn — kein neues Rot, damit es nicht wie eine zweite Warnstufe
   aussieht, sondern wie die eine, die es schon gibt. */
form.abrechnung.storno {
    background: var(--fehler-flaeche);
    border-top-color: var(--fehler-kante);
    padding: var(--a4);
    border-radius: var(--radius);
}

button.gefahr {
    background: var(--fehler-kante);
}

button.gefahr:hover {
    /* Dunkler, nicht heller: Ein Knopf, der beim Zeigen aufleuchtet, lädt
       zum Drücken ein. Dieser soll es nicht. */
    background: #9a3521;
}

/* Ein rückabgewickeltes Geschäft bleibt sichtbar, tritt aber zurück. Es
   verschwinden zu lassen wäre bequem und falsch: Das Provisionskonto stünde
   im Minus und nichts auf der Seite erklärte, warum. */
.geschaeft.storniert .stamm,
.geschaeft.storniert > .warnung + .stamm {
    opacity: 0.65;
}

/* ── Feld, Reihe, Haken ── (Melde- und Kaufmaske) */
.feld {
    margin-bottom: var(--a3);
}

.feld label {
    display: block;
    font-size: 0.8125rem;
    font-weight: 600;
    margin: 0 0 var(--a1);
}

.feld input,
.feld select,
.feld textarea {
    margin-top: 0;
}

.reihe {
    display: flex;
    gap: var(--a3);
    flex-wrap: wrap;
}

.reihe .feld {
    flex: 1 1 9rem;
    min-width: 0;
}

/* ── Ein Feld, an dem etwas nicht stimmt ── (IBAN-Prüfung, 28.08.2026)

   Die Meldung steht im Kasten am Seitenanfang UND hier am Feld. Wer zwanzig
   Stellen abtippt und die Seite zurückbekommt, sucht den Fehler dort, wo er
   ihn gemacht hat.

   Die Kante ist die Fehlerfarbe des Portals, nicht die Hausfarbe: Rote
   Buchstaben gibt es hier nicht, sonst läse sich jede Überschrift wie eine
   Warnung. Ein Rahmen ist keine Schrift. */
input.feld-fehler {
    border-color: var(--fehler-kante);
    background: var(--fehler-flaeche);
}

.feld-befund {
    display: block;
    margin-top: 0.35rem;
    color: var(--text-gedaempft);
}

/* Zwei Felder nebeneinander, die aber lieber untereinander stehen als sich
   auf 150 Pixel zu quetschen. `.reihe` bricht erst unter 9rem um; bei einem
   Feld mit Hinweistext darunter — Benutzername und Rolle beim Anlegen eines
   Zugangs — ist das zu spät, gemessen am 28.08.2026 auf 390 Pixel. */
.reihe-breit .feld {
    flex: 1 1 14rem;
}

.haken {
    display: flex;
    gap: 0.55rem;
    align-items: flex-start;
    margin-bottom: var(--a2);
}

.haken input {
    margin-top: 0.25rem;
    flex: 0 0 auto;
}

.haken label {
    font-size: 0.875rem;
    line-height: 1.45;
    font-weight: 400;
    margin: 0;
}

/* Ein Feld, in das drei Ziffern passen, soll auch nur so breit sein.
   `.schmales-formular` deckelt bei 24rem — richtig für Namen und Anschriften,
   aber ein Kasten von 384 Pixeln für die Zahl 0 sieht aus, als fehle dort
   etwas. */
.feld-zahl input {
    max-width: 7rem;
}

/* Die Liste der Unterlagen steht in der Pflegekarte direkt über dem
   Freigabe-Haken. Ohne Abstand kleben beide aneinander, und der Haken liest
   sich wie eine weitere Tabellenzeile. */
.karte table + form,
.karte table + .haken {
    margin-top: var(--a3);
}

/* ── Die Spalte, in der etwas zu tun ist ── (Mediathek)

   Der Knopf gehört an den rechten Rand seiner Zeile. Ohne diese Regel steht
   er am linken Rand der letzten Spalte, und weil diese Spalte den ganzen
   Rest der Breite bekommt, klafft rechts daneben ein Feld aus nichts —
   gemessen am 28.08.2026 auf 1280 Pixel.

   `width: 1%` ist kein Widerspruch dazu: Eine Tabellenzelle wird nie
   schmaler als ihr Inhalt, und ein kleiner Wunsch heisst deshalb „so schmal
   wie möglich". Die Breite geht damit an die Spalten mit Text. */
td.tat {
    text-align: right;
    width: 1%;
    white-space: nowrap;
}

/* Zwei Knöpfe in einer Zelle (Mediathek: „Ansehen" und „Herunterladen",
   02.10.2026). `.wege` ist ein Flex-Behälter, und auf den wirkt
   `text-align: right` nicht — ohne diese Zeile stünden die beiden links in
   einer rechtsbündigen Spalte. */
td.tat > .wege {
    justify-content: flex-end;
    flex-wrap: nowrap;
}

@media (max-width: 640px) {
    /* Gestapelt gibt es keine Spalten mehr; der Knopf steht dann links unter
       seiner Zeile und braucht die Einrückung der Beschriftung nicht. */
    table.gestapelt td.tat {
        text-align: left;
        width: auto;
        padding-left: 0.9rem;
    }

    table.gestapelt td.tat > .wege {
        justify-content: flex-start;
        flex-wrap: wrap;
    }
}

/* Ein kurzes Formular in einer Zeile: Eingabe und Knopf nebeneinander, mit
   Abstand nach oben. Für den Rückzug einer Meldung in der Kundenakte — er
   gehört in die Zeile, zu der er gehört, nicht in einen eigenen Kasten. */
form.zeile {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    margin-top: 0.4rem;
}

form.zeile input[type='text'] {
    flex: 1 1 14rem;
    width: auto;
    margin-top: 0;
}

/* ── Mehrere Haken nebeneinander ── (Mediathek: Sichtbarkeit je Vertragsart)

   `.haken` trägt EINEN Haken mit seinem Text daneben: Der Text ist dort ein
   Geschwister des Kästchens, und der Block darf umbrechen. Vier Wahlen in
   einer Zeile brauchen das Gegenteil — jedes Kästchen muss an seinem Wort
   kleben. Gemessen am 28.08.2026 auf 390 Pixel: „OH-Tippgeber" rutschte unter
   sein Kästchen, und aus vier Haken wurden vier Rätsel.

   Deshalb eine eigene Klasse statt einer Änderung an `.haken`: Die alte Regel
   steht an vierzehn Stellen in der Kaufmeldung, und keine davon wollte je
   eine Reihe. */
.hakenreihe {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1.1rem;
    margin-bottom: var(--a2);
}

.hakenreihe label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    /* Das Wort bleibt bei seinem Kästchen; umgebrochen wird zwischen den
       Paaren, nicht in ihnen. */
    white-space: nowrap;
    font-size: 0.875rem;
    line-height: 1.45;
    font-weight: 400;
    margin: 0;
}

.hakenreihe input {
    margin: 0;
    flex: 0 0 auto;
}

/* Die abhängigen Blöcke gehören sichtbar zu dem Haken bzw. dem Lieferweg
   darüber; die gestrichelte Linie sagt das, ohne einen Kasten zu bauen. */
.abhaengig {
    margin-top: var(--a2);
    padding-top: var(--a2);
    border-top: 1px dashed var(--linie);
}

/* ── Auswahlfeld und Knopf nebeneinander ── (Unterlagen-Übersicht)
   Eine eigene Klasse und nicht „.karte form", weil in anderen Karten
   Formulare stehen, die untereinander gehören — die Freischaltung mit ihrem
   Datumsfeld etwa. Eine Regel auf alle Formulare in Karten hätte die
   zerrissen. */
form.hochladen {
    display: flex;
    gap: var(--a2);
    flex-wrap: wrap;
    align-items: center;
}

form.hochladen input[type='file'] {
    flex: 1 1 12rem;
    min-width: 0;
    margin-top: 0;
}

form.hochladen button {
    white-space: nowrap;
    padding: 0.5rem 1rem;
    font-size: 0.875rem;
}

/* ── Filterzeile über den Listen ── */
.filter {
    display: flex;
    gap: var(--a2);
    flex-wrap: wrap;
    align-items: center;
    margin-bottom: var(--a5);
}

.filter input[type='search'],
.filter input[type='date'],
.filter select {
    width: auto;
    margin-top: 0;
    font-size: 0.875rem;
}

/* Datumsfelder ohne diese Zeile erben die globale Breite von 100 Prozent und
   nehmen je eine ganze Zeile ein. Im Protokollfilter standen „von" und „bis"
   dadurch als zwei breite Balken unter den schmalen Auswahlfeldern. */

.filter label {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.875rem;
    color: var(--hilfstext);
}

.filter input[type='search'] {
    min-width: 12rem;
    flex: 1 1 12rem;
}

.filter button {
    padding: 0.5rem 1rem;
    font-size: 0.875rem;
}

/* ══════════════════════════════════════════════════════════════════════════
   Stammdaten
   ══════════════════════════════════════════════════════════════════════════ */

.stamm {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--a4) var(--a5);
}

.stammfeld {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

/* Die Bezeichnung steht in gemischter Schreibweise, nicht in gesperrten
   Versalien: Achtzehn Versalzeilen nebeneinander sind ein Formular, das
   schreit.

   Entschieden am 16.08.2026: Die Felder (also wo der jeweilige Name etc. steht)
   sollten besser sichtbar sein, damit man leichter findet, wonach man sucht.

   Er hat recht, und die Ursache war eine vertauschte Gewichtung: Die
   BEZEICHNUNG stand halbfett, der WERT normal. Wer eine Akte überfliegt,
   sucht aber den Wert — „VD10001-2608", „Hoffmann & Partner", eine IBAN. Die
   Bezeichnung daneben weiß er ohnehin; sie ist die Landkarte, nicht das Ziel.

   Umgedreht: Die Bezeichnung wird leicht und bleibt klein und grau, der Wert
   bekommt Gewicht und eine Stufe mehr Größe. Der Unterschied trägt jetzt drei
   Merkmale — Größe, Farbe, Strichstärke —, und beim Überfliegen springt das
   Auge von Wert zu Wert statt Zeile für Zeile zu lesen. */
.stammfeld .bez {
    font-size: 0.75rem;
    color: var(--hilfstext);
    font-weight: 400;
}

.stammfeld .wert {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
    overflow-wrap: break-word;
    line-height: 1.35;
}

/* ══════════════════════════════════════════════════════════════════════════
   Listen in Karten
   ══════════════════════════════════════════════════════════════════════════ */

ul.punkte,
ul.verlauf,
ul.unterlagen {
    list-style: none;
    margin: 0;
    padding: 0;
}

ul.punkte li,
ul.verlauf li,
ul.unterlagen li {
    padding: var(--a2) 0;
    border-bottom: 1px solid var(--linie-zart);
    font-size: 0.875rem;
}

ul.punkte li:last-child,
ul.verlauf li:last-child,
ul.unterlagen li:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

ul.punkte a,
ul.unterlagen a {
    font-weight: 600;
}

.wann {
    color: var(--hilfstext);
}

/* ── Die internen Notizen als Zeitstrahl ──

   Das DEH am 18.09.2026: „Sie sind recht unübersichtlich, mach etwas mehr
   Platz zwischen 2 Notizen etwa. Und vielleicht findest du eine
   übersichtlichere Darstellungsweise."

   Vorher trennte die Notizen nur eine haarfeine Linie, und Zeitstempel und
   Text standen im selben Fluss. Bei fünf Notizen war nicht zu sehen, wo eine
   anfing. Drei Fassungen wurden gerendert und vorgelegt (mehr Luft, Karten,
   Zeitstrahl); gewählt wurde der Zeitstrahl: Er trennt so deutlich wie die
   Karten und kostet weniger Höhe.

   Die Regeln hängen an `.notizen` und nicht an `.verlauf`: Dieselbe Klasse
   trägt die Vertragsfassungen und die Statuswechsel, und das sind Einzeiler.

   Keine Hausfarbe. app/stil.css setzt sie an acht Stellen, und
   tests/test_gestaltung.php lässt keine neunte zu. */
ul.verlauf.notizen {
    position: relative;
    margin-left: 0.4rem;
    padding-left: 1.4rem;
    border-left: 2px solid var(--linie);
}

ul.verlauf.notizen li {
    position: relative;
    padding: 0 0 var(--a5) 0;
    border-bottom: 0;
}

ul.verlauf.notizen li:last-child {
    padding-bottom: 0;
}

/* Der Punkt auf der Linie. `box-shadow` statt eines Rahmens: Er deckt die
   Linie hinter dem Punkt ab, ohne dass der Punkt selbst grösser wird. */
ul.verlauf.notizen li::before {
    content: '';
    position: absolute;
    left: -1.83rem;
    top: 0.45rem;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--text-gedaempft);
    box-shadow: 0 0 0 3px var(--grund);
}

/* Zeitpunkt und Verfasser über den Text, nicht davor. Sie sind die
   Überschrift der Notiz; im selben Fluss lasen sie sich wie ihr Anfang. */
ul.verlauf.notizen .wann {
    display: block;
    margin-bottom: 0.3rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text-gedaempft);
}


/* Aufzählung ohne eigene Klasse: die Liste „Kommt noch" auf der Startseite.
   Sie soll ruhig aussehen — es sind Dinge, die es noch nicht gibt. */
.karte > ul:not([class]) {
    padding-left: 1.1rem;
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.7;
    color: var(--text-gedaempft);
}

/* Der erklärende Satz darüber gehört nicht an die Liste geklebt. */
.karte > .leer + ul:not([class]) {
    margin-top: var(--a3);
}

.geschaeft {
    border-bottom: 1px solid var(--linie-zart);
    padding-bottom: var(--a4);
    margin-bottom: var(--a4);
}

.geschaeft:last-child {
    border-bottom: 0;
    padding-bottom: 0;
    margin-bottom: 0;
}

/* Bearbeitungsstand und Partner-Nummer auf der Startseite. */
.stand {
    font-size: 0.9375rem;
    margin: 0 0 var(--a2);
}

.nummer {
    font-size: 0.875rem;
    color: var(--hilfstext);
    margin: 0 0 var(--a4);
}

/* ══════════════════════════════════════════════════════════════════════════
   Tabellen
   ══════════════════════════════════════════════════════════════════════════ */

table {
    width: 100%;
    border-collapse: collapse;
    background: var(--grund);
    border: var(--kante);
    border-radius: var(--radius);
}

th,
td {
    text-align: left;
    padding: 0.6rem 0.9rem;
    font-size: 0.875rem;
    border-bottom: 1px solid var(--linie);
    vertical-align: top;
}

th {
    background: var(--flaeche-still);
    font-weight: 600;
    font-size: 0.8125rem;
    color: var(--text-gedaempft);
    white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════════
   Dichte Tabellen
   ══════════════════════════════════════════════════════════════════════════

   Entschieden am 18.08.2026 zur Auftragsliste: Die Schrift darf gerne um 1
   oder 2 pt kleiner sein, damit hier mehr Angaben hineinpassen.

   Zwei Punkte weniger sind rund 0,125rem: aus 14px werden 12px, aus 13px
   werden 11px. Dazu engere Innenabstände — die kosten mehr Breite als die
   Schrift.

   Die Klasse gilt NUR dort, wo sie gesetzt wird. Das ganze Portal kleiner zu
   setzen wäre die einfachere Änderung und die falsche: Eine Kundenakte mit
   acht Feldern braucht keine gedrängte Schrift, eine Auftragsliste mit acht
   Spalten schon. */

table.dicht th,
table.dicht td {
    font-size: 0.75rem;
    padding: 0.4rem 0.55rem;
}

table.dicht th {
    font-size: 0.6875rem;
}

/* Die Zweitzeile in einer Zelle — Nummer, Datum, Begründung — wird
   mitverkleinert, sonst überragt sie den Hauptwert. */

table.dicht .wann {
    font-size: 0.6875rem;
}

tbody tr:last-child td {
    border-bottom: 0;
}

tbody tr:hover td {
    background: #fafafa;
}

td a {
    font-weight: 600;
    text-decoration: none;
}

td a:hover {
    text-decoration: underline;
}

/* Die Partner-Nummer ist eine Kennung, kein Fließtext: Sie steht so im
   unterschriebenen Vertrag und wird als Ganzes gesucht. Sichtbar wurde der
   Umbruch mit der dritten Vertragsart — „Overhead-Vertriebspartner" ist die
   breiteste Beschriftung der Prüfliste, drückt die Nummernspalte schmal, und
   aus OD10002-2608 wurden zwei Zeilen. */
td.nummer {
    white-space: nowrap;
}

/* Ein Geldbetrag in einer Tabelle ist der Wert, den man sucht — nicht die
   Beiläufigkeit, als die .nummer ihn zeichnet (0.875rem, grau).
   .nummer ist ursprünglich für kleine Kennnummern gedacht (Partner-Nummer
   unter einer Überschrift) und wurde für Geldspalten mitbenutzt, weil sie
   auch rechtsbündig sein sollten. Beides unter einem Namen zu führen ist der
   Grund, warum die Beträge des Abrechnungslaufs am 17.08.2026 blass
   ankamen — dieselbe Beobachtung wie bei .stammfeld: Wer eine Aufstellung
   überfliegt, sucht den Wert.

   Dieselbe Regel für die Summenzeile unter einer Tabelle. */
td.nummer,
.stand .nummer {
    color: var(--text);
    font-size: inherit;
}

/* Die eine große Zahl einer Seite: der Kontostand, die Laufsumme. Sie steht
   für sich und trägt deshalb Gewicht statt Grauton. */
.betrag-gross {
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--text);
    margin: 0 0 var(--a3);
}

.keine-nummer {
    color: var(--hilfstext);
    font-weight: 400;
}

/* Eine offene Aufgabe des DEH in einer Listenzeile: Diesem Partner fehlt eine
   Angabe, die für die Auszahlung gebraucht wird. Gebaut wie „.zustand.fehlt"
   — dieselbe Form wie die Meldebänder, nur klein — aber ohne dessen
   Blockabstand: In einer Tabellenzelle zöge der die ganze Zeile auseinander.
   Bewusst kein rotes Wort, sondern ein Feld; rote Schrift verwechselt sich in
   dieser Gestaltung mit der Hausfarbe. */
.offen {
    display: inline-block;
    background: var(--warnung-flaeche);
    border-left: 3px solid var(--warnung-kante);
    border-radius: var(--radius);
    padding: 0.15rem 0.5rem;
    color: var(--text-gedaempft);
    font-size: 0.8125rem;
}

/* Die Kundenliste führt bis zu sieben Spalten und lässt sich nicht sinnvoll
   stapeln (der werbende Partner gehört neben den Kunden, nicht darunter).
   Sie schiebt deshalb sich selbst statt der ganzen Seite: Der Kasten rollt,
   der Seitenkörper bleibt stehen. */
.rollkasten {
    overflow-x: auto;
}

.rollkasten table {
    min-width: 34rem;
}

/* ══════════════════════════════════════════════════════════════════════════
   Der Zustand einer Unterlage
   ══════════════════════════════════════════════════════════════════════════ */

.zustand {
    font-size: 0.875rem;
    margin: 0 0 var(--a4);
    color: var(--text-gedaempft);
}

/* „fehlt" stand bisher in der Fehlerfarbe — als einziges rotes Wort der
   Seite, und damit genau die Verwechslung mit der Hausfarbe, die diese
   Gestaltung vermeidet. Es ist jetzt ein Feld statt eines roten Wortes:
   dieselbe Form wie die Meldebänder, nur klein. */
.zustand.fehlt {
    display: inline-block;
    background: var(--fehler-flaeche);
    border-left: 3px solid var(--fehler-kante);
    border-radius: var(--radius);
    padding: 0.15rem 0.5rem;
    color: var(--text-gedaempft);
    font-size: 0.8125rem;
}

/* ── „vorhanden" und „entfällt" (04.10.2026) ──

   Die beiden anderen Antworten auf dieselbe Frage, in derselben Form wie
   „fehlt". „Vorhanden" trägt die Erfolgsfarbe wie .vollstaendig in der
   Partnerliste. „Entfällt" bewusst NICHT: Eine Unterlage, die es nicht gibt,
   ist erledigt, aber nicht da — der stille Grauton sagt „hier ist nichts zu
   tun", ohne „alles da" zu behaupten. Dieselbe Abwägung wie bei
   .nichts-offen. */
.zustand.vorhanden,
.zustand.entfaellt {
    display: inline-block;
    border-radius: var(--radius);
    padding: 0.15rem 0.5rem;
    color: var(--text-gedaempft);
    font-size: 0.8125rem;
}

.zustand.vorhanden {
    background: var(--erfolg-flaeche);
    border-left: 3px solid var(--erfolg-kante);
}

.zustand.entfaellt {
    background: var(--flaeche);
    border-left: 3px solid var(--hilfstext);
}

/* Die drei Nachweise in der Akte: Name, Zustand, Handgriff. Auf dem Telefon
   rutscht alles untereinander, auf breiten Fenstern steht der Zustand neben
   dem Namen. */
ul.nachweise {
    list-style: none;
    margin: 0 0 var(--a4);
    padding: 0;
}

ul.nachweise > li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--a2);
    padding: var(--a2) 0;
    border-bottom: 1px solid var(--linie-zart);
    font-size: 0.875rem;
}

ul.nachweise > li:last-child {
    border-bottom: 0;
}

ul.nachweise .nachweis-name {
    font-weight: 600;
    min-width: 12rem;
}

ul.nachweise .zustand {
    margin: 0;
}

/* „vermerkt von … am …" steht neben dem Zustand, nicht als eigener Absatz. */
ul.nachweise .hinweis {
    margin: 0;
    font-size: 0.8125rem;
}

/* Zurücknehmen ist ein Handgriff am Rand, kein Hauptweg der Karte: der
   zweitrangige Knopf, eine Stufe kleiner. */
ul.nachweise .nachweis-form button {
    font-size: 0.8125rem;
    padding: 0.3rem 0.75rem;
}

/* Handgriff und Hinweis beginnen eine eigene Zeile unter dem Namen. */
ul.nachweise details,
ul.nachweise .nachweis-form,
ul.nachweise .nachweis-ueberholt {
    flex-basis: 100%;
    margin: 0;
}

ul.nachweise details > summary {
    cursor: pointer;
    font-size: 0.8125rem;
    color: var(--hilfstext);
    text-decoration: underline;
}

ul.nachweise details[open] > summary {
    margin-bottom: var(--a2);
}

ul.nachweise details .feld input {
    width: 100%;
    max-width: 32rem;
}

/* ── Eine Vertragsfassung löschen (07.10.2026) ──
   Wie „Gibt es nicht" bei den Nachweisen: ein leiser Verweis, der erst auf
   Klick das Formular zeigt. Das Formular selbst steht auf der Fehlerfläche,
   wie der Storno einer Abrechnung — es lässt sich nicht zurücknehmen. */
ul.verlauf details.fassung-loeschen {
    margin-top: var(--a2);
}

ul.verlauf details.fassung-loeschen > summary {
    cursor: pointer;
    font-size: 0.8125rem;
    color: var(--hilfstext);
    text-decoration: underline;
}

ul.verlauf details.fassung-loeschen[open] > summary {
    margin-bottom: var(--a2);
}

ul.verlauf details.fassung-loeschen form {
    background: var(--fehler-flaeche);
    border-radius: var(--radius);
    padding: var(--a4);
    max-width: 36rem;
}

ul.verlauf details.fassung-loeschen .zusatz {
    margin-top: 0;
}

ul.verlauf details.fassung-loeschen label.bestaetigen {
    display: flex;
    gap: var(--a2);
    align-items: center;
    margin: var(--a4) 0 0;
}

.nachweis-verlauf {
    font-size: 0.8125rem;
    color: var(--hilfstext);
    margin: 0 0 var(--a4);
}

.nachweis-verlauf > summary {
    cursor: pointer;
}

.nachweis-verlauf ul {
    margin: var(--a2) 0 0;
    padding-left: 1.1rem;
}

/* Die Zwischenüberschrift über der Dateiliste, im Ton der Fachüberschriften
   der Aufgabenliste: leiser als die Kartenüberschrift. */
.karte h4.unterlagen-dateien {
    font-family: var(--schrift-text);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-gedaempft);
    margin: var(--a4) 0 var(--a2);
}

/* Unter „vollständig" stehen die Vermerke in einer eigenen Zeile. */
.entfaellt-zeile {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-top: 0.25rem;
}

/* In der Spalte „Was fehlt": eine als „gibt es nicht" vermerkte Unterlage.
   Dieselbe Marke wie .offen, im stillen Ton von .zustand.entfaellt. */
.entfaellt-marke {
    display: inline-block;
    background: var(--flaeche);
    border-left: 3px solid var(--hilfstext);
    border-radius: var(--radius);
    padding: 0.15rem 0.5rem;
    color: var(--hilfstext);
    font-size: 0.8125rem;
}

/* ══════════════════════════════════════════════════════════════════════════
   Merker an einer Überschrift  (Mediathek: Freigabe und Verschwundenes)
   ══════════════════════════════════════════════════════════════════════════

   Ein kurzes Wort neben dem Namen der Kategorie, nicht darüber und nicht in
   einer eigenen Zeile: Der Innendienst öffnet die Seite, um den einen neuen
   Ordner von gestern Nacht zu finden. Er soll ihn im Vorbeischauen sehen.

   Dieselbe Form wie `.zustand.fehlt` — Fläche mit Kante links, klein, in der
   gedämpften Schriftfarbe. Rote Wörter gibt es in diesem Portal nicht; die
   Hausfarbe ist rot, und ein rotes Wort neben einer roten Marke liest sich
   als Zierde statt als Warnung. */
.merker {
    display: inline-block;
    vertical-align: middle;
    margin-left: 0.5rem;
    padding: 0.1rem 0.45rem;
    border-radius: var(--radius);
    font-family: var(--schrift-text);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--text-gedaempft);
    white-space: nowrap;
}

/* Noch nicht freigegeben: ein Hinweis, keine Störung. Die Kategorie ist in
   Ordnung, sie wartet nur auf eine Entscheidung. */
.merker-neu {
    background: var(--warnung-flaeche);
    border-left: 3px solid var(--warnung-kante);
}

/* Aus der Quelle verschwunden: hier ist etwas passiert, das jemand
   nachsehen sollte. */
.merker-weg {
    background: var(--fehler-flaeche);
    border-left: 3px solid var(--fehler-kante);
}

/* ══════════════════════════════════════════════════════════════════════════
   Seiten ohne Kopfzeile: Anmeldung, Zweitfaktor, Registrierung, Bestätigung
   ══════════════════════════════════════════════════════════════════════════

   Diese vier Seiten sind eine einzelne Karte in der Bildmitte. Über ihr steht
   das Logo, größer als in der Kopfzeile — es ist auf diesen Seiten das
   Einzige, was sagt, wo man ist. */

body.mitte {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    min-height: 100vh;
    gap: var(--a5);
    /* Der Abstand nach oben ist fest und hängt am Fenster, nicht an der Höhe
       des Inhalts — die Begründung steht beim zweiten Vorkommen weiter
       unten, bei der Erklärung, warum der Freiraum nicht verteilt wird. */
    padding: clamp(var(--a5), 18vh, 16rem) var(--a4) var(--a5);
}

.marke-gross {
    display: block;
    flex: 0 0 auto;
    height: 2.5rem;
    width: auto;
}

:is(body.mitte, .anmeldung-seite) form,
:is(body.mitte, .anmeldung-seite) .karte {
    background: var(--grund);
    border: var(--kante);
    border-radius: var(--radius);
    padding: var(--a6);
    width: min(30rem, 100%);
    margin: 0;
}

/* Anmeldung und Zweitfaktor tragen zwei Felder, kein Formular über acht
   Gruppen — sie bleiben schmal. */
:is(body.mitte, .anmeldung-seite) form.schmal {
    width: min(24rem, 100%);
}

/* Der Abstand nach oben ist FEST und hängt am Fenster, nicht am Inhalt.

   ── Warum nicht mittig ──

   Geometrisch mittig sieht zu tief aus: Das Auge setzt die Mitte einer
   Fläche höher an, als sie liegt. Bei 1400 auf 1371 gemessen stand der
   Anmeldeblock exakt mittig (Blockmitte 677, Fenstermitte 685) und wirkte
   trotzdem, als sei er nach unten gerutscht.

   ── Warum der Freiraum nicht mehr verteilt wird ──

   Der erste Anlauf verteilte ihn im Verhältnis 4 zu 6 über zwei
   Abstandshalter. Das saß richtig, hatte aber eine Eigenschaft, die das DEH
   als Sprung gemeldet hat: Bei verteiltem Freiraum hängt die OBERKANTE an
   der Höhe des Inhalts. Wird der Block einen Deut höher oder niedriger —
   eine Fehlermeldung erscheint, ein Passwortmanager legt seine Leiste ins
   Feld, der Browser füllt aus —, wandert das Logo mit. Es rutscht um 40
   Prozent der Änderung, in die eine oder andere Richtung.

   Nachgemessen wurde vorher, woran es NICHT liegt: Von 450 bis 1400 Pixeln
   Fensterhöhe sitzt der Block stabil bei 40 bis 46 Prozent, ohne Überlauf,
   und der Fokus ändert die Höhe nicht (die Fokusregeln setzen outline und
   border-color, beides ohne Einfluss auf das Layout). Übrig bleibt: etwas
   verändert die Höhe des Inhalts.

   Mit festem Abstand nach oben ist das gleichgültig. Die Oberkante steht,
   wo sie steht; was hinzukommt, wächst nach unten. Das ist genau die
   Zusage, um die es geht — „er soll an der gleichen Stelle bleiben".

   ── Warum clamp und nicht schlicht 18vh ──

   Bei einem niedrigen Fenster wären 18 Prozent Luft über einem langen
   Registrierungsformular verschenkter Platz, bei einem sehr hohen wüchse
   der Abstand ins Alberne. Die untere Grenze ist der übliche Seitenrand,
   die obere sechzehn Zeilen. Dazwischen wandert der Abstand mit dem
   Fenster.

   justify-content: center wäre hier weiterhin falsch: Ist der Inhalt höher
   als das Fenster, schöbe es ihn oben aus dem Bild, und die ersten Felder
   des Registrierungsformulars wären nicht mehr erreichbar. Ein
   padding-top tut das nie. */
/* (Die Werte stehen oben in der Grundregel; hier steht nur, warum.) */

:is(body.mitte, .anmeldung-seite) h1 {
    font-family: var(--schrift-titel);
    font-size: 1.375rem;
    font-weight: 400;
    line-height: 1.25;
    margin: 0 0 var(--a4);
}

/* Die Abschnittsüberschriften im Registrierungsformular trennen acht Gruppen
   voneinander; eine Linie darüber macht die Gruppe sichtbar. */
:is(body.mitte, .anmeldung-seite) h2 {
    font-family: var(--schrift-titel);
    font-size: 1.0625rem;
    font-weight: 400;
    margin: var(--a5) 0 var(--a3);
    padding-top: var(--a4);
    border-top: var(--kante);
}

:is(body.mitte, .anmeldung-seite) h2:first-of-type {
    border-top: 0;
    padding-top: 0;
    margin-top: var(--a4);
}

:is(body.mitte, .anmeldung-seite) button {
    width: 100%;
    margin-top: var(--a2);
}

/* Der Rückweg unter dem Knopf (16.09.2026, Rückfrage vor dem Abmelden).

   Er trägt eine eigene Klasse und fällt damit absichtlich aus der Regel für
   die Fließtextabsätze darunter: Dort sitzt der Abstand UNTER dem Absatz,
   weil der Absatz dort ein Vorspann ist. Hier ist es umgekehrt — der Absatz
   steht hinter dem Knopf und braucht Luft darüber, nicht darunter.

   Mittig, weil er unter einem Knopf steht, der die ganze Breite einnimmt.
   Linksbündig läse er sich als Beschriftung eines Feldes, das es nicht gibt. */
:is(body.mitte, .anmeldung-seite) .zurueck {
    margin: var(--a4) 0 0;
    text-align: center;
    font-size: 0.875rem;
}

/* Die Fließtextabsätze der Karte — und ausdrücklich nur die unmittelbaren:
   Im Fehlerband steht ebenfalls ein klassenloses <p> („Bitte prüfen:"), und
   ohne das Kindzeichen gewänne diese Regel gegen .fehler p und risse einen
   Absatz Abstand zwischen Vorspann und Liste. So gemessen. */
:is(body.mitte, .anmeldung-seite) > form > p:not([class]),
:is(body.mitte, .anmeldung-seite) > .karte > p:not([class]) {
    font-size: 0.875rem;
    line-height: 1.55;
    margin: 0 0 var(--a4);
}

/* Das Geheimnis für die Authenticator-App: in Ziffernbreite, damit sich
   0 und O beim Abtippen nicht verwechseln. */
code {
    font-family: var(--schrift-ziffern);
    background: var(--flaeche-still);
    padding: 0.35rem 0.5rem;
    border-radius: var(--radius);
    letter-spacing: 0.08em;
    display: inline-block;
    word-break: break-all;
    font-size: 0.875rem;
}

/* Ein Befehl zum Abtippen (Prüfliste, Zahlungsdatei ohne Buchung): bricht an
   den Leerzeichen, nicht mitten in „--verwerfen". `break-all` von oben ist für
   das Geheimnis richtig, hier machte es aus einem Schalter zwei halbe. */
code.befehl {
    word-break: normal;
    overflow-wrap: anywhere;
    letter-spacing: 0;
}
/* Ein Schalter bricht nie nach seinen Strichen: „--" am Zeilenende und
   „verwerfen" darunter wird als zwei Wörter abgetippt. */
code.befehl span {
    white-space: nowrap;
}

/* Der QR-Code auf der Zweitfaktor-Seite.

   Er ist ein <img> mit einer data:-Adresse; die Ruhezone von vier Modulen und
   die Farben stecken im SVG selbst (app/lib/Qr.php). Hier steht nur, wie groß
   er wird und wo er sitzt.

   16rem sind 256 Pixel. Auf dem schmalsten Ziel — 390 Pixel Fensterbreite,
   Karte min(24rem, 100%) = 384 Pixel, davon 2 x 24 Pixel Polsterung — bleiben
   336 Pixel Innenmaß; der Code passt also mit Abstand hinein und bleibt
   trotzdem groß genug, dass eine Telefonkamera ihn vom Bildschirm liest. Bei
   Version 8, dem Fall im Portal, sind das 49 Module plus 8 Module Ruhezone
   auf 256 Pixel, also gut 4 Pixel je Modul. Unter etwa 2 Pixel wird es
   unzuverlässig, darüber ist Reserve.

   background und forced-color-adjust gehören zusammen: Ein QR-Code braucht
   dunkel auf hell. Das SVG bringt seinen weißen Grund mit, aber im
   Zwangsfarbmodus (Windows-Kontrastdarstellung) ersetzt der Browser
   Hintergründe durch die Systemfarben — ein Code auf schwarzem Grund wäre
   nicht mehr lesbar. forced-color-adjust: none nimmt genau dieses eine
   Element davon aus. Das ist keine Geschmacksfrage: Ein umgefärbter oder
   invertierter QR-Code wird von einem Teil der Lesegeräte gar nicht erkannt.

   Deshalb stehen die beiden Farben auch nicht als Variable hier, sondern fest
   im Bild: Was das Stilblatt nicht setzt, kann kein Farbschema umdrehen. */
.qr {
    display: block;
    width: min(16rem, 100%);
    height: auto;
    margin: 0 auto var(--a4);
    background: #ffffff;
    forced-color-adjust: none;
}

/* Das Eingabefeld für den sechsstelligen Code: groß, gesperrt, mittig. */
.code-eingabe {
    font-size: 1.35rem;
    letter-spacing: 0.3em;
    text-align: center;
    margin: var(--a3) 0 var(--a4);
}

/* ══════════════════════════════════════════════════════════════════════════
   Schmale Fenster
   ══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════
   „DEH Lupe" (04.10.2026, Paul wählt Entwurf B)
   ══════════════════════════════════════════════════════════════════════════
   Kopfzeile: Logo, feine Trennlinie, kleine Lupe, „Lupe" in der Titelschrift.
   Anmeldung: zweigeteilt, links eine dunkelblaue Bühne mit der Lupe. Das
   Silber der Lupe trägt nur auf dunklem Grund; auf Hellgrau verlor es den
   Glanz (Entwurf A, gerendert und verworfen). */
header h1 a.kopfmarke {
    display: flex;
    align-items: center;
    gap: var(--a3);
    text-decoration: none;
    color: var(--tief);
}

header h1 .trenner {
    width: 1px;
    align-self: stretch;
    background: #d6d6d6;
}

header h1 img.lupe-klein {
    height: 2.25rem;
    filter: drop-shadow(0 1px 2px rgba(13, 27, 42, 0.25));
}

/* Die Farbe steht ausdrücklich da: „header span" färbt die Benutzerzeile
   grau, und das Wort ist ebenfalls ein span. */
header h1 .lupe-wort {
    color: var(--tief);
    font-family: var(--schrift-titel);
    font-size: 1.25rem;
    line-height: 1;
}

header h1 .lupe-wort small {
    display: block;
    font-family: var(--schrift-text);
    font-size: 0.625rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--hilfstext);
    margin-top: 3px;
}

body.anmeldung {
    margin: 0;
    min-height: 100vh;
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    background: var(--grund);
}

.buehne {
    background: radial-gradient(120% 90% at 30% 25%, #1d3550 0%, var(--tief) 60%, #08121c 100%);
    color: #fff;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: var(--a4);
    padding: var(--a6);
    overflow: hidden;
    /* Das Registrierungsformular ist viele Bildschirme lang; die Bühne
       bleibt beim Scrollen stehen, statt nach oben wegzulaufen. */
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
}

.buehne img {
    width: min(30rem, 80%);
    height: auto;
    transform: rotate(-6deg);
    filter: drop-shadow(0 30px 40px rgba(0, 0, 0, 0.55)) drop-shadow(0 4px 8px rgba(0, 0, 0, 0.4));
}

.buehne p {
    margin: 0;
}

.buehne .lupe-name {
    font-family: var(--schrift-titel);
    font-size: 2.75rem;
    line-height: 1;
}

.buehne .lupe-unter {
    font-size: 0.75rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.65);
}

/* Fester Abstand nach oben statt Zentrierung, aus demselben Grund wie bei
   body.mitte (Begründung dort): Zentriert sprang das Logo um 34 Pixel, sobald
   eine Fehlermeldung erschien oder der Passwortmanager seine Leiste zeigte.
   Befund des Kontroll-Subagenten, gemessen am 04.10.2026. */
.anmeldung-seite {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    gap: var(--a5);
    padding: clamp(var(--a5), 18vh, 16rem) var(--a5) var(--a6);
}

body.anmeldung .anmeldung-seite .marke-gross {
    height: 2.25rem;
}

/* Rechts neben der Bühne steht der Inhalt auf Weiß, ohne Kartenrahmen: Ein
   Rahmen auf weißer Fläche wäre eine Linie ohne Aufgabe. Die Breiten kommen
   weiter aus den Regeln für body.mitte (schmal 24rem, sonst 30rem). Die
   Gewichtung body.anmeldung … steht da, weil die geteilten Regeln
   :is(body.mitte, .anmeldung-seite) schwerer wiegen als eine einzelne Klasse. */
body.anmeldung .anmeldung-seite :is(form, .karte) {
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
}

body.anmeldung .anmeldung-seite h1 {
    font-family: var(--schrift-titel);
    font-size: 1.5rem;
    font-weight: 400;
    line-height: 1.25;
    margin: 0 0 var(--a4);
}

body.anmeldung .anmeldung-seite button {
    width: 100%;
    margin-top: var(--a2);
}

body.anmeldung .anmeldung-seite .zurueck {
    margin: var(--a4) 0 0;
    text-align: center;
    font-size: 0.875rem;
}

@media (max-width: 800px) {
    body.anmeldung {
        grid-template-columns: 1fr;
        grid-template-rows: auto 1fr;
    }

    .buehne {
        position: static;
        height: auto;
        flex-direction: row;
        padding: var(--a5) var(--a4);
    }

    .buehne img {
        width: 7.5rem;
    }

    .buehne .lupe-name {
        font-size: 1.875rem;
    }

    .buehne .lupe-unter {
        font-size: 0.625rem;
    }

    .anmeldung-seite {
        padding: var(--a5) var(--a4);
    }
}

@media (max-width: 640px) {
    header {
        padding: var(--a3) var(--a4);
    }

    header h1 img {
        height: 1.5rem;
    }

    header h1 img.lupe-klein {
        height: 1.875rem;
    }

    header h1 .lupe-wort {
        font-size: 1.0625rem;
    }

    header h1 .lupe-wort small {
        display: none;
    }

    main {
        padding: var(--a4);
    }

    main > h2 {
        font-size: 1.3125rem;
    }

    .karte {
        padding: var(--a4);
    }

    :is(body.mitte, .anmeldung-seite) form,
    :is(body.mitte, .anmeldung-seite) .karte {
        padding: var(--a5);
    }

    .marke-gross {
        height: 2rem;
    }
}

@media (max-width: 480px) {
    .stamm {
        grid-template-columns: 1fr;
    }
}

/* ── Die Partnerliste auf dem Telefon ──
   Unter 640 Pixeln wird aus jeder Tabellenzeile eine Karte. Eine Tabelle, die
   seitlich aus dem Bild läuft, ist auf einem Telefon keine Auskunft. Die
   Beschriftung kommt aus data-label im Markup. */
@media (max-width: 640px) {
    table.gestapelt,
    table.gestapelt thead,
    table.gestapelt tbody,
    table.gestapelt th,
    table.gestapelt td,
    table.gestapelt tr {
        display: block;
        width: 100%;
    }

    /* ── Die Mindestbreite muss hier weg (08.09.2026) ──
       `.rollkasten table { min-width: 34rem }` weiter oben zwingt jede
       Tabelle im Rollkasten auf 544 Pixel. Das ist für eine schiebbare
       Tabelle richtig — aber `gestapelt` löst sie hier gerade in Karten auf,
       und dann kämpfen die beiden Regeln gegeneinander. Gewonnen hat die
       Mindestbreite: In der Kundenliste standen auf einem 390 Pixel breiten
       Telefon „Steinberger Immo…" und „Lutz Vermögensbe…" — abgeschnitten,
       und was rechts stand, sah niemand.

       `width: 100%` allein reicht nicht: min-width schlägt width. */
    .rollkasten table.gestapelt {
        min-width: 0;
    }

    table.gestapelt {
        border: 0;
        background: transparent;
    }

    table.gestapelt thead {
        position: absolute;
        left: -9999px;
        top: -9999px;
    }

    table.gestapelt tbody tr {
        background: var(--grund);
        border: var(--kante);
        border-radius: var(--radius);
        margin-bottom: var(--a3);
    }

    table.gestapelt tbody tr:last-child {
        margin-bottom: 0;
    }

    table.gestapelt td {
        border-bottom: 1px solid var(--linie-zart);
        padding: 0.45rem 0.9rem 0.45rem 44%;
        position: relative;
        min-height: 1.4rem;
    }

    table.gestapelt td:last-child {
        border-bottom: 0;
    }

    table.gestapelt td::before {
        content: attr(data-label);
        position: absolute;
        left: 0.9rem;
        width: 38%;
        font-weight: 600;
        font-size: 0.75rem;
        color: var(--hilfstext);
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   Setting-Gespräche in der Bitrix-Akte
   ══════════════════════════════════════════════════════════════════════════

   Mehrere Gespräche untereinander in EINER Karte. Die Trennung übernimmt eine
   Linie, keine eigene Karte je Gespräch: Fünf Karten hintereinander lesen
   sich wie fünf verschiedene Themen, dabei ist es die Vorgeschichte eines
   einzigen Menschen.

   Die Linie steht oben und nicht unten, damit das letzte Gespräch nicht mit
   einem Strich ins Leere endet. */
.gespraech + .gespraech {
    margin-top: var(--a5);
    padding-top: var(--a5);
    border-top: 1px solid var(--linie);
}

.gespraech-kopf {
    margin-bottom: var(--a4);
}

/* Die zugeklappte Notiz. Ein Kommentar hat bis zu 9634 Zeichen; offen
   nebeneinander machen drei davon die Seite unlesbar. Zugeklappt ist die
   Zusammenfassung ein Link-artiger Hinweis, der sich anklicken lässt. */
.gespraech details {
    margin-top: var(--a4);
}

.gespraech details > summary {
    cursor: pointer;
    text-decoration: underline;
}

.gespraech details > p {
    margin-top: var(--a4);
    padding-left: var(--a4);
    border-left: 2px solid var(--linie);
    line-height: 1.5;
}


/* ══════════════════════════════════════════════════════════════════════════
   Das Kennzahlenband und die Bereichszeilen der Startseite
   ══════════════════════════════════════════════════════════════════════════

   Entschieden am 20.08.2026: Auch die Gruppierung der Buttons muss aufgeräumter
   werden, das ist alles sehr unübersichtlich. Mach es leichter intuitiv
   fassbarer. Oben gehören Kacheln mit KPIs hin.

   Vorher standen fünf gleich aussehende Karten untereinander, in jeder eine
   Reihe gefüllter schwarzer Knöpfe. „Passwort ändern" wog damit optisch so
   schwer wie „Alle Partner", und nirgends stand eine Zahl. Jetzt trägt jede
   Bereichszeile GENAU EINEN gefüllten Knopf — die Handlung, die man dort am
   häufigsten braucht —, alles andere sind Textlinks.

   Der Entwurf ist die Fassung B vom 20.08.2026, vom DEH ausgewählt. */

/* ══════════════════════════════════════════════════════════════════════════
   Der Aufgabenkasten (Entwurf C, gewählt am 26.08.2026)
   ══════════════════════════════════════════════════════════════════════════

   Er steht ÜBER dem Kennzahlenband und trägt als einziger Block der Seite
   eine farbige Fläche. Das ist der ganze Punkt: Wer die Startseite öffnet,
   soll zuerst sehen, was liegen geblieben ist. Vorher stand das als kleine
   Kachel links unten im dunklen Band, mit drei leeren Spalten daneben.

   Gibt es nichts zu tun, gibt es diesen Kasten nicht: Die Ansicht rendert
   ihn nur, wenn die Aufgabenkachel `achtung` trägt (app/views/start.php).
   Ein Kasten „Zu tun 0" in Alarmfarbe wäre ein Dauer-Fehlalarm. */
.zutun {
    background: var(--marke-flaeche);
    border-left: 3px solid var(--marke);
    padding: var(--a4) var(--a5);
    margin: 0 0 var(--a3);
    display: flex;
    align-items: center;
    gap: var(--a3) var(--a5);
    flex-wrap: wrap;
}

.zutun .kopf {
    font-family: var(--schrift-titel);
    font-size: 1.125rem;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}

.zutun .zahl {
    font-family: var(--schrift-titel);
    font-size: 1.75rem;
    line-height: 1;
    color: var(--marke);
}

.zutun .wege {
    display: flex;
    gap: 0.6rem;
    flex-wrap: wrap;
    align-items: center;
}

/* Die Knöpfe im Aufgabenkasten sind Gemstone Blue wie überall sonst — nur
   etwas kleiner.

   Der erste Entwurf machte sie rot. Auf der hellen Fläche wirkten zwei große
   rote Knöpfe lauter als die Zahl daneben, und die Hausfarbe stand damit an
   fünf Stellen in einem einzigen Kasten. Rot trägt hier den Anriss und die
   Zahl; das ist die Betonung, alles Weitere nimmt sie zurück. */
.zutun .knopf {
    font-size: 0.875rem;
    padding: 0.45rem 0.9rem;
}

/* ── Die Sinnbilder der Kacheln (app/views/_icons.php) ──
   Sie nehmen die Farbe ihrer Umgebung an (`currentColor`) und sitzen auf der
   Grundlinie der Beschriftung. Deckkraft statt eigener Farbe: Ein zweiter
   Grauton neben dem der Beschriftung wäre eine Farbe mehr, die niemand
   gewählt hat. */
.icon {
    width: 1.05rem;
    height: 1.05rem;
    flex: none;
    vertical-align: -0.18em;
    margin-right: 0.35rem;
    opacity: 0.75;
}

/* Das Sinnbild im Aufgabenkasten steht in voller Deckkraft, aber ohne eigene
   Farbe: Es erbt das Schwarz der Überschrift daneben. */
.zutun .kopf .icon {
    margin-right: 0;
    opacity: 1;
}

.band {
    background: var(--tief);
    color: #fff;
    margin: 0 0 var(--a6);
    padding: var(--a5) var(--a5) var(--a4);
    /* Der rote Balken links, wie an der Seitenüberschrift: die eine Stelle,
       an der die Hausfarbe auftaucht. */
    border-left: 3px solid var(--marke);
}

.band h3 {
    font-family: var(--schrift-text);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.55);
    margin: 0 0 var(--a4);
}

/* So viele Spalten, wie es Kacheln gibt — höchstens vier.

   Feste vier Spalten waren der erste Versuch und der zweite Fehler: Ein
   Vertriebspartner hat drei Bestandskacheln, ein Tippgeber zwei. Bei ihnen
   blieb ein Viertel bzw. die halbe Breite des dunklen Bandes leer — genau
   der Mangel, den der Umbau beim Aufgabenkasten gerade beseitigt hatte
   (zwölfter Kontroll-Subagent, 26.08.2026).

   `auto-fit` mit Mindestbreite wäre der naheliegende Weg und der falsche: Es
   verteilt die Kacheln nach verfügbarem Platz, nicht nach ihrer Anzahl, und
   die Seite sähe je nach Fensterbreite anders aus. `:has()` zählt sie
   stattdessen ab. Die Zeitreihen haben immer vier und brauchen die Abstufung
   nicht. */
.band .reihe,
.band .zeitraeume {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--a4) var(--a5);
}

/* Erst ab Tablettbreite. Auf dem Telefon gelten zwei Spalten für alle Reihen
   (siehe die Regel bei max-width 640px weiter unten) — und die hat als
   einfacher Selektor die SCHWÄCHERE Spezifität. Ohne diese Klammer stünden
   dort drei Spalten à 110 Pixel, in denen „184.500 EUR" nicht mehr steht. */
@media (min-width: 641px) {
    .band .reihe:not(:has(> :nth-child(3))) {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .band .reihe:has(> :nth-child(3)):not(:has(> :nth-child(4))) {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.band .zeitraeume {
    margin-top: var(--a5);
    padding-top: var(--a4);
    border-top: 1px solid rgba(255, 255, 255, 0.16);
    gap: var(--a4);
}

.band .bez {
    display: block;
    font-size: 0.75rem;
    color: rgba(255, 255, 255, 0.6);
    margin-bottom: 0.3rem;
}

.band .zahl {
    display: block;
    font-family: var(--schrift-titel);
    /* 1,5rem statt 1,875: Das Band ist nicht mehr der Hauptdarsteller der
       Seite — das ist der Aufgabenkasten darüber. */
    font-size: 1.5rem;
    line-height: 1.15;
    color: #fff;
}

.band .zeitraeume .zahl { font-size: 1.375rem; }

.band .neben {
    display: block;
    font-size: 0.8125rem;
    color: rgba(255, 255, 255, 0.6);
    margin-top: 0.3rem;
}

/* Alle Werte am 20.08.2026 nachgerechnet, nicht geschätzt: weiß auf diesem
   Grund liegt bei 17,39:1, die Beschriftungen in 60 % Weiß bei 7,15:1, der
   aufgehellte Rotton bei 8,3:1. Die Beschriftungen in 60 % Weiß liegen bei
   6,91:1 — hier stand bis zum 20.08.2026 7,15, und zwar in einem Kommentar,
   der „nachgerechnet, nicht geschätzt" behauptet. */
.band .achtung .zahl { color: var(--marke-hell); }

/* ── Kacheln, hinter denen eine Seite liegt ──
   Eine Zahl, die etwas meldet, aber nirgends hinführt, ist eine Sackgasse.
   Der Link trägt keine eigene Farbe: Auf dem dunklen Grund ist bereits alles
   weiß, und ein zweiter Ton hier hieße, die Kachel zweimal zu betonen. */
a.zelle {
    display: block;
    color: inherit;
    text-decoration: none;
}

/* Die Farbe steht hier ausdrücklich noch einmal. Ohne sie greift die
   allgemeine Regel `a:hover { color: var(--marke) }` weiter oben im Blatt:
   Die Hausfarbe auf Gemstone Blue ergibt 2,06:1 und ist nicht lesbar. Heute
   gewinnt `a.zelle` nur, weil es später steht — wer die Blöcke umsortiert,
   hätte den Fehler zurück. */
a.zelle:hover,
a.zelle:focus {
    color: #fff;
}

a.zelle:hover .zahl {
    text-decoration: underline;
    text-underline-offset: 0.2em;
}


/* Dasselbe für die Wege in der Aufgabenkachel. */
.band .aufgaben a:hover,
.band .aufgaben a:focus {
    color: #fff;
}

/* Ein Weg ohne Ziel: derselbe Platz, kein Link. */
.band .aufgaben span {
    display: block;
    font-size: 0.875rem;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.75);
}

/* ── Die Wege der Aufgabenkachel ──
   Sie stehen IN der Kachel, unter der Zahl. Das geht nur, weil diese eine
   Kachel selbst kein Ziel trägt: Drei Aufgaben führen an drei verschiedene
   Orte, und ein Link in einem Link wäre keiner. */
.band .aufgaben {
    display: block;
    margin-top: 0.4rem;
}

.band .aufgaben a {
    display: block;
    color: #fff;
    font-size: 0.875rem;
    line-height: 1.5;
    text-underline-offset: 0.2em;
}

/* ── Die Zahlen des Hauses ──
   Abgesetzt vom Portalbestand darüber, mit eigener Überschrift. „15 gemeldete
   Kunden" (Portal) und „979 Kunden in Bitrix" sind zwei Zahlen über zwei
   Bestände; untereinander ohne Trennung sähe die eine wie ein Fehler in der
   anderen aus. */
.band .haus {
    margin-top: var(--a5);
    padding-top: var(--a4);
    border-top: 1px solid rgba(255, 255, 255, 0.16);
}

.band .haus h4 {
    font-family: var(--schrift-text);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.55);
    margin: 0 0 var(--a4);
}

.band .haus .zahl { font-size: 1.375rem; }

/* Die Zeiträume des Hauses beginnen eine neue Zeile (05.10.2026). Seit die
   Kachel „Verkaufte Steine" weg ist, stehen davor drei Kacheln; ohne diese
   Regel rückte „Ausgeliefert" in die vierte Spalte und die Monate versetzt
   darunter. */
.band .reihe > .zeilenanfang { grid-column-start: 1; }

/* ── Die Fußzeile unter der Zahlenreihe ──
   Sie sagt, welcher Preis und welcher Zeitpunkt gezählt wurde. 55 % Weiß auf
   diesem Grund ergeben 6,0:1 und liegen damit über der Grenze von 4,5:1. */
.band .fuss {
    margin: var(--a4) 0 0;
    padding-top: var(--a3);
    border-top: 1px solid rgba(255, 255, 255, 0.16);
    font-size: 0.8125rem;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.55);
    max-width: 78ch;
}

/* ══════════════════════════════════════════════════════════════════════════
   Die Bereiche als Karten (Entwurf C, gewählt am 26.08.2026)
   ══════════════════════════════════════════════════════════════════════════

   Vorher: fünf breite Zeilen untereinander, Titel links, Wege rechts, in der
   Mitte ein Drittel leere Fläche. Zwei Bildschirme für fünf Wege.

   Jetzt ein Raster. Der Abstand steht als `gap` am Container und nicht mehr
   an jeder Zeile — die Klammer gibt es seit dem Umbau (app/views/start.php),
   vorher war sie nicht möglich, weil jede Zeile in ihrer eigenen
   Rechteprüfung steckt. */
.bereiche {
    display: grid;
    /* 300 Pixel und nicht 280: Bei 280 stand in einer Karte kein zweiter
       Knopf mehr neben dem ersten, und „Mein Zugang" wurde zu vier Knöpfen
       untereinander. Gemessen an der breitesten Beschriftung, die vorkommt
       („Abrechnungsläufe"). */
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--a3);
    align-items: stretch;
}

.bereich-zeile {
    background: var(--grund);
    border: var(--kante);
    border-left: 3px solid var(--linie);
    padding: var(--a5);
    /* Eine Spalte, keine Zeile: In einer schmalen Karte stünden Text und
       Handlung sonst nebeneinander und beide zu eng. Der Text wächst
       (`flex: 1`), damit die Knöpfe aller Karten einer Reihe auf gleicher
       Höhe sitzen. */
    display: flex;
    flex-direction: column;
    gap: var(--a4);
}

.bereich-zeile > :first-child { flex: 1; }

.bereich-zeile:hover { border-left-color: var(--tief); }

.bereich-zeile h3 {
    font-family: var(--schrift-titel);
    font-size: 1.125rem;
    margin: 0 0 0.15rem;
}

.bereich-zeile .was {
    font-size: 0.8125rem;
    color: var(--hilfstext);
    margin: 0;
    line-height: 1.45;
}

.bereich-zeile .aktionen .knopf {
    font-size: 0.8125rem;
    padding: 0.4rem 0.85rem;
}

.bereich-zeile .aktionen {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
    /* Linksbündig, seit die Bereiche Karten sind. Rechtsbündig war richtig,
       solange Text links und Handlung rechts standen; in einer schmalen
       Karte erzeugt es eine zerrissene Kante. */
    justify-content: flex-start;
}

/* ── Jeder Weg ist ein Knopf (entschieden am 26.08.2026:
   statt Textlinks in den Kacheln Buttons) ──

   Die Rangfolge bleibt: Der Hauptweg trägt `.knopf` und ist gefüllt, alle
   anderen bekommen hier den Umriss. Zwei gefüllte Knöpfe nebeneinander zögen
   das Auge auf den falschen — das war der Grund, warum hier bis heute
   Textlinks standen (Fassung B vom 20.08.2026).

   Die Regel steht an EINER Stelle und nicht an sieben Bereichszeilen im
   Markup. Eine neue Zeile bekommt ihre Knöpfe damit von selbst. */
.bereich-zeile .aktionen a:not(.knopf) {
    display: inline-block;
    font-family: inherit;
    font-size: 0.8125rem;
    padding: 0.4rem 0.75rem;
    border-radius: var(--radius);
    background: var(--grund);
    color: var(--tief);
    border: 1px solid var(--tief);
    text-decoration: none;
    white-space: nowrap;
}

.bereich-zeile .aktionen a:not(.knopf):hover,
.bereich-zeile .aktionen a:not(.knopf):focus {
    background: var(--flaeche);
    color: var(--tief);
}

@media (max-width: 640px) {

    /* Auf dem Telefon zwei Spalten statt einer.
       Mit `auto-fit` und 170px Mindestbreite fiel das Band auf 390px Breite
       in EINE Spalte: neun Kacheln untereinander, rund 1400 Pixel Höhe, und
       die Bereiche darunter begannen erst nach zwei Bildschirmen. Zwei
       Spalten halbieren das. Die Zahlen werden dafür kleiner — 30 Pixel
       Versalhöhe brauchen für „184.500 EUR" mehr Platz, als eine halbe
       Telefonbreite hergibt. */
    .band .reihe,
    .band .zeitraeume {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--a4);
    }

    .band .zahl { font-size: 1.5rem; }
    .band .zeitraeume .zahl { font-size: 1.125rem; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Der Kennzahlenblock (app/views/_kpi.php, 26.08.2026)
   ══════════════════════════════════════════════════════════════════════════

   Er steht in der Partnerakte ganz oben — zuerst gehören dort die
   KPI des jeweiligen Partners hin. Anders als das dunkle Band der
   Startseite ist er eine gewöhnliche Karte: Er trägt hier keine Übersicht
   über das Haus, sondern gehört zu dem Partner, dessen Akte man liest. */
/* Fünf Kacheln, fünf Spalten. Mit `auto-fit` und 180 Pixeln Mindestbreite
   passten nur vier nebeneinander, und die Aktivität stand allein in einer
   zweiten Reihe mit vier leeren Spalten daneben — derselbe Mangel wie im
   Kennzahlenband der Startseite, nur eine Seite weiter. */
.kpi-reihe {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: var(--a4);
    margin-bottom: var(--a5);
}

@media (max-width: 900px) {
    .kpi-reihe { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
    .kpi-reihe { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── Die Wege hinter den Zahlen ──
   Sie stehen zwischen Überschrift und Kacheln und sollen dort nicht mit den
   Zahlen um Aufmerksamkeit kämpfen: kleine Schrift, Hausfarbe, ein Punkt als
   Trenner. */
.kpi-wege {
    margin: calc(-1 * var(--a3)) 0 var(--a4);
    font-size: 0.875rem;
}

.kpi-wege a + a::before {
    content: "·";
    margin: 0 0.5em;
    color: var(--hilfstext);
}

.kpi-zelle .bez {
    display: block;
    font-size: 0.75rem;
    color: var(--hilfstext);
    margin-bottom: 0.2rem;
}

.kpi-zelle .zahl {
    display: block;
    font-family: var(--schrift-titel);
    font-size: 1.5rem;
    line-height: 1.15;
    color: var(--tief);
}

.kpi-zelle .neben {
    display: block;
    font-size: 0.75rem;
    color: var(--hilfstext);
    margin-top: 0.2rem;
    line-height: 1.35;
}

/* Eine Vorhersage, auf die man sich nicht stützen sollte, sagt das auch in
   der Farbe — aber gedeckt und nicht in Alarmrot: Sie ist keine Warnung,
   sondern eine Einschränkung. */
.kpi-zelle .neben.schwach {
    color: var(--warnung-kante);
}

/* Und die Zahl selbst tritt zurück. Eine Hochrechnung aus einem Geschäft im
   Januar ist rechnerisch richtig und als Überschrift eine Behauptung; die
   Einschränkung darunter holt sie nicht ein, wenn sie dreimal so groß
   gesetzt ist. */
.kpi-zelle .zahl.vage {
    font-size: 1.125rem;
    color: var(--hilfstext);
}

/* ── Der Strich zwischen zwei Handgriffen einer Karte ──
   (app/views/zugang.php, 11.09.2026)

   Die Zugangskarte trägt jetzt vier Formulare untereinander: Passwort,
   Zweitfaktor, E-Mail samt Einladung, Löschen. Ohne Trennung liest sich das
   als ein Formular mit vier Knöpfen, und man drückt den falschen.

   Kein `border-top` an den Formularen selbst: Dann hinge der Strich an der
   Reihenfolge, und wer eines verschiebt, verschiebt ihn mit. */
hr.trenner {
    border: 0;
    border-top: 1px solid var(--linie-zart);
    margin: var(--a5) 0 var(--a4);
}

/* ── Der erklärende Satz unter einem Knopf ──
   (app/views/zugang.php, 11.09.2026)

   `.wann` ist ein inline-Element und stand damit NEBEN dem Knopf. Auf dem
   Telefon lief der Satz um den Knopf herum: „Neue Einladung schicken  Geht an
   konstantin@…" in einer Zeile, der Rest darunter, quer durch die Karte.
   Gefunden im ersten Rendering, vor der Auslieferung.

   Nur direkt nach einem Knopf, nicht überall: In einer Tabellenzelle und
   unter einem Eingabefeld steht `.wann` richtig, wo es steht. */
form button + .wann {
    display: block;
    margin-top: 0.4rem;
}

/* Das Löschformular in der Regionenliste steht in einer Tabellenzelle und
   soll dort keinen Absatzabstand mitbringen. */
form.knapp {
    margin: 0;
}

.kpi .karte h4,
.kpi h4 {
    font-family: var(--schrift-titel);
    font-size: 0.9375rem;
    font-weight: 400;
    margin: 0 0 var(--a3);
    padding-top: var(--a4);
    border-top: 1px solid var(--linie-zart);
}

/* ── Die Monatsreihe ──
   Zwölf Balken aus CSS-Höhen. Feste Höhe für den Rahmen, damit die Karte
   nicht springt, wenn ein Monat den Höchstwert übernimmt. */
.kpi-verlauf .balken {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: 0.35rem;
    align-items: end;
    height: 110px;
    margin-bottom: var(--a3);
}

.kpi-verlauf .balken-spalte {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    height: 100%;
    min-width: 0;
}

.kpi-verlauf .balken-saeule {
    background: var(--tief);
    border-radius: 2px 2px 0 0;
    min-height: 2px;
}

.kpi-verlauf .balken-marke {
    display: block;
    font-size: 0.625rem;
    color: var(--hilfstext);
    text-align: center;
    margin-top: 0.3rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.kpi-spalten {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--a5);
}

/* ── Der Weg zur nächsten Stufe ──
   Ein Balken, kein Kreis: Er zeigt eine Strecke mit einem Ziel, und eine
   Strecke ist gerade. */
.fortschritt {
    height: 8px;
    background: var(--flaeche);
    border-radius: 4px;
    overflow: hidden;
    margin: var(--a3) 0;
}

.fortschritt-balken {
    height: 100%;
    background: var(--tief);
    border-radius: 4px;
}

@media (max-width: 640px) {
    /* Auf dem Telefon sind zwölf Balken je 25 Pixel breit — lesbar, aber die
       Beschriftung darunter nicht. Dann nur jeder dritte Monat. */
    .kpi-verlauf .balken-spalte:not(:nth-child(3n)) .balken-marke {
        visibility: hidden;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   Der Standort in der Partnerakte (01.09.2026)
   ══════════════════════════════════════════════════════════════════════════

   Die Fläche steht auch ungeladen da und hält ihre Höhe. Ein Kasten, der
   beim Klick von 3rem auf 20rem springt, schiebt den halben Rest der Seite
   nach unten — und wer gerade etwas anderes las, verliert die Stelle. */
.karte-standort {
    margin-top: var(--a5);
    /* Und darunter genauso viel: Der Weg „In Google Maps öffnen" gehört zum
       Standort, „Stammdaten ändern" zur Karte darum. Ohne diesen Abstand
       standen beide Knöpfe untereinander und sahen aus wie ein Paar. */
    margin-bottom: var(--a5);
    border-top: 1px solid var(--linie);
    padding-top: var(--a4);
}

.karte-standort h4 {
    margin: 0 0 var(--a2);
    font-size: 1rem;
}

/* Die Karte lädt sofort (02.09.2026), deshalb trägt die Fläche nichts als
   den Rahmen. Der graue Grund bleibt: Er steht dort, solange die Kacheln
   unterwegs sind, und ein weißer Block auf weißem Grund sähe nach einem
   Fehler aus. */
.kartenflaeche {
    min-height: 16rem;
    background: var(--flaeche);
    border: 1px solid var(--linie);
    border-radius: var(--radius);
    overflow: hidden;
}

.kartenflaeche iframe {
    display: block;
    width: 100%;
    height: 16rem;
    border: 0;
}

/* Der Quellenhinweis unter der Standortkarte: er trägt eine Auskunft, keine
   Anweisung, und darf deshalb kleiner stehen als der übrige Hinweistext. */
.hinweis.klein {
    font-size: 0.8125rem;
    margin-top: var(--a2);
}


/* ══════════════════════════════════════════════════════════════════════════
   Ein Knopf, der arbeitet
   ══════════════════════════════════════════════════════════════════════════

   Für Vorgänge, die spürbar dauern (Vertrag erzeugen, Unterlage ablegen).
   Der Kreis dreht sich links neben der Beschriftung und nimmt ihre Farbe an;
   ein zweiter Farbwert wäre hier ebenso falsch wie überall sonst in diesem
   Blatt. */
button.laeuft,
.knopf.laeuft {
    position: relative;
    padding-left: 2.25rem;
    cursor: progress;
    opacity: 0.85;
}

button.laeuft::before,
.knopf.laeuft::before {
    content: '';
    position: absolute;
    left: var(--a3);
    top: 50%;
    width: 0.9rem;
    height: 0.9rem;
    margin-top: -0.45rem;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: dreht 0.7s linear infinite;
}

@keyframes dreht {
    to { transform: rotate(360deg); }
}

/* Wer Bewegung abgestellt hat, bekommt keine. Der Kreis bleibt stehen und
   sagt trotzdem, dass etwas läuft — zusammen mit der Beschriftung, die sich
   ändert, und dem gesperrten Knopf. */
@media (prefers-reduced-motion: reduce) {
    button.laeuft::before,
    .knopf.laeuft::before { animation: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Die Bereichsleiste (08.09.2026, Variante 1)
   ══════════════════════════════════════════════════════════════════════════

   Das Portal hatte bis dahin kein Menü. 22 von 34 Ansichten zeigten oben nur
   Start, Passwort und abmelden; jeder Wechsel zwischen zwei Bereichen lief
   über die Startseite, und aus der Partnerakte führte gar kein Weg zurück in
   die Partnerliste.

   Weiss und Linien, wie der Guide es für die Website vorgibt („lots of white
   space"): Der Streifen trägt keine Fläche, nur zwei feine Linien. Was ihn
   trägt, ist der Abstand. */

.leiste {
    background: var(--grund);
    border-bottom: var(--kante);
    padding: 0 var(--a5);
}

.leiste nav {
    display: flex;
    gap: var(--a6);
    flex-wrap: wrap;
    max-width: min(100%, 76rem);
    margin: 0 auto;
}

.leiste nav a {
    display: flex;
    align-items: center;
    padding: var(--a3) 0;
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--text-gedaempft);
    text-decoration: none;
    font-size: 0.9375rem;
    white-space: nowrap;
}

.leiste nav a:hover {
    color: var(--text);
    text-decoration: none;
}

.leiste nav a .icon {
    opacity: 0.6;
}

.leiste nav a:hover .icon {
    opacity: 0.9;
}

/* ── Die Zahl am Protokoll ──
   Sie steht nur da, wenn Betriebsmeldungen offen sind, und sie ist der
   einzige Anlass, das Protokoll zu öffnen. Deshalb muss sie auffallen.

   Nicht in der Hausfarbe: Die ist für den einen roten Strich reserviert
   (tests/test_gestaltung.php zählt mit). Der Warnton sagt ohnehin genauer,
   was gemeint ist — hier liegt etwas, das jemand ansehen sollte.

   Der Text steht in `--text` und nicht in `--warnung-kante`: Der Kantenton
   auf der Warnfläche trägt für einen Strich, aber nicht für eine Ziffer.

   Zwei Selektoren, nicht einer: Auf dem Handy ist die Leiste eingeklappt, und
   die Zahl sitzt dann am Knopf `.burger` statt an einem `nav a`. Mit nur dem
   ersten Selektor stand dort „Menü4" als nackter Text, ohne Pille und ohne
   Abstand — ausgerechnet in dem Viewport, für den die Zahl gebaut wurde. */
.leiste nav a .zaehler,
.leiste .burger .zaehler {
    display: inline-block;
    margin-left: 0.4em;
    padding: 0.05em 0.45em;
    border: 1px solid var(--warnung-kante);
    border-radius: 999px;
    background: var(--warnung-flaeche);
    color: var(--text);
    font-size: 0.8em;
    font-weight: 600;
    line-height: 1.4;
}

/* ── Der eine rote Strich ──
   Paul am 08.09.2026: „der Strich unten, der anzeigt, wo im Menü ich bin,
   der soll in diesem DEH-Rot sein."

   Das ist eine bewusste Abweichung von der Regel bei `main > h2`, wo steht,
   die Hausfarbe erscheine „ausschliesslich hier … einmal je Seite". Sie kommt
   jetzt zweimal vor: einmal senkrecht an der Überschrift, einmal waagerecht
   unter dem Bereich, in dem man steht.

   Warum das trotzdem trägt: Beide Male ist es derselbe schmale Strich und nie
   eine Fläche, nie ein Buchstabe. Die Verwechslung, vor der die Regel
   schützt — rote Schrift, die wie eine Warnung aussieht —, entsteht dadurch
   nicht. */
.leiste nav a[aria-current='page'] {
    color: var(--text);
    font-weight: 600;
    border-bottom-color: var(--marke);
}

.leiste nav a[aria-current='page'] .icon {
    opacity: 1;
}

/* ── Der Burger ──
   Ohne Javascript: eine Beschriftung schaltet ein verstecktes Kästchen, und
   das Kästchen zeigt das Menü. Am Rechner ist der Burger weg und das Menü
   immer da. Ein Menü, das ohne Javascript verschwindet, wäre schlechter als
   gar keines. */
.menu-schalter {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.burger {
    display: none;
    align-items: center;
    gap: var(--a2);
    padding: var(--a2) var(--a3);
    margin: var(--a2) 0;
    border: 1px solid var(--linie);
    border-radius: var(--radius);
    background: var(--grund);
    font-size: 0.875rem;
    cursor: pointer;
    user-select: none;
}

.burger .striche {
    display: inline-block;
    width: 16px;
}

.burger .striche span {
    display: block;
    height: 2px;
    background: currentColor;
    margin: 3px 0;
}

/* Der Fokusrahmen muss sichtbar sein: Der Burger ist eine Beschriftung, kein
   Knopf, und bekommt ihn nicht von selbst. */
.menu-schalter:focus-visible ~ .leiste .burger {
    outline: 2px solid var(--zweitakzent);
    outline-offset: 2px;
}

@media (max-width: 760px) {
    .leiste {
        padding: 0 var(--a4);
    }
    .burger {
        display: inline-flex;
    }
    .leiste nav {
        display: none;
        flex-direction: column;
        gap: 0;
        padding-bottom: var(--a2);
    }
    .menu-schalter:checked ~ .leiste nav {
        display: flex;
    }
    .leiste nav a {
        padding: var(--a3) 0;
        margin-bottom: 0;
        border-bottom: 1px solid var(--linie-zart);
    }
    .leiste nav a[aria-current='page'] {
        border-bottom-color: var(--marke);
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   Das Kennzahlenband wird hell (08.09.2026, Variante 1)
   ══════════════════════════════════════════════════════════════════════════

   Paul: „Der schwarze Kasten ist zu dominant, und das passt irgendwie nicht."

   Er hat recht, und der eigene Brand Guide gibt ihm recht: Für die Website
   steht dort „Lots of white space, subtle color areas (blue/anthracite +
   ruby red)". Eine 330 Pixel hohe Fläche in Gemstone Blue ist nicht subtle —
   sie war das Erste und Lauteste auf jeder Seite.

   Die Zahlen bleiben, die Fläche geht. Getrennt wird über feine Linien, wie
   überall sonst in diesem Blatt. Der rote Balken links bleibt: Er ist der
   eine Markenakzent des Bandes und jetzt der einzige Farbwert darin.

   Dieser Block steht am ENDE und überschreibt die Regeln von oben, statt sie
   zu ersetzen. Der Grund ist die Spaltenzählung mit `:has()` weiter oben —
   sie ist über Monate gewachsen und an drei Bildschirmbreiten gemessen. Wer
   sie beim Umfärben mit anfasst, hat gute Aussichten, sie zu zerlegen. */

.band {
    background: var(--grund);
    color: var(--text);
    border: var(--kante);
    border-left: 3px solid var(--marke);
    border-radius: var(--radius);
}

.band h3 {
    color: var(--hilfstext);
}

.band .zeitraeume {
    border-top-color: var(--linie);
}

.band .bez,
.band .neben {
    color: var(--hilfstext);
}

.band .zahl {
    color: var(--text);
}

/* ── Eine Zahl, die etwas meldet ──
   Auf dunklem Grund war sie in aufgehelltem Rot gesetzt. Auf hellem Grund
   ginge das nicht: Dieses Blatt kennt keinen roten Buchstaben, weil er sich
   mit der Hausfarbe verwechseln liesse (siehe die Regel bei den Zuständen).
   Sie bekommt stattdessen die Form, die alle Zustände hier tragen — eine
   farbige Kante links, schwarzer Text. */
.band .achtung .zahl {
    color: var(--text);
}

.band .achtung {
    border-left: 3px solid var(--warnung-kante);
    padding-left: var(--a3);
}

/* Die Sonderregeln für weiss auf Gemstone Blue sind hinfällig. Sie werden
   NICHT durch eigene Farbwerte ersetzt: Die allgemeine Hover-Regel weiter
   oben im Blatt greift jetzt wieder, und ein zusätzliches `var(--marke)`
   hier hätte die Hausfarbe an zwei weiteren Stellen verteilt — genau das,
   wovor der Wächter in tests/test_gestaltung.php warnt. */
a.zelle:hover,
a.zelle:focus,
.band .aufgaben a:hover,
.band .aufgaben a:focus {
    color: inherit;
}

/* ══════════════════════════════════════════════════════════════════════════
   Dass es weitergeht, muss man SEHEN (11.09.2026)
   ══════════════════════════════════════════════════════════════════════════

   Bis hierher war die Kachel ein Verweis ohne jedes Merkmal: gleiche Farbe,
   gleiche Schrift, ein Unterstrich erst beim Überfahren mit der Maus. Auf
   dem Telefon gibt es kein Überfahren.

   Das DEH las „Gemeldete Kunden 2", hielt es für eine tote Zahl und schrieb:
   „Da muss irgendwie ein Link geben sein, wenn ich hier auf der Übersicht
   bin, damit ich hinkomme."

   ── Warum WORTE und kein Winkel ──

   Der erste Versuch war ein „›" hinter der Zahl und ein gepunkteter
   Unterstrich unter der Beschriftung. Beides war im Rendering praktisch
   unsichtbar: das Zeichen zuerst in `rgba(255, 255, 255, …)` — aus der Zeit
   des dunklen Bandes und damit weiss auf weiss, derselbe Fehler, den der
   Kommentar weiter unten schon einmal beschreibt —, danach in Hilfstextgrau
   ein Staubkorn neben einer Zahl in 1,5rem. Die Punktlinie hatte die Farbe
   der Trennlinien.

   Ein Merkmal, das man suchen muss, ist keines. Die Kachel sagt jetzt in
   Worten, wohin sie führt. */
.zelle .weiter {
    display: block;
    margin-top: 0.45rem;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--text);
    text-decoration: underline;
    text-underline-offset: 0.2em;
    text-decoration-thickness: 1px;
}

a.zelle:hover .weiter,
a.zelle:focus .weiter {
    text-decoration-thickness: 2px;
}

.band .aufgaben span {
    color: var(--text-gedaempft);
}

/* Die restlichen Werte des ehemals dunklen Bandes.
   Sie standen als `rgba(255, 255, 255, …)` da und wären auf dem hellen Grund
   unsichtbar gewesen — der Fusstext war es bereits, weiss auf weiss, bis das
   im ersten Rendering auffiel. Deshalb hier vollständig statt einzeln. */
.band .fuss,
.band .haus h4 {
    color: var(--hilfstext);
}

.band .fuss,
.band .haus {
    border-top-color: var(--linie);
}

.band .buchhaltung h4 {
    color: var(--hilfstext);
}
/* ── Die zweite Zeile in der Partnerliste ──
   (app/views/partner_liste.php, 08.09.2026)

   Die Prüfliste trägt Nummer, Vertragsart und Ort nicht mehr in eigenen
   Spalten, sondern klein unter der Firma. Ohne diese Regeln steht die Zeile
   in Textgröße unter dem Firmennamen und liest sich wie eine zweite, gleich
   wichtige Angabe — sie soll aber die Beiläufigkeit haben, die .zusatz und
   .wann sonst schon tragen: da, wenn man hinsieht, still, wenn man
   überfliegt.

   Eigene Klasse statt .zusatz: Deren negativer Anzug nach oben und der
   Abstand nach unten sind für den Hinweis unter einem Eingabefeld gemacht;
   in einer Tabellenzelle zöge beides die Zeile auseinander. */
.zeilenzusatz {
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--hilfstext);
    margin-top: 0.15rem;
}

/* Eine Partner-Nummer wird als Ganzes gelesen und als Ganzes gesucht.
   Sie stand bis zum 08.09.2026 in einer eigenen Spalte mit genau dieser
   Regel (td.nummer); mit der Spalte darf sie nicht verlorengehen —
   „OD10002-2608" auf zwei Zeilen ist keine Nummer mehr, sondern ein Rätsel. */
.zeilenzusatz .nr {
    white-space: nowrap;
}

/* Der Haken vor einem geworbenen Partner (24.09.2026).

   Paul: „zumindest so, dass ein Partner unter einem anderen in der Liste
   unter diesen und eingerückt erscheint." Die Einrückung selbst steht als
   padding an der Zelle, weil sie je Ebene anders ausfällt; dieser Haken
   sagt dasselbe noch einmal und bleibt sichtbar, wenn die Tabelle auf dem
   Telefon zur Kartenliste wird — dort fällt das padding weg. */
.werbepfeil {
    color: var(--hilfstext);
    margin-right: 0.25rem;
}

/* Eine Stufe je Ebene der Werbekette. Fünf reichen: Tiefer wird die Zeile
   unlesbar, und tiefer ist die Kette heute nicht.

   `table.gestapelt td.werbetiefe-N` statt `!important`: Die Regel muss
   `table.gestapelt td` (Spezifität 0,1,2) schlagen, und das tut sie mit
   0,2,2 von selbst. Ein `!important` stand hier zuerst und war eine
   Abkürzung, die den nächsten Leser ratlos lässt. */
table.gestapelt td.werbetiefe-1 { padding-left: 2.1rem; }
table.gestapelt td.werbetiefe-2 { padding-left: 3.3rem; }
table.gestapelt td.werbetiefe-3 { padding-left: 4.5rem; }
table.gestapelt td.werbetiefe-4 { padding-left: 5.7rem; }
table.gestapelt td.werbetiefe-5 { padding-left: 6.9rem; }

/* Auf dem Telefon wird die Tabelle zur Kartenliste: Die Beschriftung sitzt
   absolut bei `left: 0.9rem` mit 38 % Breite, und die Zelle hält mit
   `padding-left: 44 %` den Platz dafür frei.

   Die erste Fassung setzte hier `0.9rem` — damit begann der Firmenname
   genau dort, wo das Wort „Partner" steht, und beides lag übereinander.
   Ein Prüfer fand es am 24.09.2026; mein Screenshot hatte es nicht
   gezeigt, weil in der sichtbaren ersten Zeile gar keine Einrückung
   steht.

   Das Vorbild `td.tat` darf `0.9rem` setzen, weil jene Zellen ein LEERES
   `data-label` tragen. Die Partnerzelle trägt „Partner", also bleibt das
   Polster. Die Einrückung fällt weg, die Aussage trägt dort der Haken. */
@media (max-width: 640px) {
    table.gestapelt td.werbetiefe-1,
    table.gestapelt td.werbetiefe-2,
    table.gestapelt td.werbetiefe-3,
    table.gestapelt td.werbetiefe-4,
    table.gestapelt td.werbetiefe-5 {
        padding-left: 44%;
    }
}
/* ══════════════════════════════════════════════════════════════════════════
   Die Register der Partnerakte (08.09.2026)
   ══════════════════════════════════════════════════════════════════════════

   Gehört nach app/stil.css. Zwei neue Klassen, beide nur in
   app/views/partner_akte.php: der Rückweg in die Liste und die
   Registerleiste.

   ── Warum hier kein var(--marke) steht ──

   tests/test_gestaltung.php lässt die Hausfarbe höchstens achtmal im
   Stilblatt zu, und die acht sind vergeben (Seitenüberschrift, Band,
   Bereichsleiste). Der rote Strich bleibt deshalb der Bereichsleiste im Kopf
   vorbehalten: Er sagt, in welchem BEREICH des Portals man steht. Das
   Register darunter ist eine Ebene tiefer und sagt es in Schwarz — sonst
   stünden zwei gleich aussehende rote Striche übereinander und keiner wüsste
   mehr, was er bedeutet. */

/* ── Der Rückweg in die Liste ──
   Er steht über der Überschrift und ist bewusst klein: Der Name der Firma ist
   das, was gelesen werden soll, nicht der Weg zurück. */
.rueckweg {
    margin: 0 0 var(--a3);
    font-size: 0.8125rem;
}

.rueckweg a {
    display: inline-flex;
    align-items: center;
    color: var(--hilfstext);
    text-decoration: none;
}

.rueckweg a:hover {
    color: var(--text);
    text-decoration: underline;
}

/* ── Die Registerleiste ──
   Dieselbe Form wie die Bereichsleiste im Kopf: keine Fläche, keine Kacheln,
   nur eine feine Linie und der Abstand. Vier Reiter in einer Zeile, der
   gewählte in Schwarz mit Unterstrich. */
.reiter {
    display: flex;
    gap: var(--a5);
    flex-wrap: wrap;
    border-bottom: var(--kante);
    margin: 0 0 var(--a5);
}

.reiter a {
    display: inline-flex;
    align-items: center;
    padding: var(--a2) 0;
    /* Der Unterstrich des gewählten Reiters sitzt AUF der Linie der Leiste,
       nicht darunter. */
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--hilfstext);
    text-decoration: none;
    font-size: 0.9375rem;
    white-space: nowrap;
}

.reiter a:hover {
    color: var(--text);
    text-decoration: none;
    border-bottom-color: var(--linie);
}

/* Wo man steht. `aria-current` und keine eigene Klasse: Dieselbe Auszeichnung
   trägt die Bereichsleiste, und ein Vorleseprogramm sagt es damit von selbst. */
.reiter a[aria-current='page'] {
    color: var(--text);
    font-weight: 600;
    border-bottom-color: var(--text);
}

/* Am Telefon: Die vier Reiter passen nebeneinander (gemessen an „Stammdaten"
   als längstem). Sollte je ein fünfter dazukommen, rutscht er um — deshalb
   flex-wrap oben und hier nur der engere Abstand. */
@media (max-width: 480px) {
    .reiter {
        gap: var(--a4);
    }

    .reiter a {
        font-size: 0.875rem;
    }
}

/* Webinar-Werbelink, 15.09.2026 */

/* Dieselbe Bauart an zwei Stellen: auf der Startseite in einer eigenen Karte
   („Ihre Einladungslinks", app/views/start.php) und in der Partnerakte als
   Abschnitt der Stammdatenkarte, unter dem Datenraster
   (app/views/partner_akte.php, 15.09.2026). Der Block ist abgesetzt: Eine
   Haarlinie darüber sagt, dass hier etwas anderes anfängt — die Nummer ist
   eine Auskunft, der Link ein Werkzeug. Die Linie ist dieselbe zarte wie unter
   den Kartenüberschriften.

   Hier stand bis zum 15.09.2026, der Block stehe „in der Karte
   Bearbeitungsstand". Das war am Vormittag richtig und am Nachmittag überholt:
   Er ist aus dieser Karte heraus in eine eigene gewandert, weil ein
   Untervermittler die Karte Bearbeitungsstand gar nicht sieht (die hängt an
   $eigenerPartner). Der Kommentar hinkte der Ansicht einen halben Tag
   hinterher. */
.webinarlink {
    margin-top: var(--a4);
    padding-top: var(--a3);
    border-top: 1px solid var(--linie-zart);
}

/* Die vierte Ebene erbt sonst die Browservorgabe: fett, klein und mit einem
   Abstand, der jede Karte auseinanderzieht. Sie nimmt hier die Antiqua wie
   jede andere Überschrift im Portal, nur eine Stufe leiser als die h3 darüber
   und ohne deren Linie — die trägt schon der Block. */
.webinarlink h4 {
    font-family: var(--schrift-titel);
    font-size: 1rem;
    font-weight: 400;
    margin: 0 0 var(--a2);
    color: var(--text);
}

.webinarlink p {
    font-size: 0.875rem;
    margin: 0 0 var(--a2);
}

/* Die Adresse selbst — auf der Startseite und in der Partnerakte.

   Bis zum 16.09.2026 stand sie hier in einem `input[readonly]`. Am Telefon
   zeigte das Feld 38 der 75 Zeichen, der Rest steckte darin: markierbar, aber
   nicht lesbar und nicht vorlesbar. Gemessen an
   scratch/webinar-oben/shots/akte-mit-nummer/voll-mobile.png.

   Seitdem gilt an allen drei Stellen, was das Netzwerk schon vorher hatte
   (siehe `.webinarzeile .wert` weiter unten): umbrechender Text statt Kasten.
   Das ist zugleich der Rückfallweg für den, der kein JavaScript hat — also
   für genau den, der die Adresse von Hand übernehmen muss.

   Ziffernschrift, weil der Link abgeschrieben, weitergegeben und am Telefon
   vorgelesen wird. In einer Proportionalschrift sind I, l und 1 derselbe
   Strich — in einer Partner-Nummer wie VD10001-2609 ist das genau der
   Unterschied zwischen zugerechnet und nicht zugerechnet.

   `user-select: all`: ein Klick markiert die ganze Adresse, am Telefon ein
   langes Tippen. `overflow-wrap: anywhere` und nicht `break-word`, weil nur
   `anywhere` beim Messen der kleinsten Breite mitzählt — sonst schiebt die
   75 Zeichen lange Adresse ohne ein einziges Leerzeichen die Karte seitwärts. */
.webinarlink .wert {
    font-family: var(--schrift-ziffern);
    font-size: 0.8125rem;
    overflow-wrap: anywhere;
    -webkit-user-select: all;
    user-select: all;
}

.webinarlink .nummer {
    margin: var(--a2) 0 0;
}
/* Webinarlink und Videolink stehen seit dem 01.10.2026 untereinander, je in
   einer eigenen Klammer `.einladung`. Der Abstand trennt die zwei Paare aus
   Knopf und „öffnen", damit sich das „öffnen" des ersten nicht wie die
   Überschrift des zweiten liest. */
.webinarlink .einladung + .einladung {
    margin-top: var(--a3);
}

/* Abstand nach unten nur, wenn noch etwas folgt — auf der Startseite der Knopf
   zu den Unterlagen, in der Partnerakte der Standortabschnitt, die sonst
   unmittelbar unter dem Link klebten. Steht der Block als Letztes, trägt die
   Karte ihre eigene Polsterung, und ein zusätzlicher Rand machte sie unten
   höher als an den drei anderen Seiten. */
.webinarlink:not(:last-child) {
    margin-bottom: var(--a4);
}

/* Die Zeile im Netzwerk (15.09.2026, app/views/netzwerk.php)

   Dort steht der Link je geworbenem Partner, und zwar als Textzeile statt im
   Lesefeld: Auf einer Seite mit mehreren Partnerkarten untereinander wären
   fünf gerahmte Eingabefelder eine Wand. Die ausführliche Begründung steht in
   der Ansicht.

   Die Regeln stehen in diesem Stilblatt und nicht im style-Block von
   netzwerk.php, obwohl der die übrigen Regeln jener Seite trägt: Was hier
   steht, ist keine Anordnung von Karten, sondern die Darstellung DIESES Links
   — und die gehört an dieselbe Stelle wie die des Lesefeldes darüber, damit
   Startseite, Akte und Netzwerk nicht auseinanderlaufen. */
.webinarzeile {
    font-size: 0.875rem;
    /* Oben UND unten Abstand. Beim geworbenen Partner ohne Kunden folgt
       unmittelbar `.leer` („Für diesen Partner ist noch kein Kunde
       zugeordnet"), und das trägt margin: 0 — ohne den Abstand hier lasen
       sich die beiden Sätze wie ein zweizeiliger Absatz, in dem der zweite
       den ersten erklärt. Gemessen am Bild vom 15.09.2026: 21 Pixel
       darunter gegen 50 darüber. */
    margin: var(--a3) 0;
    /* `anywhere` und nicht `break-word`: Nur `anywhere` zählt beim Messen der
       kleinsten Breite mit. Die Adresse ist rund 75 Zeichen lang und trägt
       kein Leerzeichen; ohne diese Zeile läuft sie auf dem Telefon aus der
       Karte heraus und schiebt die ganze Seite seitwärts. */
    overflow-wrap: anywhere;
}

/* Die Beschriftung und der Ersatzsatz stehen leiser als die Adresse selbst —
   dieselbe Abstufung wie bei den Zahlen im Kartenkopf darüber. */
.webinarzeile .marke,
.webinarzeile .fehlt {
    color: var(--hilfstext);
}

/* Ziffernschrift aus demselben Grund wie oben: In einer Proportionalschrift
   sind I, l und 1 derselbe Strich.

   `user-select: all` war bis zum 16.09.2026 der Ersatz für den Kopierknopf,
   den es hier nicht gab: Ein Klick markiert die ganze Adresse, ein langes
   Tippen am Telefon ebenso. Den Knopf gibt es jetzt (app/kopieren.js), und
   diese Regel bleibt genau deshalb stehen — sie ist der Weg für den, bei dem
   kein Skript läuft. Sie ist eine Regel des Stilblatts und braucht keines. */
.webinarzeile .wert {
    font-family: var(--schrift-ziffern);
    font-size: 0.8125rem;
    -webkit-user-select: all;
    user-select: all;
}

/* Der Weg nach draußen bleibt in einer Zeile. Bräche „öffnen" hinter dem
   ö um, stünde am Ende der Adresse ein einzelnes „n", das wie ein Tippfehler
   in der Adresse aussieht. */
.webinarzeile a {
    white-space: nowrap;
}

/* Der Satz, der den Link dem geworbenen Partner zurechnet (16.09.2026).

   In einer eigenen Zeile und leiser als die Adresse: Er gehört zur Zeile,
   nicht in sie. Die Begründung, warum er hier überhaupt steht, gehört in die
   Ansicht (app/views/netzwerk.php) — kurz: Wer auf „kopieren" drückt, sieht
   die Partner-Nummer im Link nicht mehr und könnte ihn für seinen eigenen
   halten. */
.webinarzeile .zurechnung {
    display: block;
    color: var(--hilfstext);
    margin-top: var(--a1);
}

/* ══════════════════════════════════════════════════════════════════════════
   Der Kopierknopf (16.09.2026)
   ══════════════════════════════════════════════════════════════════════════

   Das DEH: „mach mit einem Symbol und ‚Webinar-Einladungslink kopieren' den
   Link einfach zum kopieren." Er steht heute an drei Stellen: Startseite,
   Partnerakte, Netzwerk (dort je geworbenem Partner).

   ── Warum umrandet und nicht gefüllt ──

   Die allgemeine Regel für `button` weiter oben füllt ihn mit Gemstone Blue.
   Das ist richtig für den Knopf, der eine Maske abschickt — hier wäre es
   falsch: Auf der Startseite stünde er neben „Unterlagen hochladen", in der
   Akte über dem Standort, und im Netzwerk fünfmal untereinander. Fünf
   gefüllte dunkle Flächen auf einer Seite ziehen das Auge auf einen
   Handgriff, der eine Bequemlichkeit ist und keine Handlung mit Folgen.
   Dieselbe Form wie `.knopf-zweitrangig`, nur kleiner.

   Keine Regel zu `display`: Der Knopf startet mit `hidden`, und was das
   Grundblatt des Browsers dazu sagt, würde eine `display`-Regel hier
   überschreiben. Der Riegel dagegen steht ganz oben (`[hidden]`), aber die
   zweite Sicherung ist, hier gar nicht erst daran zu rühren. */
.kopierknopf {
    font-size: 0.8125rem;
    padding: 0.4rem 0.8rem;
    background: var(--grund);
    color: var(--tief);
    border: 1px solid var(--tief);
}

.kopierknopf:hover {
    background: var(--flaeche);
    color: var(--tief);
}

/* Das Sinnbild im Knopf steht in voller Deckkraft — es ist hier nicht
   Schmuck neben einer Überschrift, sondern das, was das DEH ausdrücklich
   verlangt hat („mit einem Symbol"). */
.kopierknopf .icon {
    opacity: 1;
}

/* Die Meldung nach dem Klick („kopiert", oder der Weg von Hand, wenn es
   nicht geklappt hat).

   Sie steht leer im Markup und wird vom Skript gefüllt. Ohne Inhalt nimmt
   sie keinen Platz ein; deshalb braucht sie keine eigene Zeile und schiebt
   auch nichts, solange niemand drückt. Der linke Abstand steht am Element
   und nicht als Wortabstand, damit er auch dann stimmt, wenn die Meldung in
   die nächste Zeile umbricht. */
.kopierstand {
    color: var(--hilfstext);
    font-size: 0.8125rem;
    margin-left: var(--a2);
}

/* Der Knopf „Teilen" ist ein <button>, seine Nachbarn „Ansehen" und
   „Herunterladen" sind Links — und Links in Tabellenzellen stehen halbfett
   (`td a`). Ohne diese Zeile stünde „Teilen" als einziger dünn in der
   Reihe, gemessen am 03.10.2026 in WebKit. */
td.tat button[data-teilen] {
    font-weight: 600;
}

/* Die Meldung des Knopfes „Teilen" in der Mediathek (03.10.2026,
   app/teilen.js). Dieselbe Rolle wie `.kopierstand`, aber in einer
   Tabellenzelle, die `nowrap` trägt (`td.tat`): Ohne `normal` zöge ein
   Meldesatz die Spalte über die halbe Seite. Als Block unter den Knöpfen,
   weil daneben kein Platz ist. Leer nimmt er keinen Raum ein. */
.teilstand {
    display: block;
    color: var(--hilfstext);
    font-size: 0.8125rem;
    white-space: normal;
    max-width: 18rem;
    margin-left: auto;
}

.teilstand:empty {
    display: none;
}

@media (max-width: 640px) {
    /* Gestapelt steht der Knopf links (siehe `td.tat`), die Meldung mit. */
    table.gestapelt td.tat .teilstand {
        margin-left: 0;
    }
}

/* Ein Satz nur für Geräte ohne Maus (Mediathek, 03.10.2026): wohin am
   iPhone ein Download geht. Am Schreibtisch wäre er Lärm. `hover: none`
   UND `pointer: coarse`, damit ein Laptop mit Berührungsbildschirm, der
   auch eine Maus hat, ihn nicht zeigt. */
.nur-beruehrung {
    display: none;
}

@media (hover: none) and (pointer: coarse) {
    .nur-beruehrung {
        display: block;
    }
}

/* In der Karte (Startseite, Akte) steht der Knopf unter der Adresse, und die
   Meldung gehört neben den Knopf — nicht darunter. Der Abstand nach oben
   trennt ihn vom Text darüber; die allgemeine Regel `input ~ button` greift
   hier nicht mehr, seit die Adresse kein Eingabefeld mehr ist. */
.webinarlink .kopierknopf {
    margin-top: var(--a2);
}

/* In der Netzwerkzeile steht rechts neben dem Knopf das Wort „öffnen".
   Zwischen beiden stand nur der Wortabstand von vier Pixeln, und damit klebte
   der Verweis am Rahmen des Knopfes — am Telefon gemessen am Bild vom
   16.09.2026. Ein Knopf braucht Luft, sonst liest sich das Wort daneben wie
   seine zweite Beschriftung. */
.webinarzeile .kopierknopf {
    margin-right: var(--a2);
}

/* ══════════════════════════════════════════════════════════════════════════
   Die Knopfreihe über der Partnerliste (15.09.2026)
   ══════════════════════════════════════════════════════════════════════════

   Nur in app/views/partner_liste.php. Das DEH am 15.09.2026: „Die Übersicht
   der Partner ist insgesamt sehr unübersichtlich." Die Reihe schneidet den
   Bestand in seine vier natürlichen Teile und trägt je Teil die Anzahl.

   ── Warum hier kein var(--marke) steht ──

   tests/test_gestaltung.php lässt die Hausfarbe höchstens achtmal im
   Stilblatt zu, und die acht sind vergeben (Seitenüberschrift, Band,
   Bereichsleiste). Der rote Strich bleibt der Bereichsleiste im Kopf
   vorbehalten: Er sagt, in welchem BEREICH des Portals man steht. Dieselbe
   Entscheidung ist am 08.09.2026 schon einmal gefallen, für die Register der
   Partnerakte — die sagen es eine Ebene tiefer in Schwarz.

   Diese Reihe liegt noch eine Ebene darunter: Sie sagt nicht, wo man ist,
   sondern welchen Ausschnitt einer Liste man sieht. Der aktive Knopf nimmt
   deshalb die stark aufgehellte Hausfarbe als FLÄCHE (--marke-flaeche, wie
   der Aufgabenkasten der Startseite) und schwarze Schrift — die Hausfarbe ist
   erkennbar, ohne dass ein dritter roter Strich um Bedeutung konkurriert.
   Kontrast gemessen (siehe die Anmerkung bei --marke-flaeche): schwarz auf
   dieser Fläche 18,38:1. */

.chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--a2);
    margin: 0 0 var(--a4);
}

/* Der einzelne Knopf. Kein .knopf: Der ist der Weg zu einer Handlung
   („Partner anlegen") und trägt dafür eine volle Fläche. Hier geht es um eine
   Auswahl unter gleichrangigen Ausschnitten — Umriss, keine Fläche. */
.chip {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.3rem 0.7rem;
    border: var(--kante);
    border-radius: var(--radius);
    background: var(--grund);
    color: var(--text-gedaempft);
    text-decoration: none;
    font-size: 0.875rem;
    white-space: nowrap;
}

.chip:hover {
    border-color: var(--hilfstext);
    color: var(--text);
    text-decoration: none;
}

/* Die Zahl in Ziffernschrift wie jede andere Zahl des Portals, und gedämpft:
   Gelesen wird zuerst das Wort, die Zahl beantwortet die Nachfrage. */
.chip-zahl {
    font-family: var(--schrift-ziffern);
    font-size: 0.8125rem;
    color: var(--hilfstext);
}

/* Welcher Ausschnitt gerade dasteht. Fläche, Kante und Fettung zusammen —
   eine Auszeichnung allein ist auf einem Telefonbildschirm zu leise. */
.chip-aktiv {
    background: var(--marke-flaeche);
    border-color: var(--marke-hell);
    color: var(--text);
    font-weight: 600;
}

.chip-aktiv .chip-zahl {
    color: var(--text-gedaempft);
}

/* Am Telefon bricht die Reihe von selbst um (flex-wrap oben). Sie wird dabei
   enger statt kleiner: Fünf Knöpfe auf 390 Pixeln brauchen drei Zeilen, und
   drei Zeilen lesbarer Knöpfe sind besser als zwei Zeilen winziger. */
@media (max-width: 480px) {
    .chips {
        gap: var(--a1);
    }

    .chip {
        padding: 0.25rem 0.55rem;
        font-size: 0.8125rem;
    }
}

/* ── Die Spalte „Was fehlt" ──
   (app/views/partner_liste.php, 15.09.2026)

   Mehrere Marken je Zeile statt einer Aufzählung mit Kommas: „Freischaltung,
   Vertragsbeginn, IBAN, Gewerbeschein" liest sich als ein Satz, den man ganz
   lesen muss. Als Marken sieht man die Zahl der Lücken, bevor man ein Wort
   gelesen hat — und genau darum ging es: „auf einen Blick sehen können, was
   bei einem Partner noch fehlt."

   Die einzelne Marke ist weiter .offen (weiter oben im Blatt); hier steht nur
   der Abstand zwischen ihnen. */
.was-fehlt {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
}

/* Wo nichts fehlt, steht das auch da — kein Gedankenstrich. Dieselbe Form wie
   .offen und .zustand.fehlt, nur in der Erfolgsfarbe: Es ist dieselbe Art
   Auskunft, mit der anderen Antwort. */
.vollstaendig {
    display: inline-block;
    background: var(--erfolg-flaeche);
    border-left: 3px solid var(--erfolg-kante);
    border-radius: var(--radius);
    padding: 0.15rem 0.5rem;
    color: var(--text-gedaempft);
    font-size: 0.8125rem;
}

/* Der beendete und der abgelehnte Partner. Bei ihm ist nichts mehr offen, und
   das ist etwas anderes als „vollständig": Sein Vorgang ist zu Ende, nicht
   seine Akte fertig. Deshalb keine Erfolgsfarbe, sondern der stille Ton, den
   .keine-nummer und .zusatz auch tragen — die Zeile soll beim Überfliegen
   nicht mitgelesen werden. */
.nichts-offen {
    color: var(--hilfstext);
    font-size: 0.8125rem;
}

/* Der Weg „nachtragen" steht zwischen den Marken und darf sie nicht
   überstimmen. `td a` setzt jeden Verweis einer Tabellenzeile auf halbfett —
   richtig für den Firmennamen, der die Zeile trägt, zu laut für einen
   Handgriff am Rand einer Aufzählung: Er las sich fetter als die Lücken, um
   die es geht. Hier also die Größe der Marken daneben und das normale
   Gewicht; unterstrichen bleibt er, damit er als Weg erkennbar ist. */
.was-fehlt a {
    font-weight: 400;
    font-size: 0.8125rem;
    text-decoration: underline;
    color: var(--hilfstext);
}

.was-fehlt a:hover {
    color: var(--text);
}

/* ══════════════════════════════════════════════════════════════════════════
   Wiedervorlagen (15.09.2026)
   ══════════════════════════════════════════════════════════════════════════

   Zwei Orte, eine Sache: die Aufgabenliste auf der Startseite
   (.aufgabenliste) und die Zeile an der einzelnen Notiz in der Partnerakte
   (.wiedervorlage-zeile).

   ── Warum hier kein Rot steht ──

   Die Hausfarbe ist vergeben: Sie erscheint im ganzen Blatt an acht Stellen,
   und tests/test_gestaltung.php lässt keine neunte zu. Das ist keine
   Einschränkung, sondern der Grund, warum der Anriss des Aufgabenkastens
   überhaupt auffällt.

   Der überfällige Eintrag unterscheidet sich deshalb zuerst in WORTEN — die
   Überschrift „Überfällig" und der Zusatz „seit 3 Tagen überfällig" stehen im
   Text und nicht in der Farbe. Die Fläche in Warnfarbe kommt dazu und trägt
   die Unterscheidung nicht allein: Auf einem Ausdruck in Graustufen und für
   jeden, der Rot von Grau nicht trennt, bleibt die Auskunft vollständig. */

.aufgabenliste .fach {
    /* Alle drei Fächer haben dieselbe FORM — Anriss links, gleicher Einzug.
       Unterschieden werden sie über die Überschrift und über das Gewicht der
       Kante, nicht über eine eigene Bauart je Fach. */
    border-left: 3px solid var(--linie);
    padding: var(--a3) var(--a4);
    margin-bottom: var(--a4);
}

.aufgabenliste .fach:last-child {
    margin-bottom: 0;
}

.aufgabenliste .fach.ueberfaellig {
    background: var(--warnung-flaeche);
    border-left-color: var(--warnung-kante);
}

.aufgabenliste .fach.heute {
    background: var(--flaeche);
    border-left-color: var(--zweitakzent);
}

/* Die Fachüberschrift. `.karte h3` ist die einzige Überschriftenstufe, die
   dieses Blatt gestaltet; ohne diese Regel fiele die h4 auf die Vorgabe des
   Browsers zurück (fett, eng, mit eigenem Abstand) und läse sich lauter als
   die Kartenüberschrift darüber. */
.aufgabenliste h4 {
    font-family: var(--schrift-text);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-gedaempft);
    margin: 0 0 var(--a2);
    display: flex;
    align-items: center;
    gap: var(--a2);
}

/* Die Zahl daneben sagt, wie viele es sind, ohne dass man zählen muss. */
.aufgabenliste h4 .anzahl {
    font-size: 0.6875rem;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--hilfstext);
    border: var(--kante);
    border-radius: 999px;
    padding: 0 0.45rem;
    background: var(--grund);
}

.aufgabenliste ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Raster statt Fluss: Der Knopf steht rechts auf der Höhe des ganzen
   Eintrags, der Text links darunter in vier Zeilen. Mit flex-wrap landete er
   je nach Länge des Firmennamens mal oben und mal unten. */
.aufgabenliste li {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.1rem var(--a4);
    padding: var(--a3) 0;
    border-top: 1px solid var(--linie-zart);
    font-size: 0.875rem;
}

.aufgabenliste li:first-child {
    border-top: 0;
    padding-top: 0;
}

.aufgabenliste li:last-child {
    padding-bottom: 0;
}

.aufgabenliste .firma {
    grid-column: 1;
    font-weight: 600;
}

.aufgabenliste .wann {
    grid-column: 1;
    font-size: 0.8125rem;
}

.aufgabenliste .anriss {
    grid-column: 1;
    color: var(--text-gedaempft);
    /* Der Anriss ist in der Ansicht schon auf 110 Zeichen gekürzt. Diese
       Zeile fängt den Rest: ein Wort ohne Leerzeichen — eine lange E-Mail,
       ein Aktenzeichen — schöbe den Kasten sonst über den Rand hinaus. */
    overflow-wrap: anywhere;
}

.aufgabenliste .wer {
    grid-column: 1;
    font-size: 0.8125rem;
    color: var(--hilfstext);
}

.aufgabenliste li > form {
    grid-column: 2;
    grid-row: 1 / span 4;
    align-self: center;
    margin: 0;
}

/* `input ~ button` setzt weiter oben einen Abstand nach oben — richtig für
   ein Formular mit sichtbaren Feldern, falsch hier: Vor dem Knopf stehen nur
   verdeckte Felder, und der Abstand schöbe ihn aus der Zeile. */
.aufgabenliste li > form button,
.wiedervorlage-zeile form button {
    margin-top: 0;
    font-size: 0.8125rem;
    padding: 0.35rem 0.8rem;
}

/* Am Telefon steht der Knopf unter dem Eintrag statt daneben: Bei 390 Pixeln
   bleiben neben „erledigt" keine 200 Pixel für den Firmennamen übrig, und der
   Anriss stünde in einer Spalte von vier Wörtern Breite. */
@media (max-width: 640px) {
    .aufgabenliste li {
        grid-template-columns: minmax(0, 1fr);
    }

    .aufgabenliste li > form {
        grid-column: 1;
        grid-row: auto;
        justify-self: start;
        margin-top: var(--a2);
    }
}

/* ── Die Zeile an der einzelnen Notiz in der Partnerakte ── */

.wiedervorlage-zeile {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--a2) var(--a3);
    margin: var(--a3) 0 0;
    font-size: 0.8125rem;
    color: var(--text-gedaempft);
}

.wiedervorlage-zeile form {
    margin: 0;
}

/* Das Wort „Wiedervorlage" als Marke davor: Ohne sie läse sich die Zeile wie
   eine Fortsetzung des Notiztextes darüber. */
.wiedervorlage-zeile .marke {
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--hilfstext);
    border: var(--kante);
    border-radius: var(--radius);
    padding: 0.1rem 0.4rem;
}

.wiedervorlage-zeile.spaet .marke {
    background: var(--warnung-flaeche);
    border-color: var(--warnung-kante);
    color: var(--text-gedaempft);
}

/* Die erledigte Wiedervorlage bleibt stehen — sie gehört zum Vorgang —, aber
   sie soll beim Überfliegen nicht mitgelesen werden. */
.wiedervorlage-zeile.erledigt {
    color: var(--hilfstext);
}

/* ══════════════════════════════════════════════════════════════════════════
   Abgleich klären (P4, 09.10.2026)
   ══════════════════════════════════════════════════════════════════════════

   Eine Karte je Partner, darin ein Block je Frage: drei Werte untereinander
   (Portal, DEH-ERP, zuletzt gemeinsam), darunter die Antworten. Als Liste
   und nicht als Tabelle, weil jede Frage eigene Knöpfe und ein Eingabefeld
   trägt — auf dem Telefon wäre eine Tabelle mit Formularen in jeder Zeile
   nicht bedienbar. */

.abgleich-zahl {
    margin: 0 0 1rem;
}

.abgleich-partner h3 .unternummer {
    margin-left: 0.5rem;
    font-weight: 400;
}

.abgleich-sammel {
    margin: 0 0 1rem;
}

.abgleich-frage {
    border-top: 1px solid var(--linie);
    padding: 1rem 0 0.5rem;
}

.abgleich-frage h4 {
    margin: 0 0 0.2rem;
    font-size: 1rem;
}

.abgleich-ziel,
.abgleich-art {
    color: var(--text-gedaempft);
    font-size: 0.8125rem;
    font-weight: 400;
}

.abgleich-ziel {
    margin-left: 0.4rem;
}

.abgleich-art {
    margin: 0 0 0.6rem;
}

.abgleich-werte {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.35rem 1rem;
    margin: 0 0 0.8rem;
}

.abgleich-werte dt {
    font-weight: 600;
    font-size: 0.8125rem;
}

.abgleich-werte dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.abgleich-werte .wann {
    display: block;
    color: var(--text-gedaempft);
    font-size: 0.75rem;
}

.abgleich-antwort .wege {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.abgleich-eigen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.6rem;
}

.abgleich-eigen label {
    margin: 0;
}

.abgleich-eigen input[type="text"] {
    flex: 1 1 14rem;
    min-width: 0;
}

@media (max-width: 600px) {
    .abgleich-werte {
        grid-template-columns: 1fr;
        gap: 0.1rem;
    }

    .abgleich-werte dd {
        margin-bottom: 0.4rem;
    }
}
