/* ============================================================
   allrounderX – Designsystem
   Farben und Maße orientiert an gängigen Handwerker-Portalen:
   dunkelblaue Seitenleiste, weiße Arbeitsfläche, blaue Primäraktion.
   ============================================================ */

:root {
    --navy: #102F4B;
    --navy-hell: #1B4670;
    --navy-tief: #0B2337;

    /* Die Schrift eines Verweises (`.knopf-nackt`). Im Hellen derselbe Ton wie `--navy-hell` –
       aber ein eigenes Token: `--navy-hell` ist im Dunkeln eine Fläche der Seitenleiste, und als
       Schrift stand dort 1,29 : 1. */
    --verweis: #1B4670;

    /* Navy als Schrift (Abzeichen, Marken) – aus demselben Grund getrennt von `--navy`. */
    --navy-schrift: #102F4B;
    --primaer: #0D87F2;
    --primaer-dunkel: #0A6FC7;
    --primaer-blass: #E7F2FE;
    /* Die Hausfarbe: das Blau des hinteren Balkens im X der Marke (`#1A7BFF`, dieselbe Stufe wie
       in `.nav__zeichen`). Bis 2026.10.20 stand hier das Orange des alten Namens. Gewählt ist die
       mittlere Stufe und nicht das Cyan der Spitze: Sie trägt auf allen drei Gründen, auf denen
       sie steht – gemessen 3,95 : 1 auf Weiß, 3,5 : 1 auf der Seitenleiste, 3,9 : 1 auf der
       dunklen Fläche; das Cyan käme auf Weiß nur auf 2,3. */
    --akzent: #1A7BFF;

    --text: #3C434A;
    --text-stark: #17212B;
    --text-schwach: #7E8896;

    /* **Gedämpft, aber zu lesen.** `--text-schwach` ist die Farbe jeder Nebenangabe und dafür
       richtig – für Schrift, die jemand wirklich liest, ist sie zu blass: auf der Arbeitsfläche
       gemessen 3,40 : 1, und die Richtlinie verlangt 4,5. Betroffen waren die ruhenden Reiter
       (fünf Bildschirme) und die Gruppenüberschriften der Einstellungen.

       Dieser Ton liegt dazwischen: gemessen 5,56 : 1 im Hellen und 9,40 : 1 im Dunkeln, und er
       steht immer noch sichtbar hinter `--text` zurück (9,50). **Er steht bewusst nur hier und
       nicht im dunklen Block:** Er hat keinen eigenen Wert, sondern eine Rechnung aus zwei
       Tokens, die dort längst getauscht werden – wer die Mischung ändert, ändert beide Welten.
       `DunkelmodusTests` führt ihn deshalb unter den gemeinsamen Tönen. */
    --text-gedaempft: color-mix(in srgb, var(--text) 50%, var(--text-schwach));

    --text-invers: #FFFFFF;
    --nav-text: #C3D0DD;

    /* Zwei Randstärken: die zarte trennt innerhalb einer Fläche (Tabellenzeilen), die
       normale umschließt eine Fläche. Ein einziger Wert ließ Listen vergittert wirken. */
    --rand: #E3E7EC;
    --rand-zart: #EDF0F4;

    /* Eine dritte Stärke für das, was auffallen soll: die Suchleiste, ein Feld unter dem
       Zeiger, eine Kachel beim Überfahren. Sie stand vorher als feste Farbe an sieben Stellen
       im Blatt – und blieb damit im Dunkeln hell. */
    --rand-stark: #CBD6E2;
    --rand-staerker: #A9BCD0;

    --flaeche: #FFFFFF;
    --flaeche-blass: #F7F9FB;
    --flaeche-grau: #EFF2F6;

    /* Statusfarben in zwei Stärken: kräftig für Punkte und Balken, blass als Grund unter
       dunkler Schrift. Volltonfarbige Pillen in einer langen Liste schreien; ein blasser
       Grund mit dunkler Schrift ist ruhiger und besser lesbar. */
    --gruen: #4E9A6A;
    --gruen-dunkel: #2F6B44;
    --gruen-blass: #E6F4EC;
    --gelb: #D9A227;
    --gelb-dunkel: #8A6218;
    --gelb-blass: #FBF2DC;
    --rot: #D95C5C;
    --rot-dunkel: #A83A3A;
    --rot-blass: #FBE9E9;

    /* Die Wandarten der Gebäudeaufnahme als Punkt vor der Auswahl – im Hellen dieselben Töne wie
       in der Zeichnung (Grundrisszeichnung.Farbe), die auf weißem Grund steht. Im Dunkeln heller,
       sonst verschwände der Navy-Punkt der Außenwand auf der Karte. */
    --wand-aussen: #1B2E3C;
    --wand-innen: #7A8A99;
    --wand-unbeheizt: #3D6FA8;
    --wand-offen: #C2410C;
    --slate: #5F7383;
    --slate-blass: #ECF0F4;
    --navy-blass: #E8EDF3;
    --grau: #E7E9ED;

    /* Die Fläche der Meldeleiste über einem neuen Programmstand. Ein eigener Ton und nicht
       `--primaer`: Der ist die Farbe der Knöpfe und kommt auf jedem Bildschirm vor; was auffallen
       soll, darf nicht aussehen wie das, was überall steht. Er ist in beiden Welten **derselbe** –
       die Leiste trägt weiße Schrift, und ein aufgehellter Ton für den Dunkelmodus verlöre
       genau den Kontrast, den sie dafür braucht (gemessen 5,1 : 1 gegen Weiß). */
    --meldung: #0A6FC7;

    --radius-klein: 8px;
    --radius: 10px;
    --radius-gross: 14px;

    /* Mehrschichtige, weiche Schatten statt einer harten Kante: näher an dem, was heutige
       Oberflächen zeigen, und sie halten die Flächen trotzdem klar getrennt. */
    --schatten: 0 1px 2px rgba(16, 47, 75, .05), 0 2px 6px rgba(16, 47, 75, .04);
    --schatten-mittel: 0 2px 4px rgba(16, 47, 75, .06), 0 8px 20px rgba(16, 47, 75, .07);
    --schatten-hoch: 0 12px 32px rgba(16, 47, 75, .14), 0 2px 8px rgba(16, 47, 75, .08);

    /* Ein Fokusring für alles Bedienbare – sichtbar, aber nicht schreiend. */
    --ring: 0 0 0 3px rgba(13, 135, 242, .22);

    --nav-breite: 232px;
    --kopf-hoehe: 64px;

    /* Was der Browser selbst zeichnet – Kalender- und Uhrsymbol im Datumsfeld, das aufklappende
       Kalenderblatt, die Liste eines Klappfelds, Rollbalken –, färbt er nicht nach unseren Token,
       sondern nach dieser Angabe. Sie wechselt deshalb mit ihnen, im dunklen Block unten. */
    color-scheme: light;
}

/* ---------- Dunkle Oberfläche ----------
   Die Außendienst-App hat sie seit je (`Farben.xaml` führt sieben eigene Dunkelwerte); die
   Weboberfläche hatte keine. Wer morgens im dunklen Fahrzeug das Tablet nimmt, bekam in der App
   die dunkle Oberfläche und im Browser desselben Geräts die helle.

   **Nur die Token werden getauscht, keine Regel weiter unten.** Das ganze Stilblatt greift
   ohnehin über die Variablen zu; eine zweite Regel je Bauteil wäre die zweite Wahrheit, gegen
   die dieses Haus überall sonst argumentiert. Die Werte sind die der App – abgeschrieben und
   nicht neu erfunden, damit Gerät und Browser gleich aussehen.

   **Nach der Wahl des Benutzers, nicht nach der des Systems.** Sie hing zuerst an
   `prefers-color-scheme` – das war die billigste Lösung und die falsche Stelle: Ein Monteur,
   dessen Telefon dauerhaft dunkel steht, bekam die dunkle Oberfläche auch mittags auf der
   hellen Baustelle, und wer sie umgekehrt abends wollte, musste sein Betriebssystem umstellen.
   Jetzt entscheidet `Mitarbeiter.Thema` (hell / dunkel / nach der Uhr), und das Ergebnis steht
   als `data-thema` am Wurzelelement – gesetzt von `Dienste/Themazustand.cs`, gerechnet von
   `Handwerk.Shared/Farbwahl.cs`.

   **Ein Selektor und keine Medienabfrage daneben.** Zwei Wege in dieselben Token (Systemwahl
   *und* Benutzerwahl) hießen, den ganzen Satz doppelt zu pflegen – und beim ersten neuen Ton
   liefen sie auseinander. */
:root[data-thema="dunkel"] {
    --text: #D7DCE2;
    --text-stark: #F2F5F8;
    --text-schwach: #96A0AC;

    --flaeche: #132430;
    --flaeche-blass: #0D1A24;
    --flaeche-grau: #1B2E3C;

    --rand: #263B4B;
    --rand-zart: #1E3240;
    --rand-stark: #35526A;
    --rand-staerker: #466882;

    /* Die Seitenleiste war schon dunkel – sie rückt nur eine Stufe tiefer, sonst stünde sie
       heller da als die Arbeitsfläche daneben. */
    --navy: #0E2432;
    --navy-hell: #16384D;
    --navy-tief: #091A25;

    /* Verweise brauchen im Dunkeln einen hellen Ton – gemessen gegen Karte und Marke. */
    --verweis: #7DBBF7;
    --navy-schrift: #A9C7E3;

    /* Das Blau wird eine Spur heller: Auf dunklem Grund verliert der Ausgangston zu viel
       Kontrast, und an ihm hängt jeder Knopf, der etwas auslöst. */
    --primaer: #3D9BF5;
    --primaer-dunkel: #2B85DB;
    --primaer-blass: #16304A;

    /* Die blassen Töne sind im Hellen fast weiß – im Dunkeln müssen sie fast schwarz sein,
       sonst leuchtet ein Hinweisband heller als die Seite. */
    --gruen-blass: #14312270;
    --gelb-blass: #3A2E1070;
    --rot-blass: #3A1C1C70;
    --wand-aussen: #C9D6E2;
    --wand-innen: #8B9BAB;
    --wand-unbeheizt: #6AA0DC;
    --wand-offen: #F08A4B;
    --slate-blass: #1B2E3C;
    --navy-blass: #16293A;
    --grau: #22323F;

    /* Die hellen Varianten tragen auf dunklem Grund nicht mehr – dort gilt der Grundton. */
    --gruen-dunkel: #6FBF8C;
    --gelb-dunkel: #E0B84A;
    --rot-dunkel: #E88080;

    /* Schatten auf dunklem Grund sieht man nicht; was die Fläche abheben muss, tut es über
       den Rand. Hier bleibt nur ein Hauch Tiefe. */
    --schatten: 0 1px 2px rgba(0, 0, 0, .28);
    --schatten-mittel: 0 2px 6px rgba(0, 0, 0, .34);
    --schatten-hoch: 0 12px 32px rgba(0, 0, 0, .46);
    --ring: 0 0 0 3px rgba(61, 155, 245, .3);

    /* **Ohne diese Zeile blieb alles, was der Browser selbst zeichnet, hell** – aus dem Betrieb
       gemeldet als „Datum und Zeitauswahl sind im dunklen Modus schwarz“: Das Kalendersymbol
       stand fast schwarz auf `--flaeche`, das aufklappende Blatt weiß über der dunklen Maske.
       Die Token tauschen nur, was wir malen; der Rest folgt dieser einen Angabe. */
    color-scheme: dark;
}

/* Die Vorschau neben der Belegmaske (`Belegvorschau`) ist Papier und bleibt im Dunkeln hell –
   wie das gedruckte Blatt und das PDF im Betrachter. Darum gelten in ihr die Werte der hellen
   Welt: genau die Token, die der dunkle Block umdefiniert, mit ihrem hellen Wert.
   `BelegvorschauTests` hält beide Listen zusammen – ein neues dunkles Token ohne Gegenstück
   hier färbte das Blatt still dunkel. */
:root[data-thema="dunkel"] .belegvorschau__papier {
    color-scheme: light;
    --navy: #102F4B;
    --navy-hell: #1B4670;
    --navy-tief: #0B2337;
    --verweis: #1B4670;
    --navy-schrift: #102F4B;
    --primaer: #0D87F2;
    --primaer-dunkel: #0A6FC7;
    --primaer-blass: #E7F2FE;
    --text: #3C434A;
    --text-stark: #17212B;
    --text-schwach: #7E8896;
    --rand: #E3E7EC;
    --rand-zart: #EDF0F4;
    --rand-stark: #CBD6E2;
    --rand-staerker: #A9BCD0;
    --flaeche: #FFFFFF;
    --flaeche-blass: #F7F9FB;
    --flaeche-grau: #EFF2F6;
    --gruen-dunkel: #2F6B44;
    --gruen-blass: #E6F4EC;
    --gelb-dunkel: #8A6218;
    --gelb-blass: #FBF2DC;
    --rot-dunkel: #A83A3A;
    --rot-blass: #FBE9E9;
    --wand-aussen: #1B2E3C;
    --wand-innen: #7A8A99;
    --wand-unbeheizt: #3D6FA8;
    --wand-offen: #C2410C;
    --slate-blass: #ECF0F4;
    --navy-blass: #E8EDF3;
    --grau: #E7E9ED;
    --schatten: 0 1px 2px rgba(16, 47, 75, .05), 0 2px 6px rgba(16, 47, 75, .04);
    --schatten-mittel: 0 2px 4px rgba(16, 47, 75, .06), 0 8px 20px rgba(16, 47, 75, .07);
    --schatten-hoch: 0 12px 32px rgba(16, 47, 75, .14), 0 2px 8px rgba(16, 47, 75, .08);
    --ring: 0 0 0 3px rgba(13, 135, 242, .22);
}

/* Bilder und Zeichnungen kommen auf weißem Grund aus dem Server – Belegvorschau, Logo,
   Bauteilzeichnung. Sie werden nicht eingefärbt: Ein invertiertes Fenstermaß ist kein
   Fenstermaß mehr.

   **Die eine Stelle, an der ein fester Wert richtig ist.** Hier stand `var(--flaeche)`, und das
   ist im Dunkeln dunkel – also genau die Farbe, vor der eine Bauteilzeichnung mit ihren dunklen
   Strichen verschwindet. Der Inhalt ist nicht mitgetauscht worden, also darf sein Grund es auch
   nicht: Er bleibt hell, und zwar in beiden Farbwelten derselbe. */
:root[data-thema="dunkel"] .vorschau img,
:root[data-thema="dunkel"] .zeichnung,
:root[data-thema="dunkel"] .belegbild,
:root[data-thema="dunkel"] .profilbild__bilder,
:root[data-thema="dunkel"] .fensterliste__bild {
    background: #FFFFFF;
    border-radius: var(--radius-klein);
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
}

body {
    font-family: Rubik, "Segoe UI", system-ui, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text);
    background: var(--flaeche);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; color: var(--text-stark); }
h1 { font-size: 26px; letter-spacing: -.02em; }
h2 { font-size: 18px; letter-spacing: -.01em; }
h3 { font-size: 15px; }

a {
    color: var(--primaer);
    text-decoration: none;
    text-underline-offset: 2px;
}

a:hover { text-decoration: underline; }

/* Zahlen in gleicher Breite. In einer Rechnungsliste stehen die Betraege damit untereinander
   auf der Stelle, statt je nach Ziffer zu wandern – der Unterschied faellt erst auf, wenn
   man es einmal richtig gesehen hat. */
table.tabelle,
.kennzahl__wert,
.summenblock,
.geld,
.zelle-rechts {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* ---------- Startanzeige ---------- */
.start-lader {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
}

.start-lader__ring,
.lade-ring {
    width: 26px;
    height: 26px;
    border: 2px solid var(--rand);
    border-top-color: var(--slate);
    border-radius: 50%;
    animation: dreh .8s linear infinite;
}

@keyframes dreh { to { transform: rotate(360deg); } }

.lade-flaeche {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 64px 0;
}

/* Der Schleier über dem ganzen Bildschirm, solange etwas läuft, das man nicht unterbrechen soll
   (Komponenten/Ladeschleier.razor). Derselbe Grund wie unter einem Dialog, damit er nach der
   Anwendung aussieht und nicht nach einem Absturz. */
.ladeschleier {
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgba(11, 35, 55, .42);
    backdrop-filter: blur(2px);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    animation: dialog-grund .15s ease-out;
}

.ladeschleier__karte {
    background: var(--flaeche);
    color: var(--text);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten-hoch);
    padding: 28px 32px;
    max-width: 420px;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    text-align: center;
}

.ladeschleier__ring { width: 36px; height: 36px; border-width: 3px; border-top-color: var(--primaer); }
.ladeschleier__titel { font-weight: 600; font-size: 16px; }
.ladeschleier__text { color: var(--text-schwach); font-size: 13px; overflow-wrap: anywhere; }

/* Die Wartetafel für lange Vorgänge (`Wartetafel.razor`). Über Seite **und** Dialog (der Dialog
   steht auf 60): Ein Katalogabruf startet in der Lieferantenmaske, und die Tafel darunter sähe
   niemand. Der Schleier ist der des Dialogs – dieselbe Geste für „hier geht gerade nichts“. */
.wartetafel {
    position: fixed;
    inset: 0;
    z-index: 85;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(11, 35, 55, .42);
    backdrop-filter: blur(2px);
    animation: dialog-grund .16s ease-out;
}

.wartetafel__karte {
    background: var(--flaeche);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten-hoch);
    width: min(420px, 100%);
    padding: 28px 24px 22px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    text-align: center;
}

.lade-ring.wartetafel__ring {
    width: 40px;
    height: 40px;
    border-width: 3px;
    border-top-color: var(--primaer);
    margin-bottom: 6px;
}

.wartetafel__titel { font-size: 16px; font-weight: 600; color: var(--text); }
.wartetafel__text { font-size: 13px; color: var(--text-schwach); line-height: 1.45; }

/* Ziffern gleicher Breite – sonst springt die Zeile jede Sekunde um einen halben Buchstaben. */
.wartetafel__zeit {
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    color: var(--text);
    margin-top: 4px;
}

.wartetafel__hinweis { font-size: 12px; color: var(--text-schwach); }

/* Wer weniger Bewegung wünscht, bekommt einen langsamen Kreisel statt keinen: Ganz ohne
   Bewegung sähe die Tafel wieder aus wie eine stehengebliebene Seite. */
@media (prefers-reduced-motion: reduce) {
    .lade-ring.wartetafel__ring { animation-duration: 2.4s; }
}

/* ---------- Grundgerüst ---------- */
.huelle {
    display: flex;
    min-height: 100vh;
}

.nav {
    width: var(--nav-breite);
    flex: 0 0 var(--nav-breite);

    /* Ein sehr flacher Verlauf gibt der Leiste Tiefe, ohne dass es auffällt. */
    background: linear-gradient(180deg, var(--navy) 0%, var(--navy-tief) 100%);
    color: var(--nav-text);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, .18) transparent;
}

.nav__marke {
    display: flex;
    align-items: center;
    gap: 10px;
    height: var(--kopf-hoehe);
    padding: 0 16px;
    flex: 0 0 var(--kopf-hoehe);
}

/* Das X der Marke allrounderX – dasselbe Zeichen wie auf dem Symbol der Außendienst-App und
   dem installierbaren Symbol. Abgezeichnet aus der Logovorlage der Website: zwei
   Parallelogramme mit waagerechten Kanten oben und unten, 44 mal 48 Einheiten, der Balken 15
   breit, die Schräge um 28 Einheiten versetzt, der vordere dunkler und über dem hinteren. Die
   Herkunft und der Grund für den verkürzten Verlauf stehen in
   src/Handwerk.App/Resources/AppIcon/appiconfg.svg.

   **Geschnitten und nicht gedreht.** Zwei gekippte Rechtecke wären in CSS kürzer, stünden aber
   mit schrägen Enden da – das ist ein anderes Zeichen. Die Hundertstel unten sind die Punkte
   der Vorlage, umgerechnet auf die 26 Punkte der Leiste (das Zeichen ist 24 davon breit und
   sitzt mittig, deshalb beginnt die Skala bei 4,17 Prozent und nicht bei null).

   Die Farben stehen hier als Werte und nicht als Token: Sie gehören der Marke und nicht der
   Oberfläche – ein Token dafür wäre eines, das nur an einer Stelle gilt. */
.nav__zeichen {
    width: 26px;
    height: 26px;
    position: relative;
    flex: 0 0 26px;
}

.nav__zeichen::before,
.nav__zeichen::after {
    content: "";
    position: absolute;
    inset: 0;
}

.nav__zeichen::before {
    clip-path: polygon(64.58% 0, 95.83% 0, 37.5% 100%, 6.25% 100%);
    background: linear-gradient(180deg, #4FD0FF 0%, #1A7BFF 100%);
}

.nav__zeichen::after {
    clip-path: polygon(4.17% 0, 35.42% 0, 95.83% 100%, 64.58% 100%);
    background: linear-gradient(180deg, #00B9FE 0%, #0066FD 100%);
}

/* Die Wortmarke wie im Logo von allrounderX: das Wort kräftig und eng gesetzt, das X gleich
   dahinter und etwas größer als die Buchstaben. Ein gemeinsamer Halter, damit der Abstand
   zwischen Wort und X der des Logos ist und nicht der der Leiste. */
.nav__name {
    display: inline-flex;
    align-items: center;
    gap: 1px;
}

.nav__wort {
    font-size: 19px;
    font-weight: 700;
    color: #fff;
    letter-spacing: -.4px;
}

.nav__liste {
    list-style: none;
    margin: 6px 0 0;
    padding: 0 8px;
    flex: 1 1 auto;
}

/* Der aktive Punkt ist eine abgerundete Fläche statt eines Blocks mit Randstreifen – das
   ist die Form, die heute jede Seitenleiste hat, und sie lässt die Leiste luftiger wirken. */
.nav__punkt {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    margin: 1px 0;
    border-radius: var(--radius-klein);
    color: var(--nav-text);
    font-size: 14px;
    cursor: pointer;
    transition: background .14s ease, color .14s ease;
}

.nav__punkt:hover {
    background: rgba(255, 255, 255, .07);
    color: #fff;
    text-decoration: none;
}

.nav__punkt.aktiv {
    background: rgba(255, 255, 255, .12);
    color: #fff;
    font-weight: 500;
    box-shadow: inset 3px 0 0 var(--akzent);
}

.nav__punkt svg { flex: 0 0 18px; opacity: .8; }
.nav__punkt.aktiv svg { opacity: 1; }

/* ---------- Die Zeile: Sprung und Neuanlage nebeneinander ----------
   Der Sprung nimmt, was übrig bleibt; das Pluszeichen steht rechts. `min-width: 0` am Sprung,
   damit ein langes Wort ihn kürzt, statt das Pluszeichen aus der Leiste zu schieben –
   „Leistungsverzeichnisse" ist hier das Maß. */
.nav__zeile {
    display: flex;
    align-items: center;
    gap: 2px;
}

.nav__zeile > .nav__punkt,
.nav__zeile > .nav__unterpunkt {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* **Das Pluszeichen steht immer da, nur blass.** Nur beim Überfahren einzublenden wäre ruhiger
   und wäre ein Bedienweg, den man durch Ausprobieren finden muss – dieselbe Überlegung wie beim
   Ziehhinweis des Schnellzugriffs. Blass zeigt, dass es ihn gibt; kräftig wird er, sobald die
   Zeile gemeint ist. */
.nav__neu {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 26px;
    width: 26px;
    height: 26px;
    border-radius: var(--radius-klein);
    color: var(--nav-text);
    opacity: .45;
    transition: opacity .14s ease, background .14s ease, color .14s ease;
}

.nav__zeile:hover .nav__neu { opacity: .8; }

.nav__neu:hover,
.nav__neu:focus-visible {
    opacity: 1;
    background: rgba(255, 255, 255, .14);
    color: #fff;
    text-decoration: none;
}

/* Am Unterpunkt eine Spur kleiner – er ist selbst kleiner gesetzt, und ein gleich großes
   Zeichen daneben wöge schwerer als die Zeile, zu der es gehört. */
.nav__unterliste .nav__neu { flex-basis: 24px; width: 24px; height: 24px; }

/* **Eingeklappt fällt es weg.** In sechzig Pixeln steht das Symbol des Punktes, und daneben
   passt nichts mehr; ein Pluszeichen, das dort das Wort verdrängt, nähme der Leiste genau das,
   wofür sie eingeklappt wurde. */
.nav--schmal .nav__neu { display: none; }

/* Mit dem Finger gilt das Hausmaß: mindestens 40 × 40 für einen kleinen Symbolknopf, wie am
   Fragezeichen und am Schließkreuz. Sechsundzwanzig Pixel trifft am Schreibtisch jede Maus und
   auf dem Tablet niemand. */
@media (pointer: coarse) {
    .nav__neu,
    .nav__unterliste .nav__neu {
        flex-basis: 40px;
        width: 40px;
        height: 40px;
    }

    /* Auf dem Tablet gibt es kein Überfahren – was nur beim Hover kräftig wird, bleibt dort für
       immer blass. */
    .nav__neu { opacity: .8; }
}

.nav__unterliste {
    list-style: none;
    margin: 2px 0 6px;
    padding: 0;
}

.nav__unterpunkt {
    display: block;
    padding: 7px 12px 7px 42px;
    border-radius: var(--radius-klein);
    color: var(--nav-text);
    font-size: 13px;
}

.nav__unterpunkt:hover { background: rgba(255, 255, 255, .05); }

.nav__unterpunkt:hover { color: #fff; text-decoration: none; }
.nav__unterpunkt.aktiv { color: #fff; font-weight: 500; }

.nav__marker {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--primaer);
    margin-right: 8px;
    vertical-align: middle;
}

/* ---------- Die eingeklappte Menüleiste ----------
   Eine Schiene aus Symbolen statt einer Spalte mit Wörtern. Die Leiste ist 232 Pixel breit;
   auf einem Tablet im Hochformat (768) ist das fast ein Drittel der Arbeitsfläche, und es ist
   der Unterschied zwischen drei und fünf sichtbaren Tabellenspalten.

   Die Breite steht an einer Stelle – der Variablen –, damit Leiste und Marke nicht
   auseinanderlaufen. Was wegfällt, wird nicht verkleinert, sondern ausgeblendet: Ein Wort in
   sieben Pixeln ist kein Wort mehr, nur ein grauer Strich. */
.nav__klappe {
    background: none;
    border: none;
    color: var(--nav-text);
    cursor: pointer;
    padding: 6px;
    margin-left: auto;
    display: flex;
    border-radius: var(--radius-klein);
}

.nav__klappe:hover { color: #fff; background: rgba(255, 255, 255, .08); }

.nav--schmal {
    --nav-breite: 60px;
    width: 60px;
    flex: 0 0 60px;
}

/* Die Marke wird zum Zeichen, und der Knopf rutscht darunter: nebeneinander bliebe in
   vierundsechzig Pixeln für keines von beiden genug Platz. */
.nav--schmal .nav__marke {
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    height: auto;
    flex: 0 0 auto;
    padding: 10px 0;
}

/* Eingeklappt bleibt das Symbol und sonst nichts. Ein auf „Tages…" gekürztes Wort ist kein
   Wort mehr, sondern ein Fleck, der Platz kostet; wer den Namen braucht, bekommt ihn über den
   `title` am Punkt. */
.nav--schmal .nav__wort,
.nav--schmal .nav__unterliste,
.nav--schmal .nav__punkt span { display: none; }

.nav--schmal .nav__klappe { margin-left: 0; }

.nav--schmal .nav__liste { padding: 6px 6px 0; }

/* Vierundvierzig Pixel hoch: Das ist die Fläche, die ein Finger sicher trifft. Am Schreibtisch
   fällt sie nicht auf, auf dem Tablet ist sie der Unterschied zwischen treffen und danebentippen. */
.nav--schmal .nav__punkt {
    justify-content: center;
    gap: 0;
    padding: 0;
    min-height: 44px;
    box-shadow: none;
}

.nav--schmal .nav__punkt.aktiv {
    box-shadow: none;
    background: rgba(255, 255, 255, .14);
}

/* ---------- Bedienung mit dem Finger ----------
   Gilt nur, wo der Zeiger grob ist: Tablet und Telefon. Der Bürorechner mit Maus bleibt
   unberührt – dort wäre alles vierundvierzig Pixel hoch nur aufgeblasen.

   Vierundvierzig ist die Fläche, die ein Finger sicher trifft; die Außendienst-App rechnet aus
   demselben Grund mit achtundvierzig Punkten. Angefasst wird die **Höhe**, nicht die
   Schriftgröße: Ein Formular, dessen Schrift auf dem Tablet größer ist als am Rechner, sieht
   nach zwei verschiedenen Programmen aus. */
@media (pointer: coarse) {
    .knopf { height: 44px; }
    .knopf--klein { height: 38px; padding: 0 15px; }

    .feld,
    select.feld,
    input.feld,
    .suche input { height: 44px; }

    /* Ein Haken von vierzehn Pixeln trifft niemand. Die Fläche wächst, das Zeichen nicht. */
    input[type="checkbox"],
    input[type="radio"] { width: 20px; height: 20px; }

    /* Zeilen in Listen sind Sprungziele – auch sie brauchen Fläche unter dem Finger. */
    .tabelle tbody td { padding-top: 11px; padding-bottom: 11px; }

    .nav__punkt { min-height: 44px; }

    /* Die kleinen Symbolknöpfe sind die schlimmsten Ziele: das Fragezeichen misst 24 Pixel,
       das Kreuz zum Schließen 29. Das **Zeichen** bleibt klein – nur die Fläche darum wächst,
       sonst sähe der Dialogkopf auf dem Tablet anders aus als am Rechner. */
    .hilfeknopf,
    .schliessen,
    .nav__klappe,
    .benutzermenue__knopf {
        min-width: 40px;
        min-height: 40px;
        justify-content: center;
    }
}

/* ---------- Kopfband mit globaler Suche ---------- */
/* Die Leiste steht über jeder Seite und bleibt beim Blättern stehen: gesucht wird meistens
   mitten in einer anderen Arbeit, oft mit dem Telefon am Ohr. */
/* Ein Raster und kein zentriertes Flex: Rechts steht seit dem Umzug des Benutzermenüs ein
   zweites Kind, und in einem zentrierten Flex schöbe es die Suchleiste nach links – sichtbar
   um genau die Breite des Namens, der daneben steht. Die erste Spalte nimmt den Platz, die
   zweite so viel, wie das Menü braucht; die Suchleiste bleibt in ihrer Spalte mittig. */
/* `minmax(0, 1fr)` und nicht `1fr`: Eine Rasterspalte ist von sich aus mindestens so breit wie
   ihr Inhalt, und der Inhalt ist hier ein Eingabefeld – das bringt seine eigene Mindestbreite
   mit (rund zwanzig Zeichen) und lässt sich dadurch nicht schmaler ziehen. Auf einem Telefon
   schob es deshalb das Benutzermenü über den rechten Rand hinaus; gemessen bei 375 Pixeln mit
   eingeklappter Leiste waren es 59 Pixel. Dieselbe Falle wie das `min-width: 0` am Seitenkopf. */
/* Die Hülle klebt, nicht das Kopfband selbst – die Meldung über einen neuen Programmstand
   gehört mit nach oben und soll nicht hinter der Liste verschwinden. Ein `top` in Pixeln an
   der Meldung wäre die Alternative gewesen und die schlechtere: Die Höhe des Kopfbands hängt
   an der Feldhöhe, und die wächst auf dem Tablet mit dem groben Zeiger – eine abgeschriebene
   Zahl liefe dort um sechs Pixel daneben. */
.kopfbereich {
    position: sticky;
    top: 0;
    z-index: 40;
}

/* Drei Spalten: Suche, Glocke, eigenes Konto. Glocke und Konto nehmen nur, was sie brauchen. */
.kopfband {
    display: grid;
    /* Suche, dann die Knöpfe – so viele, wie dastehen. Mit festen Spalten stünde der
       Mikrofonknopf, der nur bei eingerichteter Sprache erscheint, sonst in einer leeren Spalte. */
    grid-template-columns: minmax(0, 1fr);
    grid-auto-flow: column;
    grid-auto-columns: auto;
    align-items: center;
    gap: 16px;
    padding: 12px 26px;

    /* Der Grund ist leicht getönt und trägt einen Hauch Navy, damit die weiße Leiste
       darauf sichtbar aufliegt statt mit dem Kopf der Seite zu verschwimmen. */
    background: linear-gradient(180deg, var(--flaeche-blass) 0%, var(--flaeche-grau) 100%);
    border-bottom: 1px solid var(--rand);
}

.suchleiste {
    position: relative;
    width: 100%;
    max-width: 760px;
    justify-self: center;
}

/* ---------- Das Benutzermenü im Kopfband ----------
   Das eigene Konto: Name, Passwort, App-Code, Abmelden. Es stand bis zuletzt im Fuß der
   Menüleiste; oben rechts ist die Stelle, an der jeder es sucht.

   `position: relative` trägt die aufgeklappte Tafel. Sie hängt am Menü und nicht am Kopfband,
   damit sie rechtsbündig unter dem Knopf steht und nicht unter der Suchleiste. */
.benutzermenue {
    position: relative;
    flex: 0 0 auto;
}

.benutzermenue__knopf {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 46px;
    padding: 0 12px 0 8px;
    background: var(--flaeche);
    border: 2px solid var(--rand-stark);
    border-radius: 999px;
    color: var(--text);
    font-size: 14px;
    cursor: pointer;
    transition: border-color .12s ease;
}

/* Dieselbe Höhe und derselbe Rand wie das Suchfeld daneben: Zwei Bedienelemente in einer
   Zeile, die sich in Höhe oder Rundung unterscheiden, lesen sich wie zwei Programme. */
.benutzermenue__knopf:hover,
.benutzermenue__knopf.offen { border-color: var(--rand-staerker); }

.benutzermenue__name {
    max-width: 130px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.benutzermenue__pfeil { color: var(--text-schwach); flex: 0 0 auto; }

/* Der Schleier fängt den Klick daneben ab – dasselbe Mittel wie unter der Trefferliste. */
.benutzermenue__schleier {
    position: fixed;
    inset: 0;
    z-index: 45;
}

.benutzermenue__tafel {
    position: absolute;
    z-index: 50;
    top: calc(100% + 8px);
    right: 0;
    min-width: 248px;
    padding: 6px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    box-shadow: var(--schatten-hoch);
}

.benutzermenue__kopf {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px 12px;
    border-bottom: 1px solid var(--rand);
    margin-bottom: 6px;
}

/* Der Textblock nimmt den Platz, das Fragezeichen rechts daneben nur seine eigene Breite. */
.benutzermenue__kopftext {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1 1 auto;
}

/* Mailadresse und Rolle können lang sein; die Tafel soll davon nicht breiter werden. */
.benutzermenue__kopftext strong,
.benutzermenue__kopftext span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.benutzermenue__kopftext span {
    font-size: 12px;
    color: var(--text-schwach);
}

.benutzermenue__rolle { font-size: 11px; }

.benutzermenue__punkt {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 10px;
    background: none;
    border: none;
    border-radius: var(--radius-klein);
    color: var(--text);
    font-size: 14px;
    text-align: left;
    cursor: pointer;
}

.benutzermenue__punkt:hover { background: var(--flaeche-blass); }

.benutzermenue__punkt svg { color: var(--text-schwach); flex: 0 0 auto; }

/* Abmelden trägt als einziger Punkt eine Farbe – er ist der eine, der etwas beendet. */
.benutzermenue__punkt--weg,
.benutzermenue__punkt--weg svg { color: var(--rot); }

.benutzermenue__trenner {
    height: 1px;
    background: var(--rand);
    margin: 6px 0;
}

/* ---------- Die Glocke im Kopfband ----------
   Rund und so hoch wie das Suchfeld und das Konto daneben – drei Bedienelemente in einer Zeile,
   die sich in Höhe oder Rand unterscheiden, lesen sich wie zwei Programme. Die Zahl sitzt oben
   rechts auf dem Rand, in der Farbe, die hier „braucht Sie“ heißt. */
.nachrichtenglocke { position: relative; }

/* Der Sprachassistent – dieselbe runde Form wie die Glocke daneben, damit das Kopfband eine
   Reihe gleicher Griffe bleibt. Offen trägt er die Farbe des Handelns; wer spricht, sieht es
   zusätzlich an der Sprachleiste darunter. */
.sprachknopf {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    padding: 0;
    background: var(--flaeche);
    border: 2px solid var(--rand-stark);
    border-radius: 999px;
    color: var(--text);
    cursor: pointer;
    transition: border-color .12s ease, background-color .12s ease;
}

.sprachknopf:hover { border-color: var(--rand-staerker); }
.sprachknopf:disabled { cursor: progress; opacity: .7; }

/* Der dunklere Blauton und nicht `--primaer`: Weiß auf dem hellen Blau der Dunkelfassung kommt
   nur auf 2,9 : 1 – für ein Symbol ohne Wort zu wenig. Gemessen: hell 5,1 : 1, dunkel 3,8 : 1. */
.sprachknopf--an,
.sprachknopf--an:hover {
    background: var(--primaer-dunkel);
    border-color: var(--primaer-dunkel);
    color: var(--text-invers);
}

.sprachknopf--verbindet { border-color: var(--primaer); }

.sprachleiste--meldung { border-left-color: var(--rand-staerker); }

.nachrichtenglocke__knopf {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    padding: 0;
    background: var(--flaeche);
    border: 2px solid var(--rand-stark);
    border-radius: 999px;
    color: var(--text);
    cursor: pointer;
    transition: border-color .12s ease;
}

.nachrichtenglocke__knopf:hover,
.nachrichtenglocke__knopf.offen { border-color: var(--rand-staerker); }

.nachrichtenglocke__zahl {
    position: absolute;
    top: -5px;
    right: -5px;
    min-width: 20px;
    height: 20px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--rot);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
    border: 2px solid var(--flaeche);
}

.nachrichtenglocke__tafel {
    position: absolute;
    z-index: 50;
    top: calc(100% + 8px);
    right: 0;
    width: min(380px, calc(100vw - 32px));
    padding: 6px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    box-shadow: var(--schatten-hoch);
}

.nachrichtenglocke__kopf {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px 10px;
    border-bottom: 1px solid var(--rand);
}

.nachrichtenglocke__kopf strong { flex: 1 1 auto; }
.nachrichtenglocke__kopf .zelle-schwach { font-size: 12px; }

.nachrichtenglocke__leer { padding: 16px 10px; font-size: 13px; }

.nachrichtenglocke__liste {
    list-style: none;
    margin: 0;
    padding: 4px 0;
    max-height: 340px;
    overflow-y: auto;
}

.nachrichtenglocke__zeile {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 4px;
}

.nachrichtenglocke__sprung {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
    padding: 7px 6px;
    background: none;
    border: none;
    border-radius: var(--radius-klein);
    font: inherit;
    color: var(--text);
    text-align: left;
    cursor: pointer;
}

.nachrichtenglocke__sprung:hover { background: var(--flaeche-blass); }

.nachrichtenglocke__titel,
.nachrichtenglocke__zusatz {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nachrichtenglocke__titel { font-size: 14px; font-weight: 600; }
.nachrichtenglocke__zusatz { font-size: 12px; color: var(--text-schwach); }

.nachrichtenglocke__mehr { padding: 4px 10px 8px; font-size: 12px; }

.nachrichtenglocke__wege {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding: 10px;
    border-top: 1px solid var(--rand);
    font-size: 12px;
}

.nachrichtenglocke__weg {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    line-height: 1.5;
}

.nachrichtenglocke__weg svg { flex: 0 0 auto; margin-top: 1px; color: var(--gruen); }

.nachrichtenglocke__fussnote { font-size: 12px; line-height: 1.5; }

/* Das Kalender-Abo: Link und Kopierknopf in einer Zeile, der Link nimmt den Rest. */
.kalenderabo__zeile { display: flex; gap: 8px; }
.kalenderabo__zeile .feld { flex: 1 1 auto; min-width: 0; font-family: ui-monospace, monospace; font-size: 12px; }

.kalenderabo__wege {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 4px;
    font-size: 12px;
}

.kalenderabo__frage {
    flex: 1 1 auto;
    font-size: 13px;
    color: var(--text-gedaempft);
}

/* Auf schmalen Geräten bleibt der Avatar und sonst nichts: Der Vorname kostet dort die Hälfte
   dessen, was die Suchleiste noch hat – und wer sein eigenes Kürzel sieht, weiß, wer er ist. */
@media (max-width: 720px) {
    .benutzermenue__name,
    .benutzermenue__pfeil { display: none; }

    .benutzermenue__knopf { padding: 0 8px; }

    /* Drei Elemente im Kopfband: Der halbe Abstand gibt der Suche zwei Zeichen zurück. */
    .kopfband { column-gap: 8px; }

    /* Die Tafel hängt am Fenster und nicht an der Glocke: Rechtsbündig unter ihr ragte sie auf
       dem Telefon 35 Pixel links aus dem Bild – die Glocke steht dort nicht am Rand. */
    .nachrichtenglocke__tafel {
        position: fixed;
        top: calc(var(--kopfbereich-hoehe, 70px) + 4px);
        left: 16px;
        right: 16px;
        width: auto;
    }
}

/* Das Feld ist absichtlich größer als ein gewöhnliches Eingabefeld: es ist der Weg zu
   allem, und wer zum ersten Mal vor dem Programm sitzt, soll es zuerst sehen. */
.suchleiste__feld {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 0 14px;
    height: 46px;
    background: var(--flaeche);
    border: 2px solid var(--rand-stark);
    border-radius: 999px;
    box-shadow: var(--schatten);
    transition: border-color .12s ease, box-shadow .12s ease;
}

.suchleiste__feld:hover { border-color: var(--rand-staerker); }

.suchleiste__feld:focus-within {
    border-color: var(--primaer);
    box-shadow: 0 0 0 4px var(--primaer-blass), 0 2px 10px rgba(13, 135, 242, .14);
}

/* Die Lupe trägt die Primärfarbe: ein Farbpunkt genügt, damit das Auge zuerst hier landet. */
.suchleiste__zeichen {
    color: var(--primaer);
    flex: 0 0 auto;
}

.suchleiste__eingabe {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    outline: 0;
    background: transparent;
    font: inherit;
    font-size: 15px;
    color: var(--text-stark);
}

.suchleiste__eingabe::placeholder { color: var(--text-schwach); }

/* Das Tastenkürzel steht im Feld, wo es gebraucht wird – und es tut auch etwas. */
.suchleiste__kuerzel {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 3px 8px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .02em;
    color: var(--slate);
    background: var(--flaeche-grau);
    border: 1px solid var(--rand);
    border-radius: 6px;
    white-space: nowrap;
}

.suchleiste__feld:focus-within .suchleiste__kuerzel { display: none; }

.suchleiste__eingabe::-webkit-search-cancel-button { display: none; }

.suchleiste__leeren {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: var(--text-schwach);
    cursor: pointer;
    padding: 4px;
    line-height: 0;
    border-radius: 50%;
}

.suchleiste__leeren:hover { background: var(--flaeche-grau); color: var(--text); }

.suchleiste__lader {
    flex: 0 0 auto;
    width: 14px;
    height: 14px;
    border: 2px solid var(--rand);
    border-top-color: var(--primaer);
    border-radius: 50%;
    animation: suchdreh .7s linear infinite;
}

@keyframes suchdreh { to { transform: rotate(360deg); } }

/* Der Schleier liegt hinter der Liste und fängt den Klick daneben ab. */
.suchleiste__schleier {
    position: fixed;
    inset: 0;
    z-index: 45;
}

/* **Das Feld liegt über der Fangfläche, solange die Liste offen steht.**

   Die Fläche deckt die ganze Seite ab – und damit fing sie auch den Klick ins Suchfeld ab.
   Solange erst das Tippen etwas aufklappte, fiel das nicht auf: Der Fokus war längst im Feld,
   und wer daneben klickte, wollte ohnehin schließen. Mit den Schnellzugriffen ist der Klick ins
   Feld die **erste** Handbewegung, und danach war die Liste beim zweiten Klick wieder weg – ohne
   dass ein dritter sie zurückgeholt hätte: Der Fokus hatte das Feld nie verlassen, also meldete
   sich `@onfocus` kein zweites Mal. Am Bildschirm sah das aus, als täte der Klick nichts.

   Gegenstück im Markup ist das `@onclick` am Feld: Nach `Esc` steht der Schreibpunkt weiter
   darin, und nur ein Klick soll die Liste wieder aufmachen. */
.suchleiste--offen .suchleiste__feld {
    position: relative;
    z-index: 46;
}

.suchleiste__liste {
    position: absolute;
    z-index: 50;
    top: calc(100% + 8px);
    left: 0;
    right: 0;
    max-height: 70vh;
    overflow-y: auto;
    padding: 6px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    box-shadow: var(--schatten-hoch);
}

/* Die Antwort auf eine Frage – Satz und die Lesart darunter. */
/* ---------- Hilfechat in der Suchleiste ----------

   Er steht über den Trefferzeilen und muss sich von ihnen absetzen, ohne sie zu erschlagen:
   eigener Grund, eine Linie darunter, und die Dringlichkeit als schmaler Streifen links. Die
   Farbe kommt nur vom Streifen – ein ganz rot hinterlegter Kasten in einer Suchliste liest sich
   wie ein Fehler der Suche. */
.suchleiste__hilfe {
    padding: 10px 10px 12px;
    background: var(--flaeche-blass);
    border-bottom: 1px solid var(--rand);
}

.suchleiste__hilfe-kopf {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-schwach);
    margin-bottom: 6px;
}

/* ---------- Dublettenhinweis ----------
   Die Kandidaten stehen als Knöpfe da und nicht als Aufzählung: Der Zweck des Hinweises ist
   nicht, dass jemand ihn liest, sondern dass er den vorhandenen Kunden nimmt. */
.dubletten {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 8px;
}

.dublette {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 2px 12px;
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    text-align: left;
    cursor: pointer;
}

.dublette:hover { border-color: var(--primaer); }

.dublette__name { font-weight: 600; color: var(--text-stark); font-size: 14px; }

.dublette__zusatz,
.dublette__gruende { grid-column: 1; font-size: 12px; color: var(--text-schwach); }

.dublette__gruende { font-style: italic; }

.dublette__nehmen {
    grid-row: 1 / span 3;
    grid-column: 2;
    align-self: center;
    font-size: 12px;
    font-weight: 600;
    color: var(--primaer);
    white-space: nowrap;
}

.suchleiste__hilfe-satz {
    margin: 0 0 10px;
    font-size: 13px;
    line-height: 1.55;
    color: var(--text-stark);
}

/* Der Platzhalter für den Einleitungssatz, solange das Sprachmodell ihn schreibt.

   **Zwei Balken in der Höhe von zwei Zeilen und nicht ein Drehrad:** Der Platz muss genau der
   sein, den der Satz danach einnimmt, sonst rückt der Befund beim Eintreffen nach unten – unter
   dem Auge dessen, der gerade die erste Zeile liest. Ein Rad hielte den Platz nicht.

   Die zweite Zeile ist kürzer, weil ein Satz selten auf der Zeile endet; das liest sich als
   Text, der noch kommt, und nicht als kaputte Fläche. */
.suchleiste__hilfe-satz--wartet {
    display: flex;
    flex-direction: column;
    gap: 5px;
    /* 2 Zeilen à 13px × 1,55 – dasselbe Maß wie der Satz darüber. */
    height: calc(13px * 1.55 * 2);
    justify-content: center;
}

.suchleiste__hilfe-satz--wartet span {
    display: block;
    height: 8px;
    border-radius: 4px;
    background: linear-gradient(90deg,
        var(--flaeche-grau) 0%, var(--rand) 40%, var(--flaeche-grau) 80%);
    background-size: 220% 100%;
    animation: suchwarten 1.1s ease-in-out infinite;
}

.suchleiste__hilfe-satz--wartet span:last-child { width: 62%; }

@keyframes suchwarten {
    from { background-position: 120% 0; }
    to { background-position: -60% 0; }
}

/* Wer Bewegung abbestellt hat, bekommt den Platzhalter still – der Platz bleibt, das Flimmern
   geht. Dieselbe Regel wie an der Standmeldung. */
@media (prefers-reduced-motion: reduce) {
    .suchleiste__hilfe-satz--wartet span { animation: none; }
}

.suchleiste__lage {
    padding: 8px 10px;
    margin-bottom: 8px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-left: 3px solid var(--rand);
    border-radius: var(--radius);
}

.suchleiste__lage--kritisch { border-left-color: var(--rot); }
.suchleiste__lage--wichtig { border-left-color: var(--gelb-dunkel); }
.suchleiste__lage--hinweis { border-left-color: var(--primaer); }

.suchleiste__lage-kopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
}

.suchleiste__stufe {
    flex: none;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--text-schwach);
}

.suchleiste__lage-lage {
    margin-top: 2px;
    font-size: 12px;
    color: var(--text-schwach);
}

/* Nummeriert, weil die Reihenfolge Teil der Aussage ist: Der erste Schritt begrenzt den
   Schaden. Eine Aufzählung mit Punkten läse sich wie eine Auswahl. */
.suchleiste__schritte {
    margin: 8px 0 0;
    padding-left: 18px;
    font-size: 12px;
    line-height: 1.6;
}

.suchleiste__schritte li { margin-bottom: 3px; }

.suchleiste__lage-fuss,
.suchleiste__sprungziele {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

.suchleiste__hilfelink,
.suchleiste__sprungziel {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    /* Die Farbe steht hier seit je – die Schrift fehlte. Diese Pillen sind teils Knöpfe, teils
       Verweise; ohne die Zeile standen „Mahnwesen" und „Zahlungsabgleich" in Arial neben dem
       Rubik der Zeile darüber. */
    font: inherit;
    font-size: 12px;
    color: var(--primaer);
    background: none;
    border: 1px solid var(--rand);
    border-radius: 999px;
    cursor: pointer;
    text-decoration: none;
}

.suchleiste__hilfelink:hover,
.suchleiste__sprungziel:hover { border-color: var(--primaer); }

/* Die Vorschläge der Bedeutungssuche. Ein gestrichelter Rand statt eines vollen: Sie sehen
   damit anders aus als ein Befund, und genau das sollen sie – sie teilen mit der Frage kein
   Wort und sind eine Vermutung. */
.suchleiste__nachbarn {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px dashed var(--rand);
}

.suchleiste__nachbar {
    display: block;
    width: 100%;
    text-align: left;
    padding: 5px 8px;
    background: none;
    border: 0;
    border-radius: var(--radius);
    cursor: pointer;
    /* Ein Knopf erbt Schrift und Farbe nicht – der Browser malt beides selbst (Arial, schwarz).
       Im Hellen sieht das beinahe richtig aus, im Dunkeln steht Schwarz auf Dunkelblau. */
    font: inherit;
    color: var(--text);
    font-size: 12px;
}

.suchleiste__nachbar:hover { background: var(--flaeche-blass); }
.suchleiste__nachbar strong { display: block; }
.suchleiste__nachbar span { color: var(--text-schwach); }

.suchleiste__hilfeseiten { margin-top: 4px; }

.suchleiste__hilfe-untertitel {
    display: block;
    font-size: 11px;
    color: var(--text-schwach);
    margin-bottom: 4px;
}

.suchleiste__hilfeseite {
    display: block;
    width: 100%;
    text-align: left;
    padding: 5px 8px;
    background: none;
    border: 0;
    border-radius: var(--radius);
    cursor: pointer;
    /* Wie am Nachbarn: ohne diese beiden Zeilen stünde hier die Vorgabe des Browsers. */
    font: inherit;
    color: var(--text);
    font-size: 12px;
}

.suchleiste__hilfeseite:hover { background: var(--flaeche-blass); }
.suchleiste__hilfeseite strong { display: block; }
.suchleiste__hilfeseite span { color: var(--text-schwach); }

.suchleiste__antwort {
    padding: 10px 10px 12px;
    border-bottom: 1px solid var(--rand);
    margin-bottom: 4px;
}

.suchleiste__antwort-satz {
    font-weight: 600;
    color: var(--text-stark);
}

.suchleiste__antwort-filter {
    margin-top: 3px;
    font-size: 12px;
    color: var(--text-schwach);
}

/* Kennzeichnung, dass ein Sprachmodell die Frage gedeutet hat. */
.suchleiste__quelle {
    margin-left: 8px;
    padding: 1px 7px;
    font-size: 11px;
    font-weight: 600;
    color: var(--primaer-dunkel);
    background: var(--primaer-blass);
    border-radius: 999px;
}

.suchleiste__antwort-filter a {
    margin-left: 8px;
    color: var(--primaer);
}

.suchleiste__gruppe {
    padding: 8px 10px 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-schwach);
}

.suchleiste__treffer {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border: 0;
    background: transparent;
    border-radius: var(--radius-klein);
    text-align: left;
    font: inherit;
    color: var(--text);
    cursor: pointer;
}

.suchleiste__treffer.aktiv { background: var(--primaer-blass); }

/* Treffer und, wo es ihn gibt, der Weg zur leeren Maske daneben. Die Zeile ist ein Flexkasten
   und keine zweite Spalte im Raster: Fast jede Zeile hat kein „Neu", und eine leere Spalte quer
   durch die ganze Liste schöbe jeden Titel nach links, ohne dass dort je etwas stünde. */
.suchleiste__zeile {
    display: flex;
    align-items: center;
    gap: 2px;
}

.suchleiste__zeile .suchleiste__treffer { flex: 1 1 auto; min-width: 0; }

/* Dasselbe Maß und dieselbe Sprache wie an der Kachel der Übersicht
   (`.schnellzugriff__werkzeug--neu`) – es ist derselbe Weg, nur eine Etage höher. Die Farbe ist
   `--primaer` und nicht die Kachelfarbe: In der Liste steht keine Kachel, an der man die Farbe
   sähe, und ein farbiges Wort ohne seinen Grund wirkt beliebig. */
.suchleiste__neu {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 8px;
    border-radius: var(--radius-klein);
    font-size: 12px;
    font-weight: 500;
    color: var(--primaer);
    white-space: nowrap;
}

.suchleiste__neu:hover {
    background: var(--primaer-blass);
    text-decoration: none;
}

.suchleiste__treffer-zeichen { color: var(--slate); flex: 0 0 auto; }

/* `1 1 0` und nicht `1 1 auto`: Wird es eng, soll **dieser** Block weichen und nicht der Zusatz
   rechts. Mit `auto` schrumpfen beide im Verhältnis ihrer Inhalte, und dann steht dort „10.0…" –
   ein halbes Datum sagt nichts, ein halber Titel sagt noch, um welchen Vorgang es geht. Mit der
   Basis 0 behält der Zusatz seine natürliche Breite bis zu seinem Deckel, und der Titel nimmt,
   was übrig bleibt. */
.suchleiste__treffer-text {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.suchleiste__titel {
    font-weight: 500;
    color: var(--text-stark);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.suchleiste__unter {
    font-size: 12px;
    color: var(--text-schwach);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* **Der Zusatz weicht, der Titel bleibt.**

   Er stand auf `flex: 0 0 auto` mit `nowrap` – also unschrumpfbar –, und das trägt, solange
   dort ein Datum oder eine Nummer steht. Beim Projekt steht die **Anschrift**: bei 375 Pixeln
   230 Pixel breit in einer 221 Pixel breiten Liste. Gemessen lief die Liste damit **61 Pixel**
   seitlich über, und der Titel („26-00011 · Bad Koch") wurde auf null gedrückt – zu sehen war
   nur noch die Anschrift, also ausgerechnet nicht das, wonach gesucht wurde. Am Bürorechner
   fällt davon nichts auf: Dort ist die Liste 760 Pixel breit.

   Der Deckel ist ein Anteil und keine Pixelzahl: Bei 221 Pixeln bleiben 99 für den Zusatz – ein
   Datum braucht 62 und wird nie gekürzt –, bei 760 sind es 342. Und gekürzt wird mit Auslassung:
   eine halbe Anschrift ohne Zeichen dafür läse sich wie eine falsche. */
.suchleiste__zusatz {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 45%;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 12px;
    color: var(--text-schwach);
    white-space: nowrap;
}

.suchleiste__leer,
.suchleiste__fuss {
    padding: 12px 10px;
    font-size: 13px;
    color: var(--text-schwach);
}

.suchleiste__fuss { border-top: 1px solid var(--rand); }

@media (max-width: 800px) {
    .kopfband { padding: 8px 14px; }
    .suchleiste { max-width: none; }
    .suchleiste__kuerzel { display: none; }
}
/* ---------- Arbeitsfläche ---------- */
.inhalt {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;

    /* Die Arbeitsfläche liegt einen Hauch unter Weiß. Karten und Tabellen darauf sind weiß
       und heben sich damit ohne kräftige Rahmen ab – das ist der Griff, der eine Oberflaeche
       am meisten aufräumt. */
    background: var(--flaeche-blass);
}

.seiten-kopf {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 22px 28px 12px;
    min-height: var(--kopf-hoehe);

    /* **Der Kopf bricht um, und zwar hier und nicht erst im Werkzeugblock.** Der Kommentar
       an `__werkzeuge` verspricht seit je, das Werkzeug rutsche auf schmalen Geräten unter
       die Überschrift – nur konnte es das nie: Ein Umbruch *innerhalb* des Werkzeugblocks
       stapelt dessen Knöpfe, schiebt den Block aber nicht in eine eigene Zeile. Solange der
       Elternteil `nowrap` war, blieb dem Titel nur, zu schrumpfen; er trägt `min-width: 0`
       und wurde damit klaglos auf null gedrückt.
       Gemessen bei 375 Pixeln, Menüleiste ausgeklappt: Titelblock 0 px auf allen vier
       geprüften Seiten – die Überschrift war schlicht weg –, dazu bis zu 141 px Überlauf
       nach rechts. Eingeklappt stand „Lager" auf 3 px. Beides sieht man im Hellen am
       Bürorechner nie. */
    flex-wrap: wrap;
}

.seiten-kopf__titel {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1 1 auto;
    min-width: 0;
}

.seiten-kopf__werkzeuge {
    display: flex;
    align-items: center;
    gap: 10px;

    /* Auf schmalen Geräten rutscht das Werkzeug unter die Überschrift (dafür sorgt das
       `flex-wrap` am `.seiten-kopf`), und die Knöpfe stapeln sich darin, statt die
       Überschrift zusammenzuquetschen oder über den Rand zu laufen. */
    flex-wrap: wrap;

    /* Ohne das hier bliebe der Block bei seiner Mindestbreite stehen – ein Flex-Element hat
       `min-width: auto` – und der Umbruch darin käme gar nicht erst zum Zuge. */
    min-width: 0;
}

/* **Ein Seitenkopf, dessen Knopf für die ganze lange Seite gilt, bleibt stehen.** Die Einstellungen
   speichern mit *einem* Knopf, was darunter auf einer Seite von zwei Bildschirmhöhen steht –
   gemeldet als „man muss zum Speichern immer nach ganz oben scrollen“. Die Listen brauchen das
   nicht: Ihr Knopf legt etwas an und gehört zum Anfang der Seite.
   Unter dem Kopfbereich und nicht bei null, aus demselben Grund wie am `.detail-kopf`: Dort klebt
   die Suchleiste und läge darüber. Der Grund ist die Arbeitsfläche und nicht `--flaeche` – der
   Kopf steht hier auf ihr und nicht auf einer Karte. */
.seiten-kopf--klebend {
    position: sticky;
    top: var(--kopfbereich-hoehe, 0px);
    z-index: 20;
    padding-bottom: 14px;
    background: color-mix(in srgb, var(--flaeche-blass) 92%, transparent);
    backdrop-filter: saturate(1.6) blur(8px);
    border-bottom: 1px solid var(--rand-zart);
}

/* Die Meldung zum Speichern steht im stehenden Kopf und nicht über dem Inhalt: Wer unten
   speichert, sähe sie sonst nie – und hielte den Knopf für wirkungslos. Eine eigene Zeile über
   die volle Breite, damit sie die Überschrift nicht zusammendrückt. Zwei Klassen im Wähler, weil
   `.erfolg-band`/`.fehler-band` weiter hinten stehen und ihren Außenabstand sonst durchsetzten. */
.seiten-kopf .seiten-kopf__meldung {
    flex: 1 0 100%;
    margin: 0;
}

/* ---------- Der Balken über einer Auswahl ----------
   Er erscheint erst, wenn etwas angekreuzt ist – ein dauerhaft sichtbarer Knopf „Abhaken"
   behauptet, es gäbe etwas abzuhaken. Dieselbe Regel wie am Filterstreifen darüber, und aus
   demselben Grund steht die Zahl mit dabei: Wer fünfzig Zeilen angekreuzt hat, soll vor dem
   Druck sehen, wie viele es sind. */
.stapelbalken {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 10px;
    padding: 8px 12px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--primaer) 8%, var(--flaeche));
}

/* ---------- Der Status in der Zeile ----------
   Ein Auswahlfeld mitten in einer Tabelle darf nicht wie ein Formularfeld aussehen, sonst
   liest sich jede Zeile wie eine Maske. Es trägt deshalb keinen Rahmen, bis man darüberfährt –
   dann zeigt es, dass es eines ist. Der Farbpunkt davor bleibt die Auskunft, die man beim
   Überfliegen liest; ein eingefärbtes Auswahlfeld wäre ein Bedienelement, das wie ein
   Abzeichen aussieht. */
/* Die Wiedervorlage unter dem Projektnamen: klein und blass, solange sie nicht fällig ist –
   eine vorgemerkte Wiedervorlage in drei Wochen ist eine Auskunft, keine Aufforderung. Fällig
   trägt sie die Warnfarbe und ein Wort, nicht nur die Farbe. */
.wiedervorlage-zeile {
    display: flex;
    align-items: center;
    gap: 5px;
    margin-top: 3px;
    font-size: 12px;
    font-weight: 400;
    color: var(--text-schwach);
}

/* Datum, Anlass, Erledigt in einer Zeile; der Anlass nimmt den Rest und bricht auf dem
   Telefon unter das Datum. */
.wiedervorlage-eingabe {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.wiedervorlage-eingabe input[type="date"] { width: auto; }
.wiedervorlage-eingabe input:not([type="date"]) { flex: 1 1 220px; min-width: 0; }

/* Eigene Felder in der Projektakte: so breit wie ein Satz, nicht wie die Spalte – eine
   Zählernummer über die ganze Breite liest sich wie ein Absatz. */
.projektfeld { max-width: 420px; }
.projektfeld--kurz { max-width: 200px; }
textarea.projektfeld { resize: vertical; }
.projektfeld__text { white-space: pre-line; }

.wiedervorlage-zeile--faellig {
    color: var(--gelb-dunkel);
    font-weight: 600;
}

.statuszelle {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
}

.statuszelle__punkt {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: 0 0 9px;
}

/* Die Breite ist gemessen und nicht geraten: Die längste Statusbeschriftung („Projekt
   abgeschlossen") misst 150 Pixel, dazu der Pfeil und der Innenabstand. Bei 150 stand dort
   „Rechnung a…", und ein gekürzter Status ist keiner – „Rechnung angelegt", „Rechnung
   angemahnt" und „Rechnung angenommen" beginnen alle gleich. */
.feld--stillst {
    height: 30px;
    padding: 0 22px 0 6px;
    border-color: transparent;
    background-color: transparent;
    font-size: 13px;
    max-width: 190px;
}

.feld--stillst:hover { border-color: var(--rand); background-color: var(--flaeche); }

/* ---------- Netto oder brutto über den Beleglisten ----------
   Dieselbe Schale wie die Farbwahl der Übersicht, eine Nummer schmaler: zwei Knöpfe, beide
   sichtbar. Ein Umschalter wäre kompakter und verstecke den zweiten Zustand – bei einer Zahl
   auf einem Beleg ist das die falsche Sparsamkeit, denn wer sich vertut, vertut sich um
   neunzehn Prozent.

   Der gewählte Knopf bekommt eine **getönte Fläche und behält seine Schriftfarbe** – dieselbe
   Überlegung wie am Einstellungsmenü: `--primaer-dunkel` trägt im Dunkeln eine Fläche und keine
   Schrift, und genau als Schrift ist es am Reiter der Suchleiste schon einmal auf 3,52 : 1
   gekommen. */
.betragssicht {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    background: var(--flaeche-blass);
}

.betragssicht__knopf {
    height: 32px;
    padding: 0 12px;
    border: none;
    border-radius: var(--radius-klein);
    background: none;
    color: var(--text-gedaempft);
    font-family: inherit;
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
    transition: background .12s ease, color .12s ease;
}

.betragssicht__knopf:hover { color: var(--text-stark); }

.betragssicht__knopf.aktiv {
    background: color-mix(in srgb, var(--primaer) 13%, var(--flaeche));
    color: var(--text-stark);
    font-weight: 600;
}

@media (pointer: coarse) {
    .betragssicht__knopf { height: 40px; padding: 0 14px; }
}

/* Die Mengenermittlung unter einer Position – in der Vorschau wie auf dem Blatt. */
.positionen__mengen {
    margin-top: 4px;
    font-size: 11px;
    color: var(--text-schwach);
    font-variant-numeric: tabular-nums;
}

.positionen__mengenkopf { display: block; font-weight: 600; }

/* Die Summe einer Gruppe – kräftiger Strich darunter, wie auf dem Blatt: Dort endet die Gruppe. */
.positionen tr.positionen__gruppensumme td {
    border-bottom: 1px solid var(--rand-stark);
    color: var(--text-stark);
}

.beleg__zwischentitel {
    margin: 22px 0 6px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-stark);
}

/* ---------- Kostenzeilen im Kalkulationsdialog ---------- */
.kostenzeilen {
    margin-top: 14px;
    padding: 12px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche-blass);
}

.kostenzeilen__kopf { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; margin-bottom: 8px; }
/* Eine Stufe stärker als `table.tabelle td`: Diese Regel steht im Stilblatt **vor** jener, und
   bei gleicher Stärke gewinnt die spätere – die Zeile lief aus dem Dialog, obwohl die Regel
   geladen war. Gemessen und nicht vermutet: der Browser nannte beide Regeln und nahm die zweite. */
table.tabelle.kostenzeilen__tabelle th,
table.tabelle.kostenzeilen__tabelle td { padding: 4px 3px; vertical-align: middle; }
.kostenzeilen__rolle { overflow-x: auto; }

/* Die Tabelle rechnet ihre Spalten aus dem Inhalt; ein Auswahlfeld ohne Mindestbreite schrumpfte
   dabei auf seinen Pfeil, und die Kostenart war nicht mehr zu lesen. Ein Betrag bricht nie um –
   „135,00" oben und „€" darunter liest sich wie zwei Werte. */
.kostenzeilen__tabelle select { min-width: 132px; }
/* 110 und nicht mehr: Im Artikeldialog stehen 554 Pixel zur Verfügung, und bei 160 lief die Zeile
   um 30 Pixel über. Die Einheit braucht dafür ihre 60 – bei 48 las sich „Std." als „Stc". */
.kostenzeilen__tabelle td:nth-child(2) input { min-width: 110px; }
.kostenzeilen__tabelle td:nth-child(4) input { min-width: 60px; }
.kostenzeilen__tabelle td:nth-child(6) { white-space: nowrap; }
.kostenzeilen__knoepfe { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

/* Aufgabenvorlage: je Zeile oben Titel, Frist und Zuständiger, darunter die Beschreibung über
   dieselbe Breite. Als eine Zeile mit vier Feldern blieben im Dialog für den Titel zwei Wörter.
   Die Spalte des Zuständigen ist gemessen: „Projektverantwortlicher" sind 154 Pixel Text, dazu
   26 Innenabstand und der Pfeil – bei 170 stand „Verantwortlicher d", bei 195 noch
   „Projektverantwortliche". Die Frist braucht für drei Ziffern und „Tagen" keine 100. */
.aufgabenvorlage { display: grid; gap: 10px; }
.aufgabenvorlage__kopf,
.aufgabenvorlage__zeile {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 96px 214px 34px;
    gap: 6px 8px;
    align-items: center;
}
.aufgabenvorlage__kopf {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-schwach);
}
.aufgabenvorlage__zeile { padding-bottom: 10px; border-bottom: 1px solid var(--rand-zart); }
.aufgabenvorlage__tage { display: flex; align-items: center; gap: 6px; }
.aufgabenvorlage__tage .feld { min-width: 0; }
.aufgabenvorlage__beschreibung { grid-column: 1 / 4; }

/* Änderungsverlauf am Artikel: je Eintrag Zeitpunkt und Herkunft, darunter die Felder.
   Begrenzt hoch und in sich rollend – fünfzig Einträge sonst unter dem Speichern-Knopf. */
.artikelverlauf { margin-top: 12px; }
.artikelverlauf__liste {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 260px;
    overflow-y: auto;
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius);
}
.artikelverlauf__eintrag { padding: 8px 10px; border-bottom: 1px solid var(--rand-zart); font-size: 12px; }
.artikelverlauf__eintrag:last-child { border-bottom: none; }
.artikelverlauf__kopf { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-bottom: 4px; }
.artikelverlauf__feld { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: 8px; }

.aufgabenvorlagewahl { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 14px; }
.aufgabenvorlagewahl .feld { width: auto; min-width: 0; max-width: 360px; flex: 1 1 220px; }

/* ---------- Erste Schritte (Übersicht) ----------
   Eine Liste mit Haken und genau einem hervorgehobenen Knopf: dem nächsten offenen Schritt.
   Acht gleich laute Knöpfe untereinander sagten nicht, wo man anfängt. */
.erste-schritte { margin-bottom: 18px; }

.erste-schritte .karte__kopf { gap: 10px; }
.erste-schritte__stand { margin-left: auto; font-size: 12px; color: var(--text-gedaempft); }

.erste-schritte__balken {
    height: 6px;
    margin: 0 18px 6px;
    border-radius: 3px;
    background: var(--flaeche-grau);
    overflow: hidden;
}

.erste-schritte__balken > div {
    height: 100%;
    border-radius: 3px;
    background: var(--gruen);
    transition: width .3s ease;
}

.erste-schritte__liste {
    list-style: none;
    margin: 0;
    padding: 4px 18px 14px;
}

.erste-schritte__schritt {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 0;
    border-bottom: 1px solid var(--rand-zart);
}

.erste-schritte__schritt:last-child { border-bottom: none; }

.erste-schritte__haken {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border: 1.5px solid var(--rand-stark);
    border-radius: 50%;
}

.erste-schritte__schritt--erledigt .erste-schritte__haken {
    border-color: var(--gruen);
    background: var(--gruen-blass);
    color: var(--gruen-dunkel);
}

.erste-schritte__text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.erste-schritte__titel { font-size: 13px; font-weight: 600; color: var(--text-stark); }
.erste-schritte__warum { font-size: 12px; color: var(--text-gedaempft); line-height: 1.4; }

.erste-schritte__schritt--erledigt .erste-schritte__titel {
    font-weight: 500;
    color: var(--text-gedaempft);
    text-decoration: line-through;
}

/* Die Stunden je Zeitart über der Zeiterfassung. Eine Reihe kleiner Felder und kein zweites
   Zahlenband: Das Zeitkonto darüber ist die Hauptsache, dieses hier die Aufschlüsselung, und
   zwei gleich große Bänder übereinander ließen nicht erkennen, welches was sagt. */
.zeitarten {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 14px;
}

.zeitarten__feld {
    display: grid;
    grid-template-columns: auto auto;
    column-gap: 10px;
    align-items: baseline;
    padding: 8px 12px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    min-width: 140px;
}

.zeitarten__name {
    grid-column: 1 / -1;
    font-size: 12px;
    color: var(--text-gedaempft);
}

.zeitarten__wert { font-size: 16px; font-weight: 600; color: var(--text-stark); }
.zeitarten__anteil { font-size: 12px; color: var(--text-gedaempft); text-align: right; }

.zeitarten__feld--pause { border-style: dashed; }
.zeitarten__feld--summe { background: var(--flaeche-blass); }

/* Der Satz neben „Exportieren": abgeschnitten, leer oder nicht geholt. Er steht im Kopf neben
   dem Knopf und nicht als Band über der Tabelle – er gehört zu diesem einen Klick. */
.listenexport__meldung {
    max-width: 280px;
    font-size: 12px;
    line-height: 1.35;
    color: var(--text-gedaempft);
}

/* ---------- Farbwahl in der Übersicht ----------
   Drei Knöpfe in einer Schale, der gewählte hebt sich ab – dasselbe Muster wie die Reiter der
   Einstellungen, nur eine Nummer kleiner. Ein einzelner Umschalter wäre kompakter und verstecke
   zwei der drei Zustände: Man sähe weder, was gilt, noch, was der nächste Druck bringt. */
.themaschalter {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    background: var(--flaeche-blass);
}

.themaschalter__knopf {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 32px;
    padding: 0 11px;
    border: none;
    border-radius: calc(var(--radius-gross) - 3px);
    background: none;
    color: var(--text-schwach);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    white-space: nowrap;
}

.themaschalter__knopf:hover { color: var(--text); }

/* Der gewählte Knopf wird **eingefärbt** und nicht nur angehoben. Zuerst trug er eine hellere
   Fläche samt Schatten – im Hellen genügte das, im Dunkeln nicht: Dort liegen die beiden
   Flächentöne nur sechs Stufen auseinander, und einen Schatten sieht man auf dunklem Grund
   ohnehin nicht. Über dieselbe Farbe wie der aktive Reiter der Einstellungen trägt es in beiden
   Welten – und sagt zugleich „ausgewählt" und nicht „liegt obenauf". */
.themaschalter__knopf--aktiv {
    background: var(--primaer-blass);
    color: var(--primaer-dunkel);
    font-weight: 600;
}

/* Im Kopf einer Seite zählt der Platz mehr als das Wort: Das Symbol allein sagt schon, worum es
   geht, und die drei Wörter nebeneinander schöben den „Erstellen"-Knopf aus dem Bild. Der Name
   steht weiter im `title` und für Vorleseprogramme im Knopf. */
@media (max-width: 1180px) {
    .themaschalter__knopf span { display: none; }
    .themaschalter__knopf { padding: 0 9px; }
}

/* Mit dem Finger bedient werden auch diese drei – sie sind die kleinsten Ziele im Seitenkopf. */
@media (pointer: coarse) {
    .themaschalter__knopf { height: 38px; min-width: 40px; justify-content: center; }
}

.seiten-koerper {
    padding: 6px 28px 44px;
    flex: 1 1 auto;
}

/* Eine Reihe von Zahlen als eine Fläche: Entwurf, Unbezahlt, Überfällig, Im Mahnlauf.
   Vorher stand das als Gefüge von Inline-Angaben im Markup und sah aus wie ein Kasten aus
   einem älteren Programm. */
.zahlenband {
    display: flex;
    margin-bottom: 18px;
    max-width: 820px;
    background: var(--flaeche);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten);
    overflow: hidden;
}

.zahlenband__feld {
    flex: 1 1 0;
    padding: 13px 18px;
    position: relative;
}

/* Trennung durch eine kurze Linie statt durch einen vollen Rahmen – sie fuehrt das Auge,
   ohne die Fläche zu zerschneiden. */
.zahlenband__feld + .zahlenband__feld::before {
    content: "";
    position: absolute;
    left: 0;
    top: 22%;
    bottom: 22%;
    width: 1px;
    background: var(--rand-zart);
}

.zahlenband__name {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-schwach);
    margin-bottom: 2px;
}

.zahlenband__wert {
    font-size: 18px;
    font-weight: 600;
    color: var(--text-stark);
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 760px) {
    .zahlenband { flex-wrap: wrap; }
    .zahlenband__feld { flex: 1 1 50%; }
}

.filterzeile {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 0 14px;
    flex-wrap: wrap;
}

/* ---------- Bedienelemente ---------- */
.knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    height: 40px;
    padding: 0 18px;
    border-radius: var(--radius);
    border: 1px solid transparent;
    font-family: inherit;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: background .14s ease, border-color .14s ease, box-shadow .14s ease,
                transform .08s ease;
}

/* Beim Drücken sinkt der Knopf um ein Haar ein. Winzig, aber es macht die Bedienung
   greifbar – man sieht, dass der Druck angekommen ist. */
.knopf:active:not(:disabled) { transform: translateY(1px); }

.knopf--primaer {
    background: var(--primaer);
    color: #fff;
    box-shadow: 0 1px 2px rgba(10, 111, 199, .28), 0 2px 8px rgba(10, 111, 199, .18);
}

.knopf--primaer:hover {
    background: var(--primaer-dunkel);
    box-shadow: 0 1px 2px rgba(10, 111, 199, .32), 0 4px 12px rgba(10, 111, 199, .22);
}

.knopf--rand {
    background: var(--flaeche);
    color: var(--text-stark);
    border-color: var(--rand);
    box-shadow: 0 1px 1px rgba(16, 47, 75, .04);
}

.knopf--rand:hover { background: var(--flaeche-blass); border-color: var(--rand-stark); }

.knopf--still {
    background: transparent;
    color: var(--text);
}

.knopf--still:hover { background: var(--flaeche-grau); }

.knopf--gefahr {
    background: var(--rot);
    color: #fff;
    box-shadow: 0 1px 2px rgba(168, 58, 58, .24), 0 2px 8px rgba(168, 58, 58, .16);
}

.knopf--gefahr:hover { background: var(--rot-dunkel); }

.knopf--klein { height: 34px; padding: 0 13px; font-size: 13px; }

.knopf:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }

/* Ein Knopf nur mit Zeichen – quadratisch, damit drei nebeneinander wie eine Leiste aussehen.
   Das Wort steht am `title`. */
.knopf--symbol { width: 40px; padding: 0; }

/* ---------- Aktionsmenü (Komponenten/Aktionsmenue.razor) ---------- */
.aktionsmenue { position: relative; }

.aktionsmenue__schleier { position: fixed; inset: 0; z-index: 44; }

.aktionsmenue__liste {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 45;
    min-width: 250px;
    padding: 6px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    box-shadow: var(--schatten-hoch);
    display: flex;
    flex-direction: column;
}

.aktionsmenue__eintrag {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    border: 0;
    border-radius: var(--radius-klein);
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 14px;
    text-align: left;
    cursor: pointer;
    white-space: nowrap;
}

.aktionsmenue__eintrag:hover:not(:disabled) { background: var(--flaeche-grau); }
.aktionsmenue__eintrag:disabled { opacity: .5; cursor: not-allowed; }
.aktionsmenue__eintrag--gefahr { color: var(--rot-dunkel); }
.aktionsmenue__trenner { height: 1px; margin: 5px 4px; background: var(--rand); }

/* ---------- Kippschalter ----------
   Ein Kontrollkästchen, das wie ein Schalter aussieht: Es bleibt ein echtes Eingabefeld, also
   mit Tastatur und Vorleser bedienbar. */
.kippschalter { position: relative; display: inline-block; width: 42px; height: 24px; flex: 0 0 auto; }
.kippschalter input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.kippschalter span {
    position: absolute;
    inset: 0;
    border-radius: 12px;
    background: var(--rand-stark);
    transition: background .15s ease;
    pointer-events: none;
}
.kippschalter span::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--flaeche);
    box-shadow: var(--schatten);
    transition: transform .15s ease;
}
.kippschalter input:checked + span { background: var(--primaer); }
.kippschalter input:checked + span::after { transform: translateX(18px); }
.kippschalter input:focus-visible + span { outline: 2px solid var(--primaer); outline-offset: 2px; }
.kippschalter input:disabled { cursor: not-allowed; }
.kippschalter input:disabled + span { opacity: .5; }

/* ---------- Belegansicht mit Randspalte (Angebot) ----------
   Links Kennzahlen und Blatt, rechts, was zum Vorgang gehört: Kunde, Projekt, Webansicht.
   Umgebrochen wird nach der Breite der Hülle und nicht des Fensters – die Menüleiste nimmt je
   nach Gerät 60 oder 232 Pixel weg. */
.belegansicht-huelle { container-type: inline-size; }

.belegansicht-raster {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: 24px;
    align-items: start;
}

.belegansicht-raster__haupt { min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.belegansicht-raster__rand { min-width: 0; display: flex; flex-direction: column; gap: 16px; }

@container (max-width: 1000px) {
    .belegansicht-raster { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Angebot und Rechnung anlegen und bearbeiten: Maske und Vorschau nebeneinander ----------
   Rechts das Blatt, wie es gerade dasteht (`Belegvorschau`), klebend unter dem Detailkopf,
   damit es beim Rollen durch lange Positionslisten stehen bleibt. Verkleinert über `zoom` in
   fester Breite: So bricht das kleine Blatt an denselben Stellen um wie das große, und die
   Spalte ist so hoch wie das, was man sieht (ein `transform` behielte den Platz des großen). */
.belegbearbeitung-huelle { container-type: inline-size; }

.belegbearbeitung {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 24px;
    align-items: start;
    transition: grid-template-columns .25s ease;
}

/* Ausgeblendet gleitet die Spalte nach rechts auf einen schmalen Streifen zusammen, und die
   Maske bekommt die Breite. Gefragt wird mit `:has`, weil der Zustand in der Vorschau liegt und
   nicht in der Seite – eine zweite Angabe an der Seite liefe neben ihm her. */
.belegbearbeitung:has(> .belegvorschau--zu) { grid-template-columns: minmax(0, 1fr) 44px; }

@media (prefers-reduced-motion: reduce) {
    .belegbearbeitung { transition: none; }
}

.belegbearbeitung__maske { min-width: 0; }

.belegvorschau {
    position: sticky;
    top: calc(var(--kopfbereich-hoehe, 0px) + 72px);
    max-height: calc(100vh - var(--kopfbereich-hoehe, 0px) - 88px);
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    background: var(--flaeche-grau);
}

.belegvorschau--zu { max-height: none; }
.belegvorschau--zu .belegvorschau__kopf { display: none; }

/* Der Streifen am rechten Rand: Pfeil nach links und das Wort quer – auf 44 Pixeln steht
   waagerecht nichts Lesbares. */
.belegvorschau__streifen {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 0;
    background: none;
    border: 0;
    border-radius: var(--radius-gross);
    font: inherit;
    color: var(--text);
    cursor: pointer;
}

.belegvorschau__streifen:hover { color: var(--verweis); }

.belegvorschau__streifen span {
    writing-mode: vertical-rl;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
}

/* Die Schrift erbt sonst den berechneten Wert der dunklen Seite – helles Grau auf dem hellen
   Blatt. Die Token setzt der Block gleich hinter dem dunklen Tokenblock. */
.belegvorschau__papier { color: var(--text); }

.belegvorschau__kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--rand);
}

.belegvorschau--zu .belegvorschau__kopf { border-bottom: 0; }
.belegvorschau__titel { font-weight: 600; font-size: 13px; }
.belegvorschau__summe { font-size: 12px; color: var(--text-schwach); font-variant-numeric: tabular-nums; }

.belegvorschau__blatt {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    padding: 10px;
}

.belegvorschau__blatt .beleg {
    width: 800px;
    zoom: 0.44;
}

.belegvorschau__hinweis {
    padding: 6px 10px 8px;
    font-size: 11px;
    color: var(--text-schwach);
}

/* ---------- Der Block „E-Rechnung“ der Rechnungsmaske ----------
   Zuklappbar, und der Kopf trägt den Stand (`Erechnungsangaben`): rot, solange etwas fehlt,
   grün, wenn alles da ist – auch zugeklappt sichtbar. Die Farbe ist nicht allein die Auskunft,
   der Satz sagt es in Worten. */
details.erechnungskarte > summary { list-style: none; cursor: pointer; }
details.erechnungskarte > summary::-webkit-details-marker { display: none; }
details.erechnungskarte:not([open]) > .erechnungskarte__kopf { border-bottom: 0; }

.erechnungskarte__kopf {
    justify-content: flex-start;
    flex-wrap: wrap;
}

.erechnungskarte__kopf::after {
    content: "";
    width: 7px;
    height: 7px;
    border-right: 2px solid var(--text-schwach);
    border-bottom: 2px solid var(--text-schwach);
    transform: rotate(-45deg);
    transition: transform .15s ease;
    flex: 0 0 auto;
}

details.erechnungskarte[open] > .erechnungskarte__kopf::after { transform: rotate(45deg); }

.erechnungskarte__stand {
    flex: 1 1 240px;
    min-width: 0;
    font-size: 12.5px;
    font-weight: 600;
    text-align: right;
}

.erechnungskarte__stand--offen { color: var(--rot-dunkel); }
.erechnungskarte__stand--gut { color: var(--gruen-dunkel); }

/* Schmal steht nur die Leiste über der Maske – Summe und „Groß“. Ein Blatt in voller Breite
   unter dem Positionseditor sähe beim Tippen niemand, und daneben ist kein Platz. */
@container (max-width: 1000px) {
    .belegbearbeitung,
    .belegbearbeitung:has(> .belegvorschau--zu) { grid-template-columns: minmax(0, 1fr); }
    .belegvorschau { position: static; max-height: none; order: -1; }
    .belegvorschau .belegvorschau__kopf { display: flex; border-bottom: 0; }
    .belegvorschau__blatt,
    .belegvorschau__hinweis,
    .belegvorschau__schalter,
    .belegvorschau__streifen { display: none; }
}

.belegzahlen {
    background: var(--flaeche-grau);
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    padding: 12px;
}

.belegzahlen__oben {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px 32px;
    padding: 14px 16px;
    background: var(--flaeche);
    border-radius: var(--radius);
    box-shadow: var(--schatten);
}

.belegzahlen__unten {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    padding: 12px 4px 2px;
}

.belegzahlen__unten .belegzahl { padding: 0 16px; }
.belegzahlen__unten .belegzahl + .belegzahl { border-left: 1px solid var(--rand); }

.belegzahl__titel { font-size: 12px; color: var(--text-schwach); }
.belegzahl__wert { font-size: 17px; font-weight: 600; color: var(--text-stark); margin-top: 3px; }
.belegzahl--summe { margin-left: auto; text-align: right; }
.belegzahl--summe .belegzahl__wert { font-size: 20px; }

@container (max-width: 560px) {
    .belegzahlen__unten { grid-template-columns: minmax(0, 1fr); gap: 10px; }
    .belegzahlen__unten .belegzahl + .belegzahl { border-left: 0; }
}

.randkarte {
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    padding: 16px 18px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.randkarte__kopf { display: flex; align-items: center; gap: 8px; }
.randkarte__kopf h3 { margin: 0; font-size: 15px; }
.randbetrag { font-size: 18px; font-variant-numeric: tabular-nums; color: var(--text-stark); }
.randbetrag--rot { color: var(--rot-dunkel); }
details.randkarte > summary { list-style: none; }
details.randkarte > summary::-webkit-details-marker { display: none; }
.randkarte__knoepfe { display: flex; flex-wrap: wrap; gap: 8px; }
.randkarte__knoepfe .knopf { flex: 1 1 auto; }

/* Der Preisvergleich in der Randspalte: Summe je Lieferant statt einer Spalte je Lieferant;
   die Einzelpreise stehen im Dialog. */
.preisvergleich { margin: 0; }
.preisvergleich__summen {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 6px 12px;
    margin: 12px 0 0;
    font-size: 13px;
}
.preisvergleich__summen dt { color: var(--text); overflow-wrap: anywhere; }
.preisvergleich__summen dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.preisvergleich__summen dt:first-of-type,
.preisvergleich__summen dd:first-of-type { color: var(--text-schwach); }
.preisvergleich__bester { color: var(--gruen-dunkel); font-weight: 600; }
.preisvergleich__uebernahme { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.preisvergleich__uebernahme .knopf { width: 100%; }

.randangaben { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 6px 12px; font-size: 13px; }
.randangaben dt { color: var(--text-schwach); }
.randangaben dd { margin: 0; color: var(--text); overflow-wrap: anywhere; }

/* So sieht ein Textfeld aus – **an einer Stelle** für beide, die es gibt: die Felder der Masken
   und den Suchkasten der Listenköpfe.

   Sie standen bis hierher als zwei Regelsätze nebeneinander, und der zweite war eine Abschrift
   mit einer fehlenden Zeile: `.suche input` setzte Rand, Radius und Schriftfarbe, aber **keinen
   Hintergrund**. Im Hellen fiel das nie auf – der Browser malt ein Eingabefeld von sich aus
   weiß, und weiß war richtig. Im Dunkeln blieb es weiß, auf allen elf Seiten mit Suchkasten.

   Das ist eine **andere** Sorte Fehler als die fest geschriebenen hellen Farben, die
   `DunkelmodusTests` sucht: Hier stand gar keine Farbe, und die Vorgabe des Browsers hat
   gewonnen. Eine fehlende Angabe findet man nicht, indem man nach falschen Angaben sucht.
   Gemeldet hat es der Betrieb, nicht der Bau. */
.feld,
.suche input {
    height: 40px;
    padding: 0 13px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    font-family: inherit;
    font-size: 14px;
    color: var(--text-stark);
    background: var(--flaeche);
    width: 100%;
    transition: border-color .12s ease, box-shadow .12s ease;
}

.feld:hover:not(:focus),
.suche input:hover:not(:focus) { border-color: var(--rand-stark); }

.feld::placeholder,
.suche input::placeholder { color: var(--text-schwach); }

textarea.feld {
    height: auto;
    padding: 10px 12px;
    resize: vertical;
    line-height: 1.5;
}

.feld:focus,
.suche input:focus {
    outline: none;
    border-color: var(--primaer);
    box-shadow: var(--ring);
}

select.feld { cursor: pointer; }

.feld-gruppe { margin-bottom: 14px; }

.feld-gruppe label {
    display: block;
    font-size: 12px;
    font-weight: 500;
    color: var(--text-schwach);
    margin-bottom: 6px;
}

.feld-reihe {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 0 14px;
}

.suche {
    position: relative;
    display: flex;
    align-items: center;
    min-width: 240px;
}

.suche svg {
    position: absolute;
    left: 11px;
    color: var(--text-schwach);
    pointer-events: none;
}

/* Was den Suchkasten vom gewöhnlichen Feld unterscheidet, und sonst nichts: Links sitzt die
   Lupe, also braucht der Text dort Platz. Alles Übrige steht oben bei `.feld`. */
.suche input { padding-left: 36px; }

.schalter {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: 13px;
    color: var(--text-schwach);
}

/* ---------- Tabellen ---------- */
.tabelle-huelle {
    width: 100%;
    overflow-x: auto;
    background: var(--flaeche);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten);
}

table.tabelle {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

/* Kapitälchen und mehr Laufweite: der Kopf liest sich als Überschrift, nicht als erste
   Zeile. Ein mitlaufender Kopf wäre schön, geht hier aber nicht – die Hülle um die Tabelle
   muss breite Listen waagerecht scrollen können und ist damit selbst der Scrollbereich; ein
   „sticky“ darin hätte sich am Fenster nicht festgehalten. */
table.tabelle th {
    text-align: left;
    font-weight: 600;
    font-size: 11.5px;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-schwach);
    padding: 11px 12px;
    background: var(--flaeche);
    border-bottom: 1px solid var(--rand);
    white-space: nowrap;
}

table.tabelle td {
    padding: 13px 12px;
    border-bottom: 1px solid var(--rand-zart);
    vertical-align: middle;
}

table.tabelle tbody tr:last-child td { border-bottom: none; }

table.tabelle tbody tr {
    transition: background .1s ease;
}

table.tabelle tbody tr:hover { background: var(--flaeche-blass); }
table.tabelle tbody tr.klickbar { cursor: pointer; }
table.tabelle tbody tr.klickbar:hover { background: var(--primaer-blass); }

/* „Nichts gefunden.“ – eine ruhige Zeile unter der Filterzeile, kein Kasten: Die Tabelle bleibt
   stehen, damit der Suchbegriff berichtigt werden kann (`Nichtsgefunden`). */
/* Dasselbe für Listen aus Karten statt Zeilen (Warenkörbe). */
.nichts-gefunden {
    margin: 0;
    padding: 22px 12px;
    text-align: center;
    color: var(--text-schwach);
}

table.tabelle tbody tr.tabelle__nichts:hover { background: none; }
table.tabelle tbody tr.tabelle__nichts td {
    padding: 22px 12px;
    text-align: center;
    color: var(--text-schwach);
}

.zelle-rechts { text-align: right; }
.zelle-stark { font-weight: 500; color: var(--text-stark); }
.zelle-schwach { color: var(--text-schwach); }
.zelle-eng { width: 1%; white-space: nowrap; }

.tabelle-fuss {
    padding: 12px 14px;
    text-align: right;
    color: var(--text-schwach);
    font-size: 13px;
}

.leer-hinweis {
    padding: 56px 20px;
    text-align: center;
    color: var(--text-schwach);
    background: var(--flaeche-blass);
    border: 1px dashed var(--rand);
    border-radius: var(--radius);
}

.leer-hinweis h3 { color: var(--text); margin-bottom: 6px; }

/* Die leere Liste (`Komponenten/Leerliste.razor`): Bild, ein Satz, ein Knopf. Das Bild ist das
   Zeichen des Menüpunkts im blassen Grund – wer über die Seitenleiste kommt, erkennt, wo er
   gelandet ist; eine eigene Bildsprache für leere Seiten wäre eine zweite. Der Satz ist schmal
   gesetzt, damit er auf einem breiten Bildschirm nicht zu einer einzigen langen Zeile wird. */
.leer-hinweis--liste { padding: 44px 20px 48px; }
.leer-hinweis__bild {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin-bottom: 14px;
    border-radius: 50%;
    background: var(--primaer-blass);
    color: var(--primaer);
}
.leer-hinweis__satz { max-width: 440px; margin: 0 auto 18px; line-height: 1.5; }

/* ---------- Eingabefeld mit Vorschlägen ---------- */
/* Die Liste schwebt über dem Inhalt: in einer Tabellenzeile darf sie die Zeilenhöhe nicht
   verändern, sonst springt die ganze Positionstabelle beim Tippen. */
.vorschlagsfeld {
    position: relative;
}

.vorschlagsliste {
    position: absolute;
    z-index: 40;
    top: calc(100% + 2px);
    left: 0;
    /* Mindestens so breit wie das Feld, aber nicht schmaler als 340 Pixel: Im Termindialog ist
       das Projektfeld 220 Pixel breit, und darin lief ein Projektname über fünf Zeilen. Auf einem
       Telefon gilt die Feldbreite (unten) – dort steht das Feld über die ganze Breite, und
       340 Pixel ab seinem linken Rand ragten über das Fenster hinaus. */
    min-width: max(100%, 340px);
    max-width: 560px;
    max-height: 320px;
    overflow-y: auto;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    box-shadow: 0 6px 18px rgba(16, 47, 75, .12);
}

.vorschlag {
    padding: 7px 10px;
    cursor: pointer;
    border-bottom: 1px solid var(--rand-zart);
    font-size: 13px;
}

.vorschlag:last-child {
    border-bottom: none;
}

.vorschlag--aktiv {
    background: rgba(13, 135, 242, .08);
}

@media (max-width: 560px) {
    .vorschlagsliste { min-width: 100%; }
}

/* Die Überschrift über den Vorschlägen ohne Suchbegriff („Zuletzt angelegt“). Sie klebt oben,
   damit beim Rollen durch fünfzehn Einträge zu sehen bleibt, was das für eine Liste ist –
   Treffer einer Suche sind es nicht. Eigener Grund, sonst schienen die Zeilen durch. */
.vorschlagsliste__titel {
    position: sticky;
    top: 0;
    z-index: 1;
    padding: 6px 10px 5px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--text-schwach);
    background: var(--flaeche-blass);
    border-bottom: 1px solid var(--rand-zart);
}

.vorschlag__zeile {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

/* Die Nummer rechts bleibt ganz: „26-00004“ auf zwei Zeilen ist keine Nummer mehr. Weichen muss
   der Name, und der darf umbrechen. */
.vorschlag__zeile > :last-child {
    flex-shrink: 0;
    white-space: nowrap;
}

/* Ein Name, der ein ganzer Satz ist („Notdienst: Bei uns läuft Wasser aus der Heizung …“ – so
   entsteht ein Projekt aus dem Assistenten), hat nach zwei Zeilen gesagt, was er ist. Der volle
   Wortlaut steht im Feld, sobald er gewählt ist. */
.vorschlag__zeile > :first-child,
.vorschlag__fuss {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    min-width: 0;
}

.vorschlag__fuss {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
    font-size: 11px;
    margin-top: 2px;
}

/* ---------- Ablagefläche für Dateien ---------- */
/* Das Dateifeld liegt durchsichtig über der ganzen Fläche: so nimmt sie Fallenlassen und
   Klicken gleichermaßen an, ohne eigenes JavaScript. */
.ablage {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    margin-bottom: 14px;
    border: 1px dashed var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    font-size: 13px;
    transition: border-color .12s, background .12s;
}

.ablage:hover {
    border-color: var(--primaer);
}

.ablage--aktiv {
    border-color: var(--primaer);
    border-style: solid;
    background: rgba(13, 135, 242, .06);
}

/* Kalender und Plantafel, während eine Kalenderdatei darübergezogen wird (js/dateiablage.js).
   Die Zeile, auf der sie landen würde, ist hervorgehoben – sie belegt die Besetzung vor. */
.dateiablage--aktiv {
    outline: 2px dashed var(--primaer);
    outline-offset: 4px;
}

/* Der Ablagestreifen über Kalender und Plantafel sieht beim Darüberziehen aus wie der der Ausgaben. */
.ablage.dateiablage--aktiv {
    outline: none;
    border-color: var(--primaer);
    border-style: solid;
    background: rgba(13, 135, 242, .06);
}

.dateiablage--aktiv .dateiablage-ziel {
    background: color-mix(in srgb, var(--primaer) 12%, transparent);
}

.kalenderablage__liste {
    display: grid;
    gap: 8px;
    max-height: 46vh;
    overflow: auto;
    margin-bottom: 14px;
}

.kalenderablage__termin {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 10px 12px;
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius);
    cursor: pointer;
}

.kalenderablage__termin--aus { opacity: .55; }

.kalenderablage__termin input { margin-top: 3px; }

.kalenderablage__inhalt {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.kalenderablage__inhalt .abzeichen { align-self: flex-start; }
.kalenderablage__zeit { font-size: 13px; }
.kalenderablage__quelle { font-size: 12px; overflow-wrap: anywhere; }
.kalenderablage__hinweis { font-size: 12px; color: var(--text); }

.kalenderablage__team {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
}

.ablage__eingabe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.ablage__eingabe:disabled {
    cursor: progress;
}

/* Die Anteile einer aufgeteilten Ausgabe: je Anteil zwei Zeilen – oben das Ziel (Projekt,
   Kostenstelle), unten die Beträge. Als Tabelle mit sieben Spalten blieben in der 560 Pixel
   breiten Maske für das Projekt zwei Wörter. `minmax(0, …)` und nicht `1fr`: Sonst hielte die
   Mindestbreite des Vorschlagsfeldes die Spalte auf und schöbe den Rest über den Rand. */
.aufteilung {
    border-top: 1px solid var(--rand);
}

.aufteilung__anteil {
    display: grid;
    gap: 6px;
    padding: 8px 0;
    border-bottom: 1px solid var(--rand);
}

.aufteilung__ziel {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
}

.aufteilung__ziel--zwei {
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
}

.aufteilung__betrag {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 126px 110px 92px 28px;
    gap: 6px;
    align-items: center;
}

.aufteilung__brutto {
    text-align: right;
    white-space: nowrap;
    font-weight: 600;
}

/* Die Liste als Ablage (Ausgaben). Das Dateifeld liegt nur während des Ziehens über der
   Fläche und nimmt den Wurf; der Schleier darunter zeigt, dass man treffen wird, und lässt den
   Zeiger durch. Der Satz steht oben und nicht in der Mitte: Bei fünfzig Zeilen läge die Mitte
   unter dem Bildschirmrand. */
.ablagebereich {
    position: relative;
}

.ablagebereich__eingabe {
    position: absolute;
    inset: 0;
    z-index: 3;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: copy;
}

.ablagebereich__schleier {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 72px 24px 0;
    border: 2px dashed var(--primaer);
    border-radius: var(--radius);
    background: color-mix(in srgb, var(--flaeche) 86%, transparent);
    color: var(--text-stark);
    font-size: 14px;
    font-weight: 600;
    text-align: center;
    pointer-events: none;
}

.leer-hinweis h3 { color: var(--text); margin-bottom: 6px; }

/* ---------- Abzeichen ---------- */
/* Statuspillen mit blassem Grund, dunkler Schrift und einem farbigen Punkt. Volltonfarben
   über zwanzig Tabellenzeilen ergeben einen Flickenteppich, in dem gerade das Auffällige
   untergeht; so bleibt die Farbe erkennbar und die Liste ruhig. */
.abzeichen {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 23px;
    padding: 0 10px;
    border-radius: 9999px;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    border: 1px solid transparent;
}

.abzeichen::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    opacity: .9;
    flex: 0 0 6px;
}

/* Der Rand jedes Abzeichens kommt aus seiner **eigenen Schriftfarbe** und nicht aus einer
   eigenen Farbe je Art. Sechs feste Pastelltöne standen hier – im Hellen richtig, im Dunkeln
   ein leuchtender Ring um eine dunkle Pille. Aus `currentColor` folgt der Rand jeder Farbwelt
   von selbst, und die nächste Abzeichenart braucht keinen siebten Ton. */
.abzeichen--blau {
    background: var(--primaer-blass);
    color: var(--primaer-dunkel);
    border-color: color-mix(in srgb, currentColor 26%, transparent);
}

.abzeichen--gruen {
    background: var(--gruen-blass);
    color: var(--gruen-dunkel);
    border-color: color-mix(in srgb, currentColor 26%, transparent);
}

.abzeichen--gelb {
    background: var(--gelb-blass);
    color: var(--gelb-dunkel);
    border-color: color-mix(in srgb, currentColor 26%, transparent);
}

.abzeichen--rot {
    background: var(--rot-blass);
    color: var(--rot-dunkel);
    border-color: color-mix(in srgb, currentColor 26%, transparent);
}

.abzeichen--slate {
    background: var(--slate-blass);
    color: var(--slate);
    border-color: color-mix(in srgb, currentColor 26%, transparent);
}

.abzeichen--grau {
    background: var(--flaeche-grau);
    color: var(--text);
    border-color: var(--rand);
}

.abzeichen--navy {
    background: var(--navy-blass);
    color: var(--navy-schrift);
    border-color: color-mix(in srgb, currentColor 26%, transparent);
}

/* ---------- Karten ---------- */
.karte {
    background: var(--flaeche);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten);
    overflow: hidden;
}

/* Solange in einer Karte eine Vorschlagsliste offen ist (Kunde, Projekt, Adresse), schneidet sie
   nicht ab: Die Liste klappt über den Kartenrand hinaus, und abgeschnitten stand sie hinter der
   nächsten Karte – gemeldet an der Briefseite. Nur während sie offen ist, damit die runden Ecken
   sonst bleiben, wie sie sind. */
.karte:has(.vorschlagsliste) { overflow: visible; }

.karte__kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 15px 18px;
    border-bottom: 1px solid var(--rand-zart);
}

.karte__kopf h3 {
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-schwach);
}

.karte__koerper { padding: 18px; }

/* ---------- Warenkörbe ---------- */
/* Der Kopf eines Korbs ist zugleich der Griff zum Klappen. Ein Knopf und kein klickbares `div`,
   damit er mit der Tastatur erreichbar ist und `aria-expanded` sagt, was er tut. Weil er wie eine
   Zeile aussehen soll, verliert er Grund und Rand – und bekommt deshalb Schrift und Farbe
   ausdrücklich: Ein `<button>` erbt beides nicht, und im Dunkeln stünde sonst Schwarz auf
   Schwarz (die Falle der Hilfetreffer in der Suchleiste, siehe `DunkelmodusTests`). */
.warenkorb .karte__kopf { flex-wrap: wrap; }

.warenkorb__klappe {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    flex: 1 1 auto;
    min-width: 0;
    padding: 0;
    background: none;
    border: none;
    font: inherit;
    color: var(--text);
    text-align: left;
    cursor: pointer;
}

.warenkorb__klappe:disabled { cursor: default; }

.warenkorb__eckdaten {
    font-size: 12px;
    color: var(--text-schwach);
}

/* Zugeklappt ist der Kopf die ganze Karte – die Linie darunter trennte sonst nichts. */
.warenkorb--zu .karte__kopf { border-bottom: none; }

.warenkorbleiste {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
    font-size: 13px;
}

.kennzahlen {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-bottom: 22px;
}

/* ---------- Der Aufbau der Übersicht: Arbeit links, Begleitung rechts ----------
   Die rechte Spalte läuft über die **ganze Seitenhöhe**: Wetter oben, Forderungen darunter. Beides
   ist Begleitung – das eine sagt, ob morgen gearbeitet werden kann, das andere, was noch
   hereinkommen muss –, und in einer Spalte sind sie von selbst gleich breit.

   **Der Gewinn liegt links.** Solange das Wetter in der Kopfzeile saß, streckte es sie auf seine
   Höhe, und Schnellzugriff und Tagesplan rutschten um den Unterschied nach unten. Jetzt bestimmen
   Anliegen und Zahlen ihre Höhe selbst.

   `align-items: start`, damit die kürzere Spalte oben bleibt, statt sich auf die Höhe der
   längeren zu strecken – eine Karte mit hundert Pixeln Luft unter dem letzten Eintrag sieht aus,
   als fehle etwas. */
.uebersichtsraster {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(250px, 320px);
    gap: 22px;
    align-items: start;
}

/* Innerhalb der Spalten: gleichmäßiger Abstand, ohne dass jeder Baustein ihn selbst mitbringt.
   Das Anliegenband erscheint nur, wenn etwas liegen geblieben ist – brächte es seinen eigenen
   `margin-bottom` mit, stünde an einem aufgeräumten Tag eine Lücke über den Zahlen. */
.uebersichtsraster__haupt > * + *,
.uebersichtsraster__seite > * + * { margin-top: 18px; }

.uebersichtsraster .anliegen-band,
.uebersichtsraster .kennzahlen { margin-bottom: 0; }

/* **Die Schwelle ist gemessen, und die erste Rechnung dazu war falsch.** Angesetzt hatte ich die
   Seitenspalte mit ihrem *Mindestmaß* von 250 – sie nimmt aber ihr *Höchstmaß* von 320, und die
   Zahlen standen daraufhin zwei und eins, wo drei hätten stehen sollen.

   Am Bildschirm nachgemessen war die Folgerung daraus trotzdem verkehrt: Bei 1310 Pixeln ist der
   Kopf **439** Pixel hoch (zweispaltig, Zahlen zwei und eins), bei 1290 dagegen **533**
   (einspaltig, Wetter in eigener Reihe darunter). Die umgebrochenen Zahlen kosten also weniger
   als eine eigene Wetterzeile – und rechts stehen soll es ja gerade.

   Die Schwelle liegt deshalb dort, wo neben der Spalte nicht einmal mehr zwei Zahlenkacheln
   Platz haben: 2 × 235 + 16 + 320 + 22 = 828 Inhalt, plus Menüleiste und Ränder (288) sind
   1116 Pixel. */
@media (max-width: 1115px) {
    .uebersichtsraster { grid-template-columns: minmax(0, 1fr); }

    /* **Einspaltig entscheidet die Wichtigkeit und nicht die Spalte.** Untereinander gibt es
       kein „links" und kein „rechts"; gelesen wird von oben, und dann gilt: erst was liegen
       geblieben ist, dann wer etwas will, dann der Tag, zuletzt die Begleitung.

       Die Zahlen standen hier einmal an zweiter Stelle – bis sie über die Termine wanderten und
       damit in die Tagesspalte. Seither tragen sie deren Rang, und das ist richtig so: Sie
       zählen genau diesen Tag aus und gehören unmittelbar über seine Liste.

       `display: contents` löst die Hauptspalte auf, sodass ihre Kinder und die Seitenspalte
       gemeinsam in einer Reihe stehen und sich über `order` mischen lassen. Das ist die eine
       Stelle dieser Seite, an der die gesehene von der gelesenen Reihenfolge abweicht, und sie
       ist eng begrenzt: Verschoben werden nur ganze Blöcke, nichts in ihnen. */
    .uebersichtsraster { display: flex; flex-direction: column; gap: 18px; }
    .uebersichtsraster__haupt { display: contents; }

    /* Die Vorgabe gilt dem Nachrichtenkorb und allem, was später dazukommt: Wer angesprochen
       wurde, liest es vor dem Tagesplan. */
    .uebersichtsraster__haupt > * { order: 2; }
    .uebersichtsraster__haupt > .anliegen-band { order: 1; }
    .uebersichtsraster__haupt > .tagesraster { order: 3; }
    .uebersichtsraster__seite { order: 4; }

    /* Die Abstände macht jetzt das `gap` – der Aufschlag auf jedes zweite Kind ergäbe darüber
       hinaus doppelte Luft. */
    .uebersichtsraster__haupt > * + * { margin-top: 0; }
}

/* ---------- Gestaffeltes Hereinfahren ----------
   Die Übersicht ist der einzige Bildschirm, auf dem alles zugleich erscheint: ein halbes Dutzend
   Flächen, die ohne Ordnung aufblitzen. Ein Versatz von wenigen Hundertstelsekunden gibt ihnen
   eine Reihenfolge und sagt damit, was zuerst zu lesen ist.

   **Der Rang steht am Element und nicht als `:nth-child`.** Die Hälfte der Flächen erscheint nur
   unter Bedingungen (Anliegen, Nachrichten, die Belegspalte); gezählte Kinder verrutschen damit,
   und der Versatz säße am falschen Kasten.

   Es läuft **einmal** und nicht bei jedem Neuzeichnen: `both` hält den Endzustand. Wer Bewegung
   abgestellt hat, bekommt sie nicht – dafür sorgt die Sammelregel weiter unten, und weil `both`
   den Endzustand hält, steht die Fläche dann sofort und vollständig da. */
@keyframes uebersicht-auf {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

.auf {
    animation: uebersicht-auf .38s cubic-bezier(.2, .7, .3, 1) both;
    animation-delay: calc(var(--rang, 0) * 55ms);
}

/* ---------- Schnellzugriff ----------
   Kacheln, die sich jeder selbst aus dem Menü zieht. Die Farbe steht als Variable an der
   Kachel – gesetzt wird sie am Element, weil sie vom Benutzer kommt und nicht aus dem
   Stilblatt kommen kann; der Server lässt dafür nur einen Hexwert durch. */
.schnellzugriff { margin-bottom: 22px; }

.schnellzugriff__leer {
    border: 1px dashed var(--rand);
    border-radius: var(--radius-gross);
    padding: 16px 18px;
    color: var(--text-schwach);
    font-size: 13px;
    line-height: 1.55;
    background: var(--flaeche);
}

.schnellzugriff__leer strong { color: var(--text-stark); }

.schnellzugriff__hinweis {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: var(--text-schwach);
}

/* Während etwas gezogen wird, zeigt der ganze Bereich, dass er annimmt. Ohne dieses Zeichen
   zieht man auf gut Glück und lässt daneben los. */
.schnellzugriff--bereit .schnellzugriff__leer,
.schnellzugriff--bereit .schnellzugriff__brett {
    outline: 2px dashed var(--primaer);
    outline-offset: 4px;
    border-radius: var(--radius-gross);
}

.schnellzugriff__brett {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
    gap: 12px;
}

.schnellzugriff__kachel {
    position: relative;
    background: var(--flaeche);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten);
    overflow: hidden;

    /* Der farbige Streifen oben statt einer farbigen Fläche: Die Kachel bleibt lesbar, und
       sechs verschiedene Volltonflächen nebeneinander sähen aus wie ein Spielbrett. */
    border-top: 3px solid var(--kachelfarbe);
    cursor: grab;
}

.schnellzugriff__kachel--ziel { outline: 2px solid var(--primaer); outline-offset: 2px; }

.schnellzugriff__sprung {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 13px 14px 9px;
    color: var(--text-stark);
}

.schnellzugriff__sprung:hover { text-decoration: none; background: var(--flaeche-blass); }

.schnellzugriff__zeichen {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    flex: 0 0 34px;
    border-radius: var(--radius-klein);
    background: color-mix(in srgb, var(--kachelfarbe) 12%, var(--flaeche));
    color: var(--kachelfarbe);
}

.schnellzugriff__titel {
    font-size: 14px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.schnellzugriff__werkzeuge {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 0 10px 9px;
}

.schnellzugriff__werkzeug {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: none;
    border-radius: var(--radius-klein);
    padding: 5px 7px;
    font: inherit;
    font-size: 12px;
    color: var(--text-schwach);
    cursor: pointer;
}

.schnellzugriff__werkzeug:hover { background: var(--flaeche-blass); color: var(--text-stark); }

.schnellzugriff__werkzeug--neu { margin-right: auto; color: var(--kachelfarbe); font-weight: 500; }
.schnellzugriff__werkzeug--neu:hover { color: var(--kachelfarbe); text-decoration: none; }

.schnellzugriff__farbpunkt {
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--kachelfarbe);
    display: inline-block;
}

.schnellzugriff__farben {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 0 10px 11px;
}

.schnellzugriff__farbe {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    border: 1px solid rgba(0, 0, 0, .1);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-schwach);
}

.schnellzugriff__farbe--keine { background: var(--flaeche); }

/* ---------- Der Schnellzugriff als Liste in einem Kasten ----------
   Auf der Übersicht steht er in der schmalen Werkzeugspalte, und dort ist das Brett aus Kacheln
   die falsche Form: Über die volle Breite kostete es oben rund neunzig Pixel, und zwar genau
   dort, wo der Tagesplan anfangen will. Als Liste steht dasselbe auf einem Viertel der Fläche,
   und es liest sich besser – Ziele sind eine **Aufzählung** und kein Raster; man geht sie von
   oben nach unten durch, nicht zeilenweise.

   **Der Farbstreifen wandert dabei von oben nach links.** Über einer 46 Pixel hohen Zeile wäre
   eine Dreipunktlinie kaum zu sehen und zerschnitte die Liste in Bänder; links ist es dieselbe
   Kennzeichnung wie am Anliegen und an der Terminzeile – in diesem Haus heißt „Streifen links"
   seit je „hierzu gehört diese Farbe". */
.schnellzugriff--liste .schnellzugriff__brett {
    display: flex;
    flex-direction: column;
    gap: 0;
}

/* `color` gehört dazu, und das hat der Wächter gefunden: Die Zeile nimmt sich Grund und Rand,
   und wer ein Bedienelement so entkleidet, muss auch sagen, welche Schrift es trägt – sonst
   bleibt sie im Dunkeln schwarz. Hier erbt sie zwar ohnehin von der Karte; die Regel gilt der
   **Form**, und eine Ausnahmeliste wäre an dieser Stelle der bequeme und falsche Weg. */
.schnellzugriff--liste .schnellzugriff__kachel {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    background: none;
    color: var(--text);
    border: 0;
    border-top: 1px solid var(--rand-zart);
    border-left: 3px solid var(--kachelfarbe);
    border-radius: 0;
    box-shadow: none;
}

.schnellzugriff--liste .schnellzugriff__kachel:first-child { border-top: 0; }

/* **Zeichen und Wort sind groß, die Spalte bleibt schmal.** Gemeldet: Die Kacheln seien zu klein,
   um sie auf einen Blick zu erkennen – gewünscht war mehr Größe, aber kein breiterer Kasten, denn
   daneben steht der Tagesplan. Deshalb wächst die Zeile in die **Höhe**: 40er-Kreis mit
   22er-Zeichen, 16,5 Punkt Schrift, und ein langes Wort bricht um (mit Silbentrennung, die Seite
   ist `lang="de"`), statt auf „Leistungsverz…" gekürzt zu werden – ein abgeschnittenes Wort
   erkennt man schlechter als ein kleines. Gemessen: Bei 340 Pixeln Spalte bleiben dem Titel 192,
   „Leistungsverzeichnisse" steht in einer Zeile; bei der schmalsten Spalte (280) bleiben 139 und
   zwei Zeilen. Drei sind erlaubt als Reserve für einen längeren Menünamen. */
.schnellzugriff--liste .schnellzugriff__sprung { gap: 12px; padding: 11px 10px 11px 12px; }

.schnellzugriff--liste .schnellzugriff__zeichen {
    width: 40px;
    height: 40px;
    flex-basis: 40px;
}

.schnellzugriff--liste .schnellzugriff__titel {
    font-size: 16.5px;
    font-weight: 600;
    line-height: 1.25;
    white-space: normal;
    hyphens: auto;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
}

/* Die Werkzeuge stehen in der Zeile und nicht mehr darunter: In der Kachel war die zweite Zeile
   der Platz dafür, in einer Liste wäre sie eine halbe Zeile Leerraum je Eintrag.
   **Übereinander statt nebeneinander:** „Neu" oben, Farbe und Entfernen darunter. Die Zeile ist
   mit dem 40er-Kreis ohnehin so hoch, und die Spalte wird halb so breit – das sind gut fünfzig
   Pixel für den Titel, genug, dass „Leistungsverzeichnisse" bei 340 Pixeln in eine Zeile passt.
   Nebeneinander brach es auch dort um, und ohne Silbentrennung (die nicht jeder Browser für
   Deutsch mitbringt) mitten in der Silbe. */
.schnellzugriff--liste .schnellzugriff__werkzeuge {
    display: grid;
    grid-template-columns: auto auto;
    justify-items: center;
    gap: 0;
    padding: 0 6px 0 0;
}
.schnellzugriff--liste .schnellzugriff__werkzeug { padding: 4px 5px; }
.schnellzugriff--liste .schnellzugriff__werkzeug--neu { grid-column: 1 / -1; font-size: 13.5px; margin-right: 0; }

/* Die Farbauswahl klappt unter die Zeile und darf deshalb über beide Rasterspalten laufen –
   sonst stünde sie gequetscht neben dem Sprung. */
.schnellzugriff--liste .schnellzugriff__farben { grid-column: 1 / -1; }

.schnellzugriff--liste .schnellzugriff__leer { border-radius: 0; border: 0; }

/* In der Liste ist die Ablagestelle eine Zeile und kein Kästchen. */
.schnellzugriff--liste .schnellzugriff__ablage { border-radius: 0; }

/* Die Ablagefläche erscheint erst, während etwas aus dem Menü unterwegs ist – ein
   gestrichelter Kasten, der immer dasteht, ist nur ein Loch in der Reihe. */
.schnellzugriff__ablage {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 86px;
    border: 2px dashed var(--primaer);
    border-radius: var(--radius-gross);
    color: var(--primaer);
    font-size: 13px;
}

/* Die Arbeitsfläche in **zwei Spalten: Werkzeug und Tag.** Die Forderungen stehen in der
   Seitenspalte der Seite; hier bleibt, woran gearbeitet wird.

   Rechts stehen die Zahlen des Tages **und** die Termine, die sie auszählen. Die linke Spalte
   hat eine **Obergrenze** und keine feste Breite: Auf einem breiten Bildschirm soll der Tagesplan
   wachsen, nicht das Sprungbrett – und die drei Zahlen daneben brauchen jeden Pixel, um in einer
   Reihe zu bleiben. Deshalb ist die Obergrenze hier 340 und nicht mehr 360. */
.tagesraster {
    display: grid;
    gap: 22px;
    align-items: start;
    grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
}

@media (max-width: 900px) {
    .tagesraster { grid-template-columns: minmax(0, 1fr); }

    /* **Einspaltig kehrt sich die Reihenfolge um.** Nebeneinander liest man links zuerst;
       untereinander hieße „links zuerst" so viel wie „Schnellzugriff vor dem Tagesplan", und wer
       auf dem Telefon die Übersicht aufmacht, will seine Termine sehen und nicht erst zweimal
       wischen. Die Werkzeugspalte rutscht deshalb ans Ende.

       Untereinander gibt es kein „links"; die Tastatur läuft weiter von oben nach unten durch
       beide Spalten. */
    .tagesraster > :first-child { order: 2; }
}

/* ---------- Die Forderungen: dieselbe Auskunft auf zwei Dritteln der Fläche ----------
   Kunde und Betrag stehen in einer Zeile, Nummer und Fälligkeit klein darunter. Vorher war das
   ein `flex` mit zwei Blöcken; in einer 250 Pixel schmalen Spalte brach der Kundenname dabei um
   und schob den Betrag aus der Zeile. Als Raster mit zwei Spalten bleibt der Betrag rechts und
   der Name kürzt sich. */
.forderung {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0 8px;
    padding: 7px 0;
    border-bottom: 1px solid var(--rand-zart);
    color: var(--text);
}

.forderung:last-child { border-bottom: 0; }
.forderung:hover { text-decoration: none; }

.forderung__kunde {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-stark);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.forderung__betrag {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-stark);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Über beide Spalten: Nummer und Fälligkeit gehören zusammen und sollen nicht am Betrag
   abgeschnitten werden. */
.forderung__zusatz {
    grid-column: 1 / -1;
    font-size: 11.5px;
    color: var(--text-schwach);
}

.forderungen .karte__koerper { padding: 10px 14px; }

/* ---------- Vorschau des Bewertungscodes in den Einstellungen ----------
   Code links, Text rechts – wie auf dem Blatt (`BelegPdfDienst.Codebaustein`). Der Code bringt
   seinen weißen Grund selbst mit; auf dunkler Fläche ist das der Rand, den die Kamera braucht. */
.bewertungsvorschau {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--rand-zart);
}

.bewertungsvorschau__code {
    width: 132px;
    height: 132px;
    border-radius: var(--radius-klein);
}

/* ---------- Auslaufende Wartungsverträge ----------
   Gebaut wie die Forderungen darüber – dieselbe Spalte, dieselbe Zeilenform –, nur trägt die
   rechte Spalte den Stand („endet in 23 Tagen“) statt eines Betrags. Ein Streifen links in
   Gelb, ab dreißig Tagen in Rot: in diesem Haus heißt „Streifen links“ seit je „hierzu gehört
   diese Farbe“. Die Schrift des Standes nimmt die dunkle Fassung des Tons, die in beiden Welten
   als Schrift taugt. */
.wartungsauslauf { border-left: 3px solid var(--gelb); }
.wartungsauslauf .karte__koerper { padding: 10px 14px; }

.wartungsauslauf__zeile {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0 8px;
    padding: 7px 0;
    border-bottom: 1px solid var(--rand-zart);
    color: var(--text);
}

.wartungsauslauf__zeile:last-of-type { border-bottom: 0; }
.wartungsauslauf__zeile:hover { text-decoration: none; }

.wartungsauslauf__kunde {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-stark);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wartungsauslauf__stand {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--gelb-dunkel);
    white-space: nowrap;
}

.wartungsauslauf__zeile--dringend .wartungsauslauf__stand { color: var(--rot-dunkel); }

.wartungsauslauf__zusatz {
    grid-column: 1 / -1;
    font-size: 11.5px;
    color: var(--text-schwach);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.wartungsauslauf__mehr {
    padding-top: 6px;
    font-size: 12px;
    color: var(--text-schwach);
}

/* ---------- Der Tagesplan ----------
   Die Termine standen als Tabelle mit vier Spalten. Eine Tabelle ist richtig, wo verglichen und
   sortiert wird; hier wird keines von beidem getan – der Tag hat eine Reihenfolge, und sie ist
   die Zeit. Auf 375 Pixeln war die Tabelle außerdem die Stelle, an der waagerecht gewischt
   werden musste, und die Projektspalte stand rechts außerhalb.

   Die Zeit steht groß links, der Rest hängt daran. Der Farbstreifen ist die Kalenderfarbe des
   Termins – derselbe Wert, der in der Tabelle als 8-Pixel-Punkt neben dem Titel stand und dort
   nichts geordnet hat. */
.tagesplan__zeile {
    display: grid;
    grid-template-columns: 70px 3px minmax(0, 1fr) auto;
    gap: 0 14px;
    align-items: center;
    padding: 12px 18px;
    border-top: 1px solid var(--rand-zart);
    color: var(--text);
    text-decoration: none;
    cursor: pointer;
    transition: background .14s ease;
}

.tagesplan__zeile:first-child { border-top: 0; }
.tagesplan__zeile:hover { background: var(--flaeche-blass); text-decoration: none; }

.tagesplan__zeit {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-stark);
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}

.tagesplan__dauer { font-size: 11.5px; color: var(--text-schwach); }

.tagesplan__streifen {
    align-self: stretch;
    min-height: 36px;
    border-radius: 999px;
    background: var(--kalenderfarbe, var(--slate));
}

.tagesplan__titel { font-weight: 500; color: var(--text-stark); }
.tagesplan__projekt { font-size: 12px; color: var(--text-schwach); }

/* **Was vorbei ist, tritt zurück – aber nicht der Text.** Der erste Entwurf legte
   `opacity: .55` auf die ganze Zeile. Das sah richtig aus und war gemessen falsch: Der Titel
   stand danach bei 3,73 : 1, die Projektzeile bei **1,88 : 1**. Deckkraft multipliziert sich mit
   der Schriftfarbe, und `--text-schwach` ist schon eine schwache; beide zusammen ergeben eine
   Zeile, die auf einem Tablet im Fahrzeug nicht mehr zu lesen ist.

   Inhaltlich ist es ohnehin der falsche Griff: In einen erledigten Termin sieht man hinein, um
   nachzulesen, was dort war. Zurück tritt deshalb das Zeichen – der Farbstreifen verblasst, die
   Uhrzeit wird still –, und was dasteht, bleibt lesbar. Dass der Termin vorbei ist, sagt das
   Abzeichen. */
.tagesplan__zeile--vergangen .tagesplan__streifen { opacity: .38; }
.tagesplan__zeile--vergangen .tagesplan__zeit { color: var(--text-schwach); }

/* Die Jetzt-Marke. Sie ist der Grund, warum diese Liste keine Tabelle mehr ist: Zwischen „war"
   und „kommt" liegt eine Linie, und die kann eine Tabellenzeile nicht sein. */
.tagesplan__jetzt {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 18px;
}

/* **Die Uhrzeit trägt den Text, die Marke trägt die Farbe.** In `--akzent` gesetzt stand sie bei
   3,44 : 1 (im Orange von damals; im Blau der Marke sind es 3,95) – für 11,5 Pixel fett zu wenig,
   und eine dunklere Fassung des Tons gibt es nicht.
   Punkt und Linie sagen ohnehin, was hier los ist; die Zahl muss man lesen können. Dieselbe
   Überlegung wie an der Befundzahl: Der Unterschied darf nicht allein in der Farbe stecken. */
.tagesplan__jetzt-zeit {
    width: 70px;
    flex: 0 0 70px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-stark);
    font-variant-numeric: tabular-nums;
}

.tagesplan__jetzt-punkt {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--akzent);
    animation: jetzt-puls 2.4s ease-out infinite;
}

.tagesplan__jetzt-linie {
    flex: 1 1 auto;
    height: 2px;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--akzent), transparent);
}

/* Der Punkt pulst – 2,4 Sekunden, ohne Farbwechsel; was blinkt, wird weggesehen. */
@keyframes jetzt-puls {
    0%        { box-shadow: 0 0 0 0 color-mix(in srgb, var(--akzent) 50%, transparent); }
    70%, 100% { box-shadow: 0 0 0 9px transparent; }
}

/* Auf schmalen Geräten rutscht das Abzeichen unter den Titel – es rechts danebenzulassen
   drückte den Titel auf wenige Zeichen. */
@media (max-width: 640px) {
    .tagesplan__zeile { grid-template-columns: 60px 3px minmax(0, 1fr); row-gap: 6px; }
    .tagesplan__zeile > .abzeichen { grid-column: 3; justify-self: start; }
}

.kennzahl {
    background: linear-gradient(180deg, var(--flaeche) 0%, var(--flaeche-blass) 100%);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-gross);
    padding: 17px 19px;
    box-shadow: var(--schatten);
    transition: box-shadow .16s ease, transform .16s ease;
}

.kennzahl:hover {
    box-shadow: var(--schatten-mittel);
    transform: translateY(-1px);
}

.kennzahl__titel {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--text-schwach);
    margin-bottom: 8px;
}

.kennzahl__wert {
    font-size: 28px;
    font-weight: 600;
    color: var(--text-stark);
    letter-spacing: -.03em;
}

.kennzahl__fuss {
    margin-top: 6px;
    font-size: 12px;
    color: var(--text-schwach);
    display: flex;
    align-items: center;
    gap: 6px;
}

/* ---------- Eine Leitzahl statt lauter gleichrangiger ----------
   Gleich große Kacheln sagen: alles ist gleich wichtig. Das ist nie wahr – „Heute abrechenbar"
   ist die Zahl, wegen der jemand morgens hinsieht, und der Rest ist Begleitung. Hervorgehoben
   wird sie über Tönung und Schriftgröße.

   **Die Breite trägt die Stufung nicht mit.** `auto-fit` verteilt gleichmäßig und kommt mit zwei
   Kacheln ebenso zurecht wie mit drei – einem Handwerker fehlt die Leitzahl, und dort steht dann
   keine leere Spur.

   **Gleich hoch, und das ist der Standard – `align-items` steht hier absichtlich nicht.** Die
   drei beantworten dieselbe Frage aus drei Richtungen: was der Tag einbringt, was von ihm
   dokumentiert ist, wie viel davon erfasst. Eine Reihe mit drei verschiedenen Unterkanten läse
   sich, als gehörten sie nicht zusammen. (Solange das Wetter als vierte Kachel in dieser Zeile
   stand, brauchte es hier `start` – sonst hätten Ring und Balken über hundert Pixel Luft unter
   sich bekommen. Seit das Wetter in der Seitenspalte steht, ist die Ausnahme weg.) */
/* **190 und nicht 235, seit die Zahlen über den Terminen stehen.** Dort bleiben ihnen neben dem
   Sprungbrett 608 Pixel; drei Kacheln zu 235 plus zwei Abstände wären 502 zu viel – gemessen
   standen sie zwei und eins, und die dritte allein in der zweiten Reihe. Mit 190 gehen 602 auf. */
.kennzahlen--gestuft {
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}

/* Jede Kachel ist ihr eigener Container – siehe die Schriftgröße der Leitzahl weiter unten. */
.kennzahl { container-type: inline-size; }

.kennzahl--leit {
    background: linear-gradient(140deg,
                color-mix(in srgb, var(--primaer) 10%, var(--flaeche)) 0%,
                var(--flaeche) 58%);
    border-color: color-mix(in srgb, var(--primaer) 24%, var(--rand-zart));
}

.kennzahl--leit .kennzahl__wert { font-size: 38px; }

/* **Die Leitzahl wächst mit ihrer Kachel.** „2.437,50 €" braucht bei 38 Pixeln rund 160 – in
   einer 190 Pixel schmalen Kachel bleiben davon 152, und acht Pixel standen über dem Rand.
   Entschieden wird an der Breite der **Kachel** und nicht an der des Fensters: Dieselbe Kachel
   steht auf einem großen Bildschirm breit und auf einem schmalen eng, und nur sie selbst weiß,
   wie viel sie hat.

   **Die Regel steht hier unten und nicht oben bei der Container-Angabe**, und das ist kein
   Ordnungsgeschmack: Eine Container-Abfrage hebt die Spezifität nicht an. Weiter oben notiert
   verlor sie gegen die 38 Pixel darüber – die Kachel war 192 breit, die Abfrage traf zu, und die
   Schrift blieb trotzdem groß. Gemessen, nicht vermutet; am Bildschirm sah man nichts, weil im
   Entwicklungsbestand „0,00 €" steht und das auch groß hineinpasst. */
@container (max-width: 235px) {
    .kennzahl--leit .kennzahl__wert { font-size: 27px; }
}

/* **Die Fußzeile der Leitkachel trägt `--text` und nicht `--text-schwach`.** Auf dem getönten
   Grund fiel sie gemessen auf 3,19 : 1 – der Hauswert liegt auf weißem Grund bei 3,48, und die
   Tönung drückt ihn weiter. Dort steht aber die Lücke („3,5 Std. ohne Stundensatz – nicht
   enthalten"), und die ist keine Beschriftung, sondern die Einschränkung der Zahl darüber: Wer
   sie nicht liest, hält den Betrag für die ganze Leistung des Tages. */
.kennzahl--leit .kennzahl__fuss { color: var(--text); }

/* ---------- Die Quote als Ring ----------
   „3/5" ist eine Rechenaufgabe; ein Ring ist eine Antwort. Gezeichnet wird er über
   `stroke-dashoffset` und nicht als Balken, weil eine Quote ein Anteil an einem Ganzen ist und
   kein Weg zu einem Ziel. Umfang bei r = 22 ist 138,2 – er steht als Variable am Element, damit
   die Regel den Radius nicht kennen muss. */
.quote { display: flex; align-items: center; gap: 15px; }
.quote__ring { flex: 0 0 auto; transform: rotate(-90deg); }
.quote__bahn { stroke: var(--rand); }

.quote__wert {
    stroke: var(--gruen);
    stroke-linecap: round;
    stroke-dasharray: var(--umfang);
    stroke-dashoffset: var(--umfang);
    animation: quote-fuellen .9s cubic-bezier(.2, .7, .3, 1) .3s both;
}

.quote__wert--knapp { stroke: var(--gelb); }

@keyframes quote-fuellen { to { stroke-dashoffset: var(--rest); } }

/* ---------- Soll und Ist in einer Kachel ----------
   „Geplante Stunden" und „Erfasste Zeit" standen als zwei Kacheln nebeneinander, und jeder hat
   sie im Kopf verglichen. Der Vergleich ist die Aussage, also gehört er in eine Fläche. Über
   hundert Prozent läuft der Balken nicht über, sondern färbt um – mehr gearbeitet als geplant
   ist kein Fehler, aber eine Auskunft. */
.balken {
    height: 8px;
    border-radius: 999px;
    background: var(--flaeche-grau);
    overflow: hidden;
    margin-top: 12px;
}

.balken__fuell {
    height: 100%;
    border-radius: 999px;
    width: 0;
    background: linear-gradient(90deg, var(--primaer), var(--primaer-dunkel));
    animation: balken-fuellen .85s cubic-bezier(.2, .7, .3, 1) .3s both;
}

.balken__fuell--ueber { background: linear-gradient(90deg, var(--gelb), var(--gelb-dunkel)); }

@keyframes balken-fuellen { to { width: var(--anteil); } }

@media (max-width: 640px) {
    .kennzahlen--gestuft { grid-template-columns: minmax(0, 1fr); }
    .kennzahl--leit .kennzahl__wert { font-size: 32px; }
}

.trend {
    display: inline-flex;
    align-items: center;
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 500;
}

.trend--plus { background: var(--gruen-blass); color: var(--gruen-dunkel); }
.trend--minus { background: var(--rot-blass); color: var(--rot-dunkel); }
.trend--neutral { background: var(--flaeche-grau); color: var(--text-schwach); }

/* ---------- Reiter ---------- */
/* Die Reiterzeile bricht um, statt über den Rand zu laufen. Bei elf Reitern passte sie noch
   in eine Zeile, beim zwölften stand der letzte außerhalb – erreichbar war er dann nicht mehr,
   und gefehlt hätte er erst dem, der ihn sucht. Ein seitliches Rollen wäre die andere
   Möglichkeit; es versteckt die hinteren Reiter aber genauso, nur mit Balken. */
.reiter {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    border-bottom: 1px solid var(--rand);
    margin-bottom: 18px;
}

/* **Der ruhende Reiter war zu blass.** `--text-schwach` ist die Farbe jeder Nebenangabe im
   Haus und stand auch hier – auf der Arbeitsfläche gemessen **3,40 : 1**, bei vierzehn Pixeln
   ohne Fettung. Die Richtlinie verlangt 4,5, und sie hat recht: Von fünf Reitern sind vier
   ruhend, also ist das die Schrift, die man liest, um zu wechseln.

   Der Ton ist **derselbe wie an den Gruppenüberschriften der Einstellungen** und steht als
   `--text-gedaempft` an einer Stelle – zwei eigens gesuchte Mischungen für dieselbe Frage
   liefen beim ersten Nachschärfen auseinander. Gemessen 5,56 : 1 im Hellen, 9,40 : 1 im
   Dunkeln.

   **Der gewählte Reiter bleibt, wie er ist**: 4,84 : 1 im Hellen und 4,60 : 1 im Dunkeln – das
   trägt. Er steht auf der Arbeitsfläche und nicht auf einer getönten Pille; die Falle von
   `--primaer-dunkel` (im Dunkeln eine Fläche und keine Schrift) schnappt hier nicht zu. Dass
   die ruhenden Reiter danach rechnerisch mehr Kontrast haben als der gewählte, ist kein
   Widerspruch: Ausgezeichnet wird er durch Farbe, Fettung und den Strich darunter, nicht
   dadurch, dass er dunkler ist. */
.reiter__punkt {
    padding: 10px 14px;
    font-size: 14px;
    color: var(--text-gedaempft);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    background: none;
    border-top: none;
    border-left: none;
    border-right: none;
    border-radius: var(--radius-klein) var(--radius-klein) 0 0;
    font-family: inherit;
    transition: color .12s ease, background .12s ease, border-color .12s ease;
}

.reiter__punkt:hover { color: var(--text-stark); background: var(--flaeche-blass); }

.reiter__punkt.aktiv {
    color: var(--primaer-dunkel);
    border-bottom-color: var(--primaer);
    font-weight: 600;
}

/* ---------- Das Menü der Einstellungen ----------
   Siebenundzwanzig Reiter in einer umbrechenden Zeile waren keine Ordnung, sondern eine
   Aufzählung: Wer „Skonto" suchte, las sie jedes Mal von vorn durch, weil eine Zeile, die je
   nach Fensterbreite anders umbricht, keine Stelle hat, die man sich merken kann. Sechs
   Gruppen mit höchstens sieben Punkten kann man einmal lernen.

   Die Spalte klebt **nicht** oben. Das wäre die reizvollere Lösung und die schlechtere: Das
   Kopfband darüber ist selbst klebend, also bräuchte ein `top` seine Höhe als Zahl – und die
   hängt an der Feldhöhe (auf dem Tablet wächst sie mit dem groben Zeiger) und daran, ob gerade
   eine Standmeldung darunter steht. Dieselbe Überlegung wie an `.kopfbereich`, nur mit dem
   umgekehrten Ausgang: Dort ließ sich beides in eine klebende Hülle fassen, hier stünde eine
   abgeschriebene Zahl, die in zwei von drei Fällen danebenliegt und die obersten Punkte hinter
   das Band schiebt. */
.einstellraster {
    display: grid;
    grid-template-columns: 218px minmax(0, 1fr);
    gap: 26px;
    align-items: start;

    /* Die Inhaltsspalte bleibt so breit wie die Masken vorher (1000 px); die Menüspalte kommt
       davor dazu, statt von ihr abzuziehen. */
    max-width: 1244px;
}

.einstellnav {
    display: flex;
    flex-direction: column;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    box-shadow: var(--schatten);
    padding: 10px 8px;
}

/* **Die Überschrift ist die kleinste Schrift des Bildschirms und deshalb nicht die blasseste.**
   `--text-schwach` lag hier nahe – es ist die Farbe jeder Nebenangabe im Haus – und kam auf
   weißem Grund auf gemessene 3,59 : 1. Für zehneinhalb Pixel verlangt die Richtlinie 4,5, und
   sie hat recht: Gerade diese sechs Wörter sucht das Auge beim Überfliegen. `--text-gedaempft`
   liegt bei 5,87 und bleibt trotzdem sichtbar hinter den Punkten (10,03) zurück – die Rangfolge
   entsteht aus Größe, Versalien und Sperrung, nicht aus Blässe. */
.einstellnav__gruppe {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--text-gedaempft);
    padding: 0 8px;
    margin: 15px 0 5px;
}

.einstellnav__gruppe:first-child { margin-top: 2px; }

.einstellnav__punkt {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 6px 8px;
    border-radius: var(--radius-klein);
    color: var(--text);
    text-decoration: none;
    font-size: 13.5px;
    line-height: 1.3;
    transition: background .12s ease, color .12s ease;
}

/* Das Symbol steht zurück, solange der Punkt nicht gemeint ist – siebenundzwanzig gleich
   kräftige Zeichen untereinander sind ein Muster und keine Hilfe. */
.einstellnav__punkt svg { flex: 0 0 auto; opacity: .65; }

.einstellnav__punkt:hover { background: var(--flaeche-blass); color: var(--text-stark); }
.einstellnav__punkt:hover svg { opacity: 1; }

/* **Der gewählte Punkt bekommt eine getönte Fläche und behält seine Schriftfarbe.** Die
   naheliegende Fassung wäre `color: var(--primaer-dunkel)` gewesen, wie an der Reiterzeile –
   und genau die ist am gewählten Reiter der Suchleiste schon einmal aufgefallen: Das Token
   trägt zwei Rollen, im Hellen Schrift und im Dunkeln Fläche, und als Schrift kam es dort auf
   3,52 : 1. Die Tönung entsteht deshalb aus der Fläche selbst und ist in beiden Welten
   dieselbe Rechnung; farbig ist nur das Symbol, und das trägt keine Auskunft, die man lesen
   muss. */
.einstellnav__punkt.aktiv {
    background: color-mix(in srgb, var(--primaer) 13%, var(--flaeche));
    color: var(--text-stark);
    font-weight: 600;
}

.einstellnav__punkt.aktiv svg { opacity: 1; color: var(--primaer); }

.einstellinhalt { min-width: 0; }

/* Unter dieser Breite bliebe für die Masken nichts übrig – das Menü legt sich dann über den
   Inhalt. Mit einem Deckel und eigener Rolle, denn siebenundzwanzig Punkte untereinander
   schöben den Inhalt sonst um rund neunhundert Pixel nach unten: Man scrollte an der ganzen
   Liste vorbei, um zu lesen, was man eben ausgewählt hat. */
@media (max-width: 960px) {
    .einstellraster { grid-template-columns: minmax(0, 1fr); gap: 18px; }
    .einstellnav { max-height: 44vh; overflow-y: auto; }
}

/* Angefasst wird die Fläche, nicht die Schrift: Die Zeilen wachsen auf die Hausgröße, der
   Schriftgrad bleibt. */
@media (pointer: coarse) {
    .einstellnav__punkt { min-height: 40px; padding: 8px 10px; }
}

/* ---------- Avatar ---------- */
.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    color: #fff;
    font-size: 11px;
    font-weight: 500;
    flex: 0 0 auto;
    letter-spacing: .3px;
}

.avatar--gross { width: 36px; height: 36px; font-size: 13px; }
.avatar-reihe { display: flex; gap: -6px; }
.avatar-reihe .avatar + .avatar { margin-left: -8px; border: 2px solid var(--flaeche); }

/* ---------- Kalender ---------- */
.kalender {
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--flaeche);
}

.kalender__kopf {
    display: grid;
    grid-template-columns: 76px repeat(7, minmax(0, 1fr));
    border-bottom: 1px solid var(--rand);
    background: var(--flaeche-blass);
}

.kalender__kopf div {
    padding: 9px 10px;
    font-size: 13px;
    color: var(--text-schwach);
    border-left: 1px solid var(--rand);
}

.kalender__kopf div:first-child { border-left: none; }
.kalender__kopf .heute { color: var(--text-stark); font-weight: 500; }

.kalender__zeile {
    display: grid;
    grid-template-columns: 76px repeat(7, minmax(0, 1fr));
    border-bottom: 1px solid var(--rand);
    min-height: 72px;
}

.kalender__zeile:last-child { border-bottom: none; }

.kalender__person {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px;
    border-right: 1px solid var(--rand);
    background: var(--flaeche-blass);
}

.kalender__zelle {
    border-left: 1px solid var(--rand);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
}

.kalender__zelle:first-of-type { border-left: none; }
.kalender__zelle.wochenende { background: var(--flaeche-blass); }

.termin {
    border-left: 3px solid var(--primaer);
    background: var(--flaeche-blass);
    border-radius: 4px;
    padding: 5px 7px;
    font-size: 12px;
    cursor: pointer;
    overflow: hidden;
}

.termin:hover { background: var(--flaeche-grau); }
.termin__titel {
    font-weight: 500;
    color: var(--text-stark);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.termin__zeit { color: var(--text-schwach); font-size: 11px; }

/* ---------- Balkendiagramm ---------- */
.diagramm {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    height: 230px;
    padding: 10px 4px 0;
    border-bottom: 1px solid var(--rand-zart);
}

.diagramm__saeule {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    height: 100%;
    gap: 6px;
}

/* Der Balken bekommt oben eine runde Kappe und einen leichten Verlauf: das ist der
   Unterschied zwischen einem gezeichneten Diagramm und einem gestapelten Kasten. */
.diagramm__balken {
    width: 100%;
    max-width: 52px;
    background: linear-gradient(180deg, #3AA0F7 0%, var(--primaer) 60%, var(--primaer-dunkel) 100%);
    border-radius: 6px 6px 2px 2px;
    min-height: 3px;
    box-shadow: 0 1px 2px rgba(10, 111, 199, .2);
    transition: filter .14s ease, transform .14s ease;
}

.diagramm__saeule:hover .diagramm__balken {
    filter: brightness(1.06) saturate(1.1);
    transform: scaleY(1.01);
    transform-origin: bottom;
}

.diagramm__achse {
    display: flex;
    gap: 10px;
    padding: 8px 4px 0;
}

.diagramm__achse span {
    flex: 1 1 0;
    text-align: center;
    font-size: 12px;
    color: var(--text-schwach);
}

/* Zwei Reihen in einer Spalte – erstellt gegen abgeschlossen, erfasst gegen verrechnet.
   Sie stehen nebeneinander und nicht gestapelt: Gestapelt läse sich die zweite Reihe als
   Teil der ersten, und genau das ist sie in der Projektauswertung nicht. */
.diagramm__paar {
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 3px;
    width: 100%;
    max-width: 52px;
    height: 100%;
}

.diagramm__paar .diagramm__balken { max-width: none; }

.diagramm__balken--zweit {
    background: linear-gradient(180deg, #7FC8A0 0%, var(--gruen) 60%, var(--gruen-dunkel) 100%);
    box-shadow: 0 1px 2px rgba(31, 122, 74, .18);
}

/* Die Erklärung der beiden Reihen. Ohne sie sind es zwei Farben ohne Bedeutung. */
.diagrammlegende {
    display: flex;
    gap: 18px;
    padding: 0 4px 10px;
    font-size: 12px;
    color: var(--text-schwach);
}

.diagrammlegende span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.diagrammlegende i {
    width: 10px;
    height: 10px;
    border-radius: 2px;
    background: var(--primaer);
}

.diagrammlegende i.zweit { background: var(--gruen); }

/* ---------- Rangliste ----------
   Ein Balken hinter der Zahl. Er ersetzt keine Spalte, er macht die Verhältnisse in einer
   Spalte sichtbar: Welcher Kunde die Hälfte des Jahres trägt, liest man an der Länge
   schneller ab als an fünfzehn Beträgen untereinander. */
.rangbalken {
    position: relative;
    height: 6px;
    border-radius: 3px;
    background: var(--flaeche-blass);
    overflow: hidden;
    margin-top: 5px;
}

.rangbalken__fuellung {
    position: absolute;
    inset: 0 auto 0 0;
    border-radius: 3px;
    background: var(--primaer);
    opacity: .8;
}

/* ---------- Trichter ----------
   Angebot → Auftrag → Rechnung. Die Stufen stehen nebeneinander und nicht als Pyramide:
   Eine gezeichnete Trichterform suggeriert, dass die Stufen auseinander hervorgehen – hier
   zählt jede für sich, was im Zeitraum entstanden ist. */
.trichter {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 12px;
}

.trichter__stufe {
    border: 1px solid var(--rand-zart);
    border-radius: 8px;
    padding: 12px 14px;
    background: var(--flaeche);
}

.trichter__name {
    font-size: 12px;
    color: var(--text-schwach);
    display: flex;
    justify-content: space-between;
    gap: 8px;
}

.trichter__wert {
    font-size: 20px;
    font-weight: 500;
    color: var(--text-stark);
    margin: 2px 0 6px;
}

.trichter__fuss {
    font-size: 11px;
    color: var(--text-schwach);
    line-height: 1.35;
}

/* ---------- Dialog ---------- */
.dialog-huelle {
    position: fixed;
    inset: 0;
    background: rgba(11, 35, 55, .42);
    backdrop-filter: blur(2px);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 48px 16px;
    z-index: 60;
    overflow-y: auto;
    animation: dialog-grund .16s ease-out;
}

.dialog {
    background: var(--flaeche);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten-hoch);
    width: 100%;
    max-width: 620px;
    animation: dialog-auf .18s cubic-bezier(.2, .8, .3, 1);
}

/* Der Dialog kommt eine Handbreit von unten herauf, statt zu erscheinen. Das ordnet ihn dem
   Blick unter – man sieht, dass er sich über die Seite legt und woher er kam. */
@keyframes dialog-auf {
    from { opacity: 0; transform: translateY(8px) scale(.99); }
    to { opacity: 1; transform: none; }
}

@keyframes dialog-grund {
    from { opacity: 0; }
    to { opacity: 1; }
}

.dialog--breit { max-width: 940px; }
.dialog--weit { max-width: 1320px; }

.dialog__kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 17px 22px;
    border-bottom: 1px solid var(--rand-zart);
}

.dialog__koerper { padding: 20px; }

/* Der Fuß bricht um, statt überzulaufen. Ein `flex` ohne Umbruch drückt seine Kinder über den
   linken Rand hinaus, wenn sie zusammen zu breit sind – auf einem Telefon stand vom
   „Abbrechen" der Rückfrage nur noch „hen" im Bild, und die Seite ließ sich seitwärts
   schieben. Sichtbar wird das erst unter etwa 520 Pixeln, also nie am Bürorechner. */
.dialog__fuss {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 20px;
    border-top: 1px solid var(--rand);
    background: var(--flaeche-blass);
    border-radius: 0 0 10px 10px;
}

/* **Kopf und Fuß bleiben stehen, wenn die Maske länger ist als das Fenster.** Gerollt wird die
   Hülle und nicht der Körper des Dialogs – so bleiben Vorschlagslisten (Adresssuche, Land) frei
   und werden nicht am Rand des Körpers abgeschnitten, was ein `overflow: auto` dort täte. Mit
   `sticky` klebt der Fuß am unteren Rand des Fensters, solange der Dialog darüber hinausreicht:
   **Speichern ist damit nie weggerollt**, gleich wie lang die Maske ist und wie klein das
   Fenster. Die Vorschlagslisten liegen mit `z-index: 40` weiter darüber. */
.dialog__kopf {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--flaeche);
    border-radius: 10px 10px 0 0;
}

.dialog__fuss {
    position: sticky;
    bottom: 0;
    z-index: 2;
}

/* ---------- Stammdatenmasken: zwei Spalten, benannte Blöcke ----------
   Kunde und Lieferant standen als eine lange Spalte untereinander – zwanzig Felder, die man
   nur durch Rollen bis zum Speichern-Knopf sah, und nichts sagte, wo die Anschrift aufhört und
   die Abrechnung anfängt. Nebeneinander stehen links **wer und wo**, rechts **wie erreichbar
   und wie abgerechnet**; jeder Block trägt eine Überschrift, damit das Auge springen kann statt
   zu lesen. Unter 760 Pixeln wird wieder eine Spalte daraus – auf dem Telefon ist Rollen das
   kleinere Übel als zwei zusammengedrückte Spalten. */
.maske {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 0 28px;
}

.maske__spalte { min-width: 0; }

.maske__block + .maske__block { margin-top: 2px; }

.maske__titel {
    margin: 0 0 8px;
    padding-bottom: 5px;
    border-bottom: 1px solid var(--rand-zart);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-gedaempft);
}

/* Dichter als eine gewöhnliche Maske: Die Überschriften gliedern schon, der Abstand muss es
   nicht auch noch tun. Gemessen an der Messbühne ergab das die Pixel, die auf einem Laptop
   (1366 × 768, sichtbar rund 650) zwischen „passt" und „rollt" lagen. */
.maske .feld-gruppe { margin-bottom: 8px; }
.maske .feld-gruppe label { margin-bottom: 4px; }

.maske__hinweis {
    margin: -4px 0 10px;
    font-size: 12px;
    color: var(--text-schwach);
    line-height: 1.4;
}

/* Feste Raster statt `auto-fit`: In einer Spalte von gut vierhundert Pixeln bräche die
   Namenszeile (Anrede, Vorname, Nachname) sonst in zwei Zeilen, und PLZ und Ort bekämen gleich
   viel Platz – die PLZ hat fünf Zeichen, der Ort oft zwanzig. */
.feld-reihe--zwei { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.feld-reihe--drei { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.feld-reihe--name { grid-template-columns: 96px minmax(0, 1fr) minmax(0, 1fr); }
.feld-reihe--plz { grid-template-columns: 104px minmax(0, 1fr); }
.feld-reihe--schmal-breit { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }

/* Was man selten braucht, klappt auf – und ist offen, sobald etwas darin steht. */
.maske__klappe {
    margin-top: 4px;
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius);
    padding: 0 12px;
}

.maske__klappe > summary {
    padding: 9px 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
}

.maske__klappe[open] > summary { margin-bottom: 4px; }

/* Die Reiter im Dialog sitzen dichter als auf einer Seite: Der Platz über den Feldern ist der,
   der am Ende das Rollen kostet. */
.dialog .reiter { margin-bottom: 14px; }

.reiter__marke {
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    color: var(--gruen);
    background: color-mix(in srgb, var(--gruen) 12%, transparent);
}

@media (max-width: 760px) {
    .maske { grid-template-columns: minmax(0, 1fr); }
}

/* Auf einem niedrigen Fenster kostet der Rand um den Dialog mehr, als er nützt: 48 Pixel
   oben und unten sind auf einem Laptop fast ein Sechstel der Höhe. */
@media (max-height: 820px) {
    .dialog-huelle { padding-top: 16px; padding-bottom: 16px; }
}

@media (max-width: 480px) {
    .feld-reihe--drei,
    .feld-reihe--schmal-breit { grid-template-columns: minmax(0, 1fr); }
}

.schliessen {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-schwach);
    font-size: 18px;
    line-height: 1;
    padding: 4px;
}

.schliessen:hover { color: var(--text); }

/* ---------- Anmeldung ----------
   Die Anmeldung ist der erste Bildschirm der Anwendung und sah lange aus wie ein fremder:
   eigene Kartenmaße, eigene Radien, ein eigener Spruchblock. Sie benutzt jetzt dieselben
   Bausteine wie alles dahinter – `.karte`, `.feld-gruppe`, `.knopf` – und hier stehen nur
   noch die beiden Dinge, die es woanders nicht gibt: die Aufteilung in zwei Hälften und die
   Marke auf hellem Grund.

   Alle Farben und Maße kommen aus den Variablen in :root. Ein hart geschriebenes #fff oder
   ein eigener Radius ist genau die Abweichung, die man einzeln nicht sieht und in der Summe
   als „irgendwie anders" wahrnimmt. */
.anmeldung {
    display: flex;
    min-height: 100vh;
    background: var(--flaeche-blass);
}

.anmeldung__links {
    flex: 1 1 58%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 40px 24px;
}

.anmeldung__rechts {
    flex: 1 1 42%;
    background: linear-gradient(150deg, var(--navy) 0%, var(--navy-tief) 100%);
    color: var(--text-invers);
    display: flex;
    align-items: center;
    padding: 48px;
}

.anmeldung__buehne { max-width: 380px; }

.anmeldung__spruch {
    font-size: 30px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -.4px;
}

.anmeldung__strich {
    height: 5px;
    width: 72px;
    background: var(--akzent);
    border-radius: 3px;
    margin: 18px 0;
}

.anmeldung__text {
    font-size: 14px;
    line-height: 1.65;
    color: var(--nav-text);
}

/* Die Aufzählung nennt, was in der Anwendung steckt – ohne Häkchengrafik: Ein Haken
   behauptet eine Zusage, hier steht schlicht ein Inhaltsverzeichnis. */
.anmeldung__liste {
    list-style: none;
    margin: 22px 0 0;
    padding: 0;
    font-size: 13.5px;
    color: var(--nav-text);
}

.anmeldung__liste li {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 5px 0;
}

.anmeldung__liste li::before {
    content: "";
    flex: 0 0 5px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--akzent);
}

.anmeldung__kasten { width: 100%; max-width: 340px; }

/* Die Marke steht waagerecht wie in der Seitenleiste – derselbe Betrieb, dieselbe Anordnung.
   Senkrecht gestapelt war sie ein zweites Erscheinungsbild für dasselbe Zeichen. */
.anmeldung__marke {
    display: flex;
    align-items: center;
    gap: 11px;
    margin-bottom: 20px;
}

/* Die Wortmarke der Seitenleiste in größer und dunkel auf hellem Grund – wie das Logo auf der
   Website. Das X ist dasselbe Element wie in der Leiste (`nav__zeichen`); seine Schnitte stehen in
   Prozent und wachsen mit, hier wird nur die Größe gesetzt. (Vorher stand hier das alte
   Hauszeichen, ein oranges Plättchen mit dunklem Block.) */
.anmeldung__name {
    display: inline-flex;
    align-items: center;
    gap: 1px;
}

.anmeldung__zeichen {
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
}

.anmeldung__wort {
    font-size: 24px;
    font-weight: 700;
    color: var(--text-stark);
    letter-spacing: -.6px;
}

.anmeldung__einleitung {
    font-size: 13px;
    color: var(--text-schwach);
    margin: -8px 0 16px;
}

/* Die Demo-Zugänge stehen bewusst auffällig da und nicht als beiläufige Fußnote: Auf einem
   Anmeldebildschirm Kennwörter abzudrucken ist eine Entwicklungshilfe, und man soll sofort
   sehen, dass diese Anwendung noch nicht scharf geschaltet ist. */
.anmeldung__hinweis {
    margin-top: 18px;
    padding: 12px 14px;
    background: var(--gelb-blass);
    border: 1px solid color-mix(in srgb, var(--gelb-dunkel) 30%, transparent);
    border-radius: var(--radius);
    font-size: 12px;
    color: var(--gelb-dunkel);
    line-height: 1.6;
}

.anmeldung__hinweis strong { color: var(--gelb-dunkel); }

/* Der Weg zwischen Anmelden und Registrieren. Er steht unter dem Knopf, durch eine Linie
   abgesetzt: Anmelden ist der tägliche Fall, der Wechsel der seltene – er soll zu finden
   sein, ohne mit dem Knopf um Aufmerksamkeit zu ringen. */
.anmeldung__wechsel {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--rand);
    text-align: center;
    font-size: 13px;
    color: var(--text-schwach);
}

.anmeldung__wechsel a {
    color: var(--primaer);
    font-weight: 600;
    text-decoration: none;
}

.anmeldung__wechsel a:hover { text-decoration: underline; }

/* Der Satz unter einem Feld, der eine Folge erklärt („lässt sich nicht tauschen"). Kleiner
   als das Feld und ruhiger als eine Warnung – es ist ein Hinweis, kein Befund. */
.anmeldung__feldhinweis {
    margin-top: 4px;
    font-size: 12px;
    color: var(--text-schwach);
    line-height: 1.5;
}

.anmeldung__erfolg {
    margin: 0 0 16px;
    padding: 12px 14px;
    background: var(--gruen-blass);
    border: 1px solid var(--gruen);
    border-radius: var(--radius);
    font-size: 13px;
    line-height: 1.6;
}

/* Eigene Zeile: Inline gesetzt lief die Überschrift in den Satz hinein und las sich wie
   dessen erstes Wort. */
.anmeldung__marker {
    display: block;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    margin-bottom: 4px;
}

.fehler-band {
    background: var(--rot-blass);
    color: var(--rot-dunkel);
    border-radius: var(--radius);
    padding: 9px 12px;
    font-size: 13px;
    margin-bottom: 12px;
}

.erfolg-band {
    background: var(--gruen-blass);
    color: var(--gruen-dunkel);
    border-radius: var(--radius);
    padding: 9px 12px;
    font-size: 13px;
    margin-bottom: 12px;
}

/* Ein neutraler Hinweis – weder Fehler noch Erfolg, etwa „Zusatz ist aus“. */
.hinweis-band {
    background: var(--flaeche-grau);
    color: var(--text);
    border-radius: var(--radius);
    padding: 9px 12px;
    font-size: 13px;
    margin-bottom: 12px;
}

/* ---------- Dokumentenkacheln ---------- */
.kacheln {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 16px;
}

.kachel {
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--flaeche);
    box-shadow: var(--schatten);
    display: flex;
    flex-direction: column;
}

.kachel__bild {
    height: 130px;
    background: var(--flaeche-grau);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    overflow: hidden;
}

.kachel__bild img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.kachel__bild svg { color: var(--text-schwach); }

.kachel__koerper {
    padding: 10px 12px;
    flex: 1 1 auto;
    min-width: 0;
}

.kachel__name {
    font-weight: 500;
    color: var(--text-stark);
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kachel__daten {
    font-size: 12px;
    color: var(--text-schwach);
    margin-top: 2px;
}

.kachel__fuss {
    display: flex;
    /* Umbrechen statt abschneiden: Die Kachel ist schmal und trägt `overflow: hidden` – ohne
       diese Zeile verschwindet der dritte Knopf hinter der Kante, ohne dass es auffällt. Wer
       ihn sucht, findet ihn nie, denn abgeschnitten sieht aus wie nicht vorhanden. */
    flex-wrap: wrap;
    gap: 2px;
    padding: 6px 8px;
    border-top: 1px solid var(--rand);
}

/* ---------- Kacheln mit einer Fensterzeichnung ----------
   Eine technische Zeichnung braucht mehr Platz als ein Vorschaubild: Die Kachel wird breiter
   und ihr Bildfeld höher. Und die Zeichnung nimmt die Höhe des Feldes an, statt ihre eigene
   mitzubringen – sonst ragt sie aus der Kachel heraus und wird oben und unten abgeschnitten. */

.kacheln--zeichnung {
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.kachel__bild--zeichnung {
    height: 210px;
    background: var(--flaeche);
    padding: 6px;
}

.kachel__bild--zeichnung .fensterbild-huelle {
    height: 100%;
    width: 100%;
    padding: 0;
}

/* Vorschaufeld für das Firmenlogo */
.logo-feld {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 240px;
    height: 110px;
    padding: 10px;
    border: 1px dashed var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche-blass);
}

.logo-feld img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

@media (max-width: 900px) {
    .anmeldung__rechts { display: none; }
}

/* ---------- Detailseiten ---------- */
/* Das Kopfband der Detailseiten bleibt stehen – in einem langen Beleg will man jederzeit
   sehen, um welchen es geht, und die Knöpfe im Griff behalten. Der leichte Schatten setzt es
   von der Fläche darunter ab, sobald gescrollt wird. */
.detail-kopf {
    display: flex;

    /* Die Leiste bricht um, statt über den Rand zu laufen – dieselbe Falle wie am `.seiten-kopf`.
       Am Angebot stehen bis zu zwölf Knöpfe; gemessen liefen sie bei 1564 Pixeln Fensterbreite
       348 Pixel hinaus, und „In Rechnung stellen“ war nur über die Bildlaufleiste zu erreichen. */
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    padding: 14px 28px;
    border-bottom: 1px solid var(--rand-zart);
    position: sticky;

    /* Unter dem Kopfbereich und nicht bei null: Dort klebt schon die Suchleiste, und sie liegt
       darüber – der Kopf des Belegs samt seinen Knöpfen verschwand dahinter, sobald gescrollt
       wurde. Die Höhe misst `handwerkKopf.beobachten` (index.html) laufend, weil sie mit dem
       groben Zeiger und mit jeder Meldung im Kopfbereich wächst. Ohne Messung gilt null. */
    top: var(--kopfbereich-hoehe, 0px);

    /* Leicht durchscheinend, damit man sieht, dass darunter weitergeht – aber aus der
       Arbeitsfläche und nicht aus festem Weiß. Als `rgba(255,255,255,.92)` blieb die Leiste im
       Dunkeln weiß, und ausgerechnet sie: Sie klebt oben und trägt die Knöpfe des Belegs. */
    background: color-mix(in srgb, var(--flaeche) 92%, transparent);
    backdrop-filter: saturate(1.6) blur(8px);
    box-shadow: var(--schatten);
    z-index: 20;
}

.detail-kopf h2 {
    font-size: 17px;
    flex: 0 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.zurueck {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-schwach);
    padding: 6px;
    display: flex;
    border-radius: var(--radius-klein);
    transition: background .12s ease, color .12s ease;
}

.zurueck:hover { color: var(--text-stark); background: var(--flaeche-grau); }

.detail-raster {
    display: grid;
    grid-template-columns: 340px minmax(0, 1fr);
    gap: 28px;
    padding: 24px 28px 44px;
    align-items: start;
}

@media (max-width: 1100px) {
    .detail-raster { grid-template-columns: minmax(0, 1fr); }
}

.merkmal { margin-bottom: 18px; }

.merkmal__name {
    font-weight: 500;
    font-size: 11.5px;
    letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--text-schwach);
    margin-bottom: 3px;
}

.merkmal__wert { color: var(--text); }

.merkmal-paar {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
}

.zeile-mit-symbol {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin-bottom: 8px;
    color: var(--text);
}

.zeile-mit-symbol svg { flex: 0 0 16px; margin-top: 2px; color: var(--text-schwach); }

/* Die fehlenden Kontaktangaben einer Akte: leiser als eine gefüllte Angabe, denn sie ist ein
   Angebot und keine Auskunft. Die Farbe ist die jedes Verweises (`a`) und nicht
   `--primaer-dunkel` – die ist im Dunkeln eine Fläche und keine Schrift. */
.kontaktluecken { font-size: 13px; }

/* Die Mailadresse, die den eigenen Schreibdialog öffnet: ein Knopf, der aussieht wie der Verweis,
   den er ersetzt – dieselbe Farbe wie `a`, dieselbe Schrift wie die Zeile. Ein Knopf erbt beides
   nicht vom Körper; ohne `color` und `font` stünde die Adresse schwarz und in Arial da. */
.mailverweis {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--primaer);
    cursor: pointer;
    text-align: left;
    overflow-wrap: anywhere;
    text-underline-offset: 2px;
}

.mailverweis:hover { text-decoration: underline; }
.kontaktluecken__trenner { margin: 0 6px; color: var(--text-schwach); }

.abschnitt { margin-bottom: 28px; }

.abschnitt__kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}

.abschnitt__kopf h2 { font-size: 16px; }

/* Auf der getönten Arbeitsfläche braucht jede Liste ihre eigene weiße Fläche, sonst
   schwebt sie ohne Grund. Tabellen und Leerhinweise bekommen sie hier, ohne dass jede
   Detailseite eine Hülle ins Markup schreiben muss. */
.abschnitt > table.tabelle,
.abschnitt > .leer-hinweis {
    background: var(--flaeche);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten);
    overflow: hidden;
}

.abschnitt > table.tabelle th:first-child { border-top-left-radius: var(--radius-gross); }
.abschnitt > table.tabelle th:last-child { border-top-right-radius: var(--radius-gross); }
.abschnitt > .leer-hinweis { border-style: solid; }

.beleg {
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    padding: 34px 38px;
    box-shadow: var(--schatten);
}

/* ---------- Das Blatt in der Detailansicht (`Blattablage`) ----------
   Ein A4-Bogen auf einer Unterlage, wie ein PDF im Betrachter: 210 zu 297, höchstens 794 Pixel
   breit (A4 bei 96 dpi), die Ränder im Verhältnis der Seitenränder des PDFs (oben 2, links 2,5,
   rechts 2, unten 1,5 cm). Die `cqi` der Unterlage beziehen sich auf die Hülle der Belegansicht
   und schrumpfen mit ihr; `min()` deckelt sie bei voller Breite auf die Maße des Papiers. Ist der
   Inhalt länger als eine Seite, wächst der Bogen mit – geteilt in Seiten wird erst im PDF. */
.blattablage {
    padding: clamp(8px, 3cqi, 32px) clamp(8px, 2.5cqi, 28px) clamp(14px, 4cqi, 40px);
    background: var(--flaeche-grau);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-gross);
}

.blattablage__blatt {
    display: flex;
    flex-direction: column;
    max-width: 794px;
    aspect-ratio: 210 / 297;
    margin: 0 auto;
    padding: min(8.5cqi, 76px) min(8.5cqi, 76px) min(6.5cqi, 57px) min(10.5cqi, 94px);
    background: var(--flaeche);
    color: var(--text);
    border-radius: 2px;
    /* Dezent: ein Haarstrich Schatten für die Kante und ein weicher darunter, der das Blatt
       von der Unterlage hebt. Kein Rand – Papier hat keinen. */
    box-shadow: 0 1px 2px rgba(16, 24, 40, .08), 0 14px 34px -10px rgba(16, 24, 40, .22);
}

/* Im Dunkeln trägt ein dunkler Schatten auf dunkler Unterlage nichts; die Kante macht dort ein
   heller Hauch, die Tiefe ein kräftigerer Schatten. */
:root[data-thema="dunkel"] .blattablage__blatt {
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .06), 0 16px 38px -8px rgba(0, 0, 0, .65);
}

/* Der Bogen ist das Papier – die Karte darin verliert Rahmen, Schatten und Innenabstand, und ihr
   Inhalt nimmt den Platz bis zum Fuß ein, damit der Fuß unten steht wie auf dem Blatt. */
.blattablage__blatt > .beleg {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    color: inherit;
}

.blattablage__blatt .beleg__inhalt { flex: 1 1 auto; }

/* Anschrift und Kennfeld nebeneinander, wie auf dem Papier: Mit den Seitenrändern ist die
   Textbreite schmaler als in der Karte, und der Umbruch der Karte legte das Kennfeld unter die
   Anschrift – ein Aufbau, den das gedruckte Blatt nie hat. Erst auf dem Telefon (unten) bricht
   es wieder um. */
.blattablage__blatt .beleg__kopf { flex-wrap: nowrap; }
.blattablage__blatt .beleg__rechts { flex: 0 1 260px; min-width: 0; }

/* Auf dem Telefon wäre ein Bogen im Seitenverhältnis eine lange leere Fläche unter wenig Text,
   und die Ränder des Papiers fräßen die halbe Breite. */
@container (max-width: 640px) {
    .blattablage__blatt {
        aspect-ratio: auto;
        padding: 22px 18px;
    }

    .blattablage__blatt .beleg__kopf { flex-wrap: wrap; }
    .blattablage__blatt .beleg__rechts { min-width: min(240px, 100%); }
}

/* Der Kopf wie auf dem gedruckten Blatt (`Briefkopf`): oben Luft, links das Anschriftfeld, rechts
   Logo und darunter das Kennfeld. */
.beleg__logozone {
    min-height: 56px;
    margin-bottom: 12px;
}

.beleg__logozone--mitte { text-align: center; }

.beleg__kopf {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 24px;
    margin: 28px 0 34px;
}

/* Das Anschriftfeld hat eine Breite und richtet sich nicht nach seinem längsten Text – dieselbe
   Aussage wie auf dem gedruckten Blatt, wo es die 85 mm der DIN 5008 sind (`Briefkopf`). Der
   Anteil ist derselbe wie dort – 8,5 von 16,8 cm Textbreite. */
.beleg__anschriftfeld {
    flex: 1 1 50%;
    min-width: 0;
}

/* Klein und ohne Linie, wie auf dem Blatt: Die kleine Schrift trennt schon. Die Linie darunter
   war auf dem Papier „viel zu lang" und ist dort weg – hier also auch. */
.beleg__absender {
    font-size: 10px;
    color: var(--text);
    margin-bottom: 8px;
}

.beleg__anschrift {
    font-size: 14px;
    line-height: 1.55;
    color: var(--text-stark);
}

/* `min()` und nicht 240 fest: Auf dem Telefon ist der Beleg schmaler als 240 Pixel, und der
   Block schob die Seite sonst seitlich über – umbrechen soll er, nicht hinausragen. */
.beleg__rechts {
    flex: 0 1 300px;
    min-width: min(240px, 100%);
    display: flex;
    flex-direction: column;
}

.beleg__logo {
    text-align: right;
    min-height: 56px;
    margin-bottom: 22px;
}

.beleg__logobild {
    max-height: 64px;
    max-width: 100%;
    object-fit: contain;
}

/* Die Stufen im Verhältnis des Blattes (1,1 / 1,8 / 2,5 / 3,5 cm, `Briefkopf.Logohoehe`); breiter
   als die Spalte wird es nicht, wie auf dem Blatt nicht breiter als das Kennfeld. */
.beleg__logobild--klein { max-height: 39px; }
.beleg__logobild--gross { max-height: 89px; }
.beleg__logobild--sehrgross { max-height: 124px; }

/* In der Kopfzone hat das Blatt eine feste Höhe (`Briefkopf.LogohoeheKopfzone`, 2,6 cm). */
.beleg__logozone .beleg__logobild--sehrgross { max-height: 92px; }

.beleg__logoname {
    font-size: 20px;
    font-weight: 700;
    color: var(--text-stark);
}

.beleg__meta { font-size: 13px; }

.beleg__meta div {
    display: flex;
    gap: 12px;
    justify-content: space-between;
}

.beleg__meta span:first-child { color: var(--text); }
.beleg__meta span:last-child { color: var(--text-stark); text-align: right; }

.beleg__titel {
    font-size: 21px;
    font-weight: 700;
    color: var(--text-stark);
    margin: 0 0 10px;
}

.beleg__bezug {
    font-size: 13px;
    line-height: 1.5;
    margin-bottom: 16px;
}

.beleg__einleitung { margin: 0 0 16px; }

.beleg__schluss { margin-top: 20px; }

/* Der Brief zwischen Kopf und Fuß – Maße nach `BriefPdfDienst`: Betreff 12 Punkt fett mit
   Abstand zum Kennfeld, die Absätze wie getippt, zwischen Gruß und Name Platz für die
   Unterschrift von Hand. */
.brief__betreff {
    font-size: 16px;
    font-weight: 700;
    color: var(--text-stark);
    margin: 40px 0 20px;
}

.brief__anschriftzeile { white-space: pre-line; }

.brief__anrede { margin: 0 0 12px; }

.brief__text {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    line-height: 1.55;
}

.brief__gruss { margin: 24px 0 0; }

.brief__unterzeichner {
    margin: 52px 0 8px;
    color: var(--text-stark);
}

/* Der Fuß in drei Spalten, wie auf dem Blatt: wer, wie erreichbar, wohin überweisen. */
.beleg__fuss {
    display: grid;
    grid-template-columns: 35fr 27fr 38fr;
    gap: 12px;
    margin-top: 40px;
    padding-top: 8px;
    border-top: 1px solid var(--text);
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--text);
}

.beleg__fuss--text { display: block; text-align: center; }

@media (max-width: 640px) {
    .beleg__fuss { grid-template-columns: minmax(0, 1fr); }
}

/* Die Positionen in einem Rahmen mit senkrechten Linien und ohne waagerechte zwischen den
   Positionen – wie auf dem Blatt. Das Auge läuft an den Spalten entlang; waagerecht getrennt wird
   nur, was einen neuen Abschnitt beginnt: Kopf, Summen, Bedingungen. */
.beleg__positionen { overflow-x: auto; }

table.positionen--blatt { border: 1px solid var(--text); }

table.positionen--blatt th,
table.positionen--blatt td {
    border-bottom: none;
    border-left: 1px solid var(--text);
}

table.positionen--blatt th {
    color: var(--text-stark);
    border-top: 1px solid var(--text);
    border-bottom: 1px solid var(--text);
}

table.positionen--blatt th.zelle-mitte { text-align: center; }

/* Menge und Einheit lesen sich als eine Angabe („1,00 Pausch.“) – ohne Linie dazwischen. */
table.positionen--blatt td.positionen__menge-einheit { border-left: none; }
table.positionen--blatt td.positionen__menge-zahl { white-space: nowrap; }

table.positionen--blatt tr.positionen__bauteil td + td { border-left: 1px solid var(--text); }

table.positionen--blatt tr.positionen__abschnitt td { border-top: 1px solid var(--text); }

/* Die Summen im selben Rahmen: die Bezeichnung über alle Spalten bis zur Gesamtspalte. */
table.positionen--blatt tr.positionen__summe td { padding-top: 4px; padding-bottom: 4px; }
table.positionen--blatt tr.positionen__summe--beginn td { border-top: 1px solid var(--text); padding-top: 8px; }

table.positionen--blatt tr.positionen__summe--zwischen td,
table.positionen--blatt tr.positionen__summe--gesamt td {
    font-weight: 700;
    color: var(--text-stark);
    border-top: 1px solid var(--text);
}

table.positionen--blatt tr.positionen__summe--gesamt td {
    font-size: 14px;
    border-bottom: 3px solid var(--text);
    padding-top: 7px;
    padding-bottom: 7px;
}

table.positionen--blatt tr.positionen__bedingungen td {
    border-top: 1px solid var(--text);
    font-size: 12.5px;
    color: var(--text-stark);
    padding: 8px 8px;
}

table.positionen--blatt tr.positionen__bedingungen p { margin: 0; white-space: pre-line; }
table.positionen--blatt tr.positionen__bedingungen p + p { margin-top: 5px; }

/* Das Blatt ohne Linien (`Belegstil.OhneLinien`, `BelegPdfDienst.OhneLinien`): kein Rahmen, keine
   senkrechten Linien, eine graue Linie unter dem Kopf und über den Summen, Luft zwischen den
   Positionen, der Summenblock rechts. Steht hinter den Regeln des gerahmten Blattes, weil beide
   Wähler gleich stark sind. */
table.positionen--blatt.positionen--offen { border: none; }

table.positionen--blatt.positionen--offen th,
table.positionen--blatt.positionen--offen td { border-left: none; }

table.positionen--blatt.positionen--offen th {
    border-top: none;
    border-bottom: 2px solid var(--rand-staerker);
}

table.positionen--blatt.positionen--offen tbody td { padding-top: 9px; }

table.positionen--blatt.positionen--offen tr.positionen__bauteil td + td { border-left: none; }
table.positionen--blatt.positionen--offen tr.positionen__abschnitt td { border-top: 2px solid var(--rand-staerker); }

table.positionen--blatt.positionen--offen tr.positionen__summe td { padding-top: 4px; padding-bottom: 4px; }
table.positionen--blatt.positionen--offen tr.positionen__summe--beginn td { border-top: 2px solid var(--rand-staerker); padding-top: 10px; }

/* Linien im Block nur unter dem Block selbst, nicht über die leeren Spalten links davon. */
table.positionen--blatt.positionen--offen tr.positionen__summe--zwischen:not(.positionen__summe--beginn) td.positionen__summe-leer,
table.positionen--blatt.positionen--offen tr.positionen__summe--gesamt:not(.positionen__summe--beginn) td.positionen__summe-leer {
    border-top: none;
}

table.positionen--blatt.positionen--offen tr.positionen__summe--gesamt td.positionen__summe-leer { border-bottom: none; }

table.positionen--blatt.positionen--offen tr.positionen__bedingungen td { border-top: none; padding-top: 18px; }

table.positionen { width: 100%; border-collapse: collapse; font-size: 13px; }

table.positionen th {
    text-align: left;
    font-weight: 400;
    font-size: 12px;
    color: var(--text-schwach);
    border-bottom: 1px solid var(--rand);
    padding: 8px 6px;
}

table.positionen td {
    padding: 9px 6px;
    border-bottom: 1px solid var(--flaeche-grau);
    vertical-align: top;
}

table.positionen tr.gruppe td {
    background: var(--flaeche-blass);
    font-weight: 500;
    color: var(--text-stark);
}

/* Zeichnung und Maße unter ihrer Position (Bauteilzeile) – wie auf dem Blatt ohne Linie
   dazwischen, sonst läse sich die Zeichnung wie die nächste Position. Die Zeile bringt ihren
   Innenabstand über .fensterliste__zeile selbst mit; hier nur kein zweiter. */
table.positionen tr:has(+ tr.positionen__bauteil) td { border-bottom: none; }
table.positionen tr.positionen__bauteil td { padding-top: 0; }
table.positionen tr.positionen__bauteil .fensterliste__zeile { padding: 4px 0 14px; }

/* Mit Profilsystem: Skizze, Querschnitt, Aufmaß nebeneinander – wie auf dem Blatt. Zwei
   Klassen und nicht eine: Die Grundregel .fensterliste__zeile steht weiter hinten im Stilblatt
   und schlüge eine gleich starke Regel hier, obwohl diese geladen ist. */
.fensterliste__zeile.fensterliste__zeile--profil {
    grid-template-columns: 240px 150px minmax(0, 1fr);
    grid-template-areas: "bild profil text";
    align-items: start;
}

.fensterliste__zeile--profil > .fensterliste__bild { grid-area: bild; }
.fensterliste__zeile--profil > .fensterliste__profil { grid-area: profil; }
.fensterliste__zeile--profil > .fensterliste__text { grid-area: text; }

/* Entschieden wird an der Breite der Zelle und nicht an der des Fensters: Die Belegansicht
   steht neben der Menüleiste und in Dialogen verschieden breit. Unter 700 Pixeln blieben dem
   Aufmaß neben Skizze und Querschnitt keine hundert – dann rückt es darunter. */
/* An der Hülle und nicht an der Zelle: Eine Tabellenzelle kann kein Größencontainer sein. */
.positionen__bauteilhuelle { container-type: inline-size; }

@container (max-width: 700px) {
    .fensterliste__zeile.fensterliste__zeile--profil {
        grid-template-columns: 240px minmax(0, 1fr);
        grid-template-areas: "bild profil" "text text";
    }
}

@container (max-width: 420px) {
    .fensterliste__zeile.fensterliste__zeile--profil {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "bild" "profil" "text";
    }
}

.positionen__beschreibung {
    color: var(--text-schwach);
    font-size: 12px;
    white-space: pre-line;
    margin-top: 2px;
}

/* Ein ausgeblendeter Langtext bleibt lesbar und bearbeitbar – er steht nur nicht auf dem
   Blatt. Blass und gestrichelt sagt das, ohne ihn zu verstecken. */
.positionen__langtext--aus {
    border-style: dashed;
    color: var(--text-gedaempft);
}

/* „alle ausblenden" in der Spaltenüberschrift – klein und klein geschrieben, damit es neben der
   Überschrift steht und nicht wie eine zweite. */
.positionen__alle-langtexte {
    margin-left: 8px;
    font-size: 11px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    text-decoration: underline;
}

/* Die Umsatzsteuer für alle Positionen im Kopf der MwSt-Spalte. Eine eigene Zeile unter dem Wort
   „MwSt“ und nicht daneben: Die Spalte ist so breit wie ihre Auswahlfelder, und dasselbe Feld
   darüber zeigt, dass es für alle darunter gilt. Die Schrift des Kopfes (Großbuchstaben,
   Sperrung) gilt für die Beschriftung und nicht für den Inhalt des Feldes. */
table.positionen select.positionen__steuervorgabe {
    display: block;
    margin-top: 4px;
    height: 28px;
    font-size: 12px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
}

.positionen__steuerhinweis {
    display: block;
    margin-top: 3px;
    font-size: 11px;
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    color: var(--gelb-dunkel);
    text-decoration: underline;
}

.positionen__schalter {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    font-size: 12px;
    color: var(--text-gedaempft);
    cursor: pointer;
}

.positionen__bild {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px;
    margin-top: 6px;
}

.positionen__bild img {
    display: block;
    max-width: 260px;
    max-height: 180px;
    border: 1px solid var(--rand);
    border-radius: var(--radius-klein);
}

/* ---------- Positionseditor nach dem Vorbild von Tooltime ----------
   Zwei Zeilen je Position: oben die Rechnung (Art, Menge, Einheit, Bezeichnung, Einkauf,
   Aufschlag, Marge, Verkauf), darunter Beschreibung, Bild und Positionsart. Die obere Zeile trägt
   deshalb keine Linie – sonst läse sich die Beschreibung wie die nächste Position. */
table.positionen--editor td { vertical-align: middle; }
table.positionen--editor tr.positionen__hauptzeile:has(+ tr.positionen__detail) td { border-bottom: none; padding-bottom: 4px; }
table.positionen--editor tr.positionen__detail td { vertical-align: top; padding-top: 0; }

.positionen__leiste {
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 14px;
    margin-bottom: 6px;
}

.positionen__leiste .positionen__alle-langtexte {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 0;
    font-size: 12px;
    color: var(--primaer);
    text-decoration: none;
}

.positionen__gruppenkopf {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

/* Mit `.knopf-nackt` davor: Die Regel steht weiter hinten im Stilblatt und nähme bei gleicher
   Stärke Farbe und Unterstreichung – der Pfeil stand im Dunkeln bei 1,43 : 1 (gemessen). */
.knopf-nackt.positionen__klappe {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-klein);
    color: var(--text-stark);
}

.knopf-nackt.positionen__klappe:hover { background: var(--flaeche-grau); }

.positionen__gruppennummer {
    font-weight: 600;
    color: var(--text-stark);
    white-space: nowrap;
}

/* Der Titel wie eine Überschrift, nicht wie ein Formularfeld – er ist das, was man in der
   eingeklappten Liste liest. Der Rand erscheint erst beim Darüberfahren. */
table.positionen input.positionen__gruppentitel {
    flex: 1 1 auto;
    min-width: 0;
    height: 32px;
    font-size: 15px;
    font-weight: 500;
    color: var(--text-stark);
    background: transparent;
    border-color: transparent;
}

table.positionen input.positionen__gruppentitel:hover { border-color: var(--rand); }
table.positionen input.positionen__gruppentitel:focus { background: var(--flaeche); border-color: var(--primaer); }

.positionen__gruppenzahl {
    font-size: 12px;
    font-weight: 400;
    color: var(--text-schwach);
    white-space: nowrap;
}

table.positionen td.positionen__gruppensumme {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-stark);
    white-space: nowrap;
}

.positionen__nummer { white-space: nowrap; }

.positionen__art {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-stark);
}

.positionen__art select.feld { height: 32px; padding: 0 22px 0 6px; min-width: 110px; }

.positionen__mengenfeld,
.positionen__prozentfeld {
    display: flex;
    align-items: center;
    gap: 2px;
}

.positionen__prozentfeld span { font-size: 12px; color: var(--text-schwach); }
table.positionen input.positionen__aufschlag { min-width: 58px; }
table.positionen--editor input.feld { height: 32px; }

/* Die Einheit hatte keine Mindestbreite: Die Tabelle drückte sie auf 39 Pixel, davon 26
   Innenabstand – aus „Stk.“ wurde „St“, schon bei 1440 Pixeln (gemessen am Feld). */
table.positionen--editor td.positionen__einheit input.feld { min-width: 64px; padding: 0 6px; }

/* Was gerechnet und nicht getippt wird – Marge und Gesamtpreis –, steht auf blassem Grund wie
   in Tooltime, damit niemand hineinzuklicken versucht. */
table.positionen td.positionen__berechnet {
    background: var(--flaeche-blass);
    white-space: nowrap;
}

/* Bedarfs- und Alternativpositionen: blass, damit ihr Betrag nicht als Teil der Summe gelesen
   wird. Das Wort dazu steht in der Auswahl der Positionsart. */
table.positionen tr.positionen__zeile--eventual td.positionen__berechnet { color: var(--text-schwach); font-weight: 400; }
table.positionen tr.positionen__detail--eventual select.positionen__positionsart { border-color: var(--gelb-dunkel); color: var(--gelb-dunkel); }

table.positionen textarea.positionen__langtext {
    width: 100%;
    min-height: 56px;
    font-size: 12px;
    resize: vertical;
}

.positionen__verweise,
.positionen__hinweise {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
    margin-top: 4px;
    font-size: 12px;
}

/* „Zum Katalog hinzufügen“ – mit `.knopf-nackt` davor aus demselben Grund wie die Klappe: Ohne
   stand der Verweis im Dunkeln bei 1,29 : 1, gemeldet aus dem Betrieb. */
.knopf-nackt.positionen__verweis {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    font-weight: 500;
    color: var(--primaer);
}

.positionen__bildknopf {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 56px;
    border: 1px dashed var(--rand-stark);
    border-radius: var(--radius-klein);
    color: var(--text-schwach);
    cursor: pointer;
}

.positionen__bildknopf:hover { border-color: var(--primaer); color: var(--primaer); }

table.positionen select.positionen__positionsart {
    width: auto;
    min-width: 170px;
    height: 32px;
}

table.positionen tr.positionen__menuezeile td {
    padding-top: 0;
    background: var(--flaeche-blass);
}

.positionen__menue {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    padding: 6px 0;
}

.positionen__menue .knopf { display: inline-flex; align-items: center; gap: 6px; }
.positionen__menue .positionen__entfernen { color: var(--rot); }

table.positionen tr.positionen__gruppenfuss td { padding: 4px 6px 12px; }

.positionen__knopfleiste {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 12px;
}

.positionen__kennwort { font-style: italic; color: var(--text-stark); }

/* Das Bild in der Vorschau – so breit wie auf dem Blatt, also über die Zeile. */
.positionen__vorschaubild {
    display: block;
    max-width: min(100%, 460px);
    max-height: 340px;
    margin-top: 6px;
    border-radius: var(--radius-klein);
}

.fehlertext {
    font-size: 12px;
    color: var(--rot-dunkel);
}

/* ---------- Positionen verschieben ---------- */
/* Gezogen wird nur am Griff: läge draggable auf der ganzen Zeile, könnte in den
   Eingabefeldern kein Text mehr markiert werden. */
.griff {
    display: inline-flex;
    align-items: center;
    padding: 2px;
    color: var(--text-schwach);
    cursor: grab;
}

.griff:active {
    cursor: grabbing;
}

.zeile--zieht {
    opacity: .55;
}

/* Breiter als früher (300 px): Die Zeilen tragen jetzt ihre Bedingung („abzüglich 2 % Skonto bei
   Zahlung bis 08.10.2026"), und die bricht lieber in eine zweite Zeile um, als den Betrag
   wegzuschieben. Der Betrag bricht nie. */
.summenblock {
    margin-left: auto;
    width: min(420px, 100%);
    margin-top: 18px;
}

.summenblock div {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
    padding: 6px 0;
    font-size: 14px;
}

.summenblock div > span:last-child {
    white-space: nowrap;
}

.summenblock div.gesamt {
    border-top: 1px solid var(--rand);
    margin-top: 6px;
    padding-top: 10px;
    font-weight: 500;
    font-size: 16px;
    color: var(--text-stark);
}

.summenblock div.summenblock__zwischen {
    font-weight: 500;
    color: var(--text-stark);
}

/* Bezeichnung, Wert und Art in einer Zeile; die Bezeichnung nimmt, was übrig bleibt. */
.summenblock div.summenblock__rabatt {
    align-items: center;
    gap: 6px;
    padding-bottom: 10px;
}

.summenblock__rabatt .summenblock__rabattname {
    flex: 1 1 auto;
    min-width: 0;
}

.summenblock__rabatt .summenblock__rabattwert {
    flex: 0 0 96px;
    width: 96px;
    text-align: right;
}

.summenblock__rabatt .summenblock__rabattart {
    flex: 0 0 64px;
    width: 64px;
}

/* Die Verweise „Rabatt hinzufügen“ und „Margen anpassen“ – links, wie ein Satz und nicht wie ein
   Betrag. */
.summenblock div.summenblock__verweise {
    justify-content: flex-start;
    padding: 4px 0;
}

.summenblock__verweise .knopf-nackt {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--primaer);
}

/* Kosten und Marge stehen nur in der Maske – als eigene Karte abgesetzt (Vorbild Tooltime),
   damit niemand sie für eine Zeile des Blattes hält. Eine `section` und kein `div`: Die Regel
   `.summenblock div` legt jede Zeile als Flexreihe an, die Karte selbst ist keine. */
.summenblock__kostenkarte {
    margin-top: 12px;
    padding: 6px 14px 10px;
    border-radius: var(--radius);
    background: var(--flaeche-blass);
}

/* Die Nettosumme beim Bearbeiten ist zugleich der Griff für Kosten und Marge (Vorbild Tooltime,
   „Nettosumme ▾“). Sie sieht aus wie jede Zeile des Blocks – ein Knopf ohne eigenen Grund und
   Rand, mit Schrift und Farbe der Zeile, denn ein `<button>` erbt beides nicht. */
.summenblock__netto {
    display: flex;
    width: 100%;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
    padding: 6px 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    cursor: pointer;
    text-align: left;
}

.summenblock__netto > span:first-child {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.summenblock__netto > span:last-child { white-space: nowrap; }

.summenblock div.summenblock__intern-wort {
    display: block;
    padding: 4px 0 0;
    font-size: 11px;
    color: var(--text-schwach);
}

.summenblock div.summenblock__kostensumme {
    padding: 6px 0 3px;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-stark);
}

.summenblock div.summenblock__kostenzeile {
    padding: 2px 0;
    font-size: 12px;
    color: var(--text-schwach);
}

/* ---------- Blazor-Fehlerband ---------- */
#blazor-error-ui {
    background: #fff3cd;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, .2);
    display: none;
    left: 0;
    padding: 10px 14px;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 12px;
    top: 8px;
}

/* ---------- Ablehnungsleiste: der Satz des Servers zu einem abgelehnten Schreibvorgang ----------
   Unten fest und über dem Inhalt, weil gespeichert wird, wo man gerade steht – oft weit unten.
   Farben aus den Token des Fehlerbands, damit sie im Dunkeln mitgehen. */
.ablehnungsleiste {
    position: fixed;
    left: 50%;
    bottom: 20px;
    transform: translateX(-50%);
    z-index: 900;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    width: min(640px, calc(100vw - 32px));
    padding: 12px 14px 12px 16px;
    background: var(--rot-blass);
    color: var(--rot-dunkel);
    border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
    border-radius: var(--radius);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .18);
    font-size: 14px;
    line-height: 1.4;
}

.ablehnungsleiste__text {
    flex: 1 1 auto;
    min-width: 0;
}

.ablehnungsleiste__schliessen {
    flex: 0 0 auto;
    background: none;
    border: none;
    color: inherit;
    font: inherit;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    padding: 0 2px;
}

/* ---------- Anliegen: was auf der Tagesübersicht liegen geblieben ist ---------- */
.anliegen {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 18px 12px 14px;
    border: 1px solid var(--rand);
    border-left-width: 3px;
    border-radius: var(--radius);
    background: var(--flaeche);
    text-decoration: none;
    color: inherit;
    transition: border-color .12s, box-shadow .12s;
}

.anliegen:hover {
    border-color: var(--primaer);
    box-shadow: 0 1px 4px rgba(16, 47, 75, .08);
}

.anliegen__zahl {
    font-size: 21px;
    font-weight: 500;
    color: var(--text-stark);
    line-height: 1;
    min-width: 26px;
    text-align: center;
}

.anliegen__titel {
    display: block;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-stark);
}

.anliegen__zusatz {
    display: block;
    font-size: 12px;
    color: var(--text-schwach);
}

.anliegen--rot { border-left-color: var(--rot); }
.anliegen--gelb { border-left-color: var(--gelb); }
.anliegen--blau { border-left-color: var(--primaer); }
.anliegen--gruen { border-left-color: var(--gruen); }
.anliegen--grau { border-left-color: var(--slate); }

/* Die Kästen standen in einem `flex-wrap` und waren damit verschieden breit – eine Reihe, in der
   nichts untereinander steht. Als Raster sind sie gleich breit, und die Zahl bekommt eine
   getönte Scheibe: Sie ist der Grund, warum der Kasten da ist. */
/* **225 und nicht 236, und die elf Pixel sind gemessen.** Neben der Seitenspalte bleiben der
   Arbeitsfläche 960 Pixel; vier Kästen zu 236 plus drei Abstände sind 980 – einer zu viel, und
   das Band stand zweizeilig. Das kostete 88 Pixel, und zwar über allem, was darunter kommt.
   Mit 225 gehen 936 auf, und der vierte Kasten rückt hinauf.

   Eng wird darin nichts: Die Scheibe nimmt 40, der Abstand 12, für „Überfällige Rechnungen"
   bleiben 173 – gebraucht werden rund 105. */
.anliegen-band {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(225px, 1fr));
    gap: 12px;
    margin-bottom: 22px;
}

.anliegen-band .anliegen__zahl {
    width: 40px;
    height: 40px;
    min-width: 40px;
    border-radius: 13px;
    display: grid;
    place-items: center;
    font-size: 17px;
    font-weight: 600;
    background: var(--flaeche-grau);
}

.anliegen--rot   .anliegen__zahl { background: var(--rot-blass);     color: var(--rot-dunkel); }
.anliegen--gelb  .anliegen__zahl { background: var(--gelb-blass);    color: var(--gelb-dunkel); }
.anliegen--gruen .anliegen__zahl { background: var(--gruen-blass);   color: var(--gruen-dunkel); }
.anliegen--blau  .anliegen__zahl { background: var(--primaer-blass); color: var(--primaer-dunkel); }

/* ---------- Feinheiten für alles ---------- */

/* Ein sichtbarer Fokusring an allem Bedienbaren – und zwar nur, wenn mit der Tastatur
   navigiert wird. Wer mit der Maus klickt, soll keinen Rahmen sehen; wer sich durch die Maske
   tabbt, muss jederzeit erkennen, wo er steht. */
a:focus-visible,
button:focus-visible,
.knopf:focus-visible,
.reiter__punkt:focus-visible,
.nav__punkt:focus-visible,
.nav__unterpunkt:focus-visible,
[tabindex]:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--primaer);
    outline-offset: 2px;
    border-radius: var(--radius-klein);
}

/* In der dunklen Seitenleiste braucht der Ring die helle Farbe, sonst verschwindet er. */
.nav__punkt:focus-visible,
.nav__unterpunkt:focus-visible {
    outline-color: #fff;
}

/* Schlanke, unauffällige Scrollleisten. Die breiten grauen Balken von Windows sind das
   Erste, was eine Oberfläche alt aussehen lässt. */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--rand-stark) transparent;
}

*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }

*::-webkit-scrollbar-thumb {
    background: var(--rand-stark);
    border-radius: 9999px;
    border: 2px solid transparent;
    background-clip: content-box;
}

*::-webkit-scrollbar-thumb:hover { background: #AEB9C6; background-clip: content-box; }

/* Markierter Text in der Hausfarbe. */
::selection { background: rgba(13, 135, 242, .18); color: var(--text-stark); }

/* Wer Bewegung abgestellt hat, bekommt keine. Das ist keine Feinheit, sondern eine
   Einstellung des Betriebssystems, und sie gilt für manche Menschen aus gutem Grund. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}

/* Beim Drucken bleibt nur der Inhalt: Seitenleiste, Suchleiste und Knöpfe gehören nicht
   aufs Papier. Gedruckt wird aus dem Browser selten – aber wenn, dann richtig. */
@media print {
    .nav,
    .kopfband,
    .seiten-kopf__werkzeuge,
    .knopf {
        display: none !important;
    }

    .huelle { display: block; }
    .karte, .kennzahl { box-shadow: none; border-color: #ccc; }
    body { background: #fff; }
}

/* ============================================================
   Assistent
   Ein Faden, mehrere Wege: die Blase trägt ihren Kanal als Abzeichen im Fuß. Damit bleibt
   sichtbar, wo etwas gesagt wurde, ohne dass das Gespräch in Reiter zerfällt.
   ============================================================ */

.seiten-kopf__unter {
    margin: 4px 0 0;
    color: var(--text-schwach);
    font-size: 13px;
}

.assistent {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 16px;
    align-items: start;
}

@media (max-width: 1100px) {
    .assistent { grid-template-columns: minmax(0, 1fr); }
}

.assistent__spalte {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.assistent__faden {
    display: flex;
    flex-direction: column;
    min-height: 60vh;
}

.hinweistext {
    margin: 0 0 10px;
    color: var(--text-schwach);
    font-size: 12px;
    line-height: 1.5;
}

/* ============================================================
   Karte
   Leaflet bringt eigene Maße mit; hier steht nur, wie sich die Fläche in die Karten der
   Anwendung einfügt – gerundete Ecken, ein zarter Rahmen, dieselbe Schrift.
   ============================================================ */

.karte-flaeche {
    width: 100%;
    border-radius: var(--radius);
    z-index: 0;
}

.karte-flaeche .leaflet-container {
    font: inherit;
    border-radius: var(--radius);
}

/* Die beschriftete Nadel der Terminkarte.

   Die Hülle ist absichtlich ohne Ausdehnung: Sind zwei Monteure auf einem Termin, steht das
   zweite Kürzel daneben und die Nadel wird breiter – eine feste Größe könnte Leaflet dann
   nicht mehr richtig ausrichten. Die Nadel selbst hängt über dem Punkt und läuft nach unten
   in eine Spitze aus, damit sie auf die Stelle zeigt statt daneben zu schweben. */
.kartennadel-huelle {
    width: 0 !important;
    height: 0 !important;
}

.kartennadel {
    position: absolute;
    bottom: 7px;
    left: 0;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 28px;
    padding: 0 9px;
    border-radius: 14px;
    /* Weißer Rand und Schatten heben das Kürzel von den Kacheln ab – ohne sie verschwindet
       eine dunkle Farbe auf einer dunklen Straße. */
    border: 2px solid #fff;
    box-shadow: 0 2px 6px rgba(16, 32, 48, .35);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .4px;
    white-space: nowrap;
    cursor: pointer;
}

.kartennadel::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -8px;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: #fff;
}

/* ============================================================
   Zeitleiste der Terminkarte
   Der Regler ist das Hauptwerkzeug und bekommt deshalb den ganzen übrigen Platz. Die Uhrzeit
   daneben steht in gleichbreiten Ziffern – sonst wackelt sie beim Ziehen, weil eine 1 schmaler
   ist als eine 8.
   ============================================================ */

.zeitleiste {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 14px;
    margin-bottom: 14px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
}

.zeitleiste__uhr {
    min-width: 58px;
    text-align: center;
    font-size: 16px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-stark);
}

.zeitleiste__regler {
    flex: 1 1 240px;
    height: 26px;
    accent-color: var(--primaer);
    cursor: pointer;
}

/* ============================================================
   Aufmaß: Fensterzeichnung und Bildauswahl

   Die Hülle bekommt eine feste Höhe, die Zeichnung füllt sie aus. Das ist nötig, nicht nur
   hübsch: Eine SVG mit viewBox, aber ohne width und height hat keine eigene Größe und fällt
   in einem Flex-Kasten auf null zusammen – sichtbar bleibt dann nichts, und zwar ohne jede
   Fehlermeldung.

   Innerhalb einer Zeichnung stimmt der Maßstab weiterhin: Rahmen, Flügel und Maßkette sind in
   Millimetern gerechnet. Zwischen zwei Zeichnungen tut er es nicht mehr, weil jede ihre Box
   ausfüllt – deshalb steht an jeder ihre Maßkette.
   ============================================================ */

.fensterbild-huelle {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px;
    height: 320px;
}

.fensterbild-huelle .fensterbild {
    width: 100%;
    height: 100%;
}

.fensterbild-huelle--klein {
    padding: 4px;
    height: 76px;
}

/* ---------- Profilbild: Foto und gerechneter Schnitt des Profilsystems ----------
   Neben der Skizze und nicht darunter, wo Platz ist: Wer ein Fenster ansieht, soll das Profil
   im selben Blick haben. Der Schnitt ist hochkant und schmal, er braucht wenig Breite. */

.profilbild {
    margin: 10px 0 0;
    display: flex;
    gap: 12px;
    align-items: center;
    flex-wrap: wrap;
}

.profilbild__bilder {
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 6px;
    border: 1px solid var(--rand);
    border-radius: var(--radius-klein);
    background: var(--flaeche);
}

.profilbild__foto {
    height: 150px;
    max-width: 200px;
    object-fit: contain;
    border-radius: var(--radius-klein);
}

.profilbild__schnitt { height: 150px; }
.profilbild__schnitt .profilschnitt { height: 100%; width: auto; display: block; }

.profilbild__text {
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: 12.5px;
    color: var(--text-schwach);
    min-width: 0;
}

.profilbild__text strong { color: var(--text); font-size: 13.5px; }
.profilbild__quelle { font-size: 11px; }

.profilbild--klein { margin: 0; }
.profilbild--klein .profilbild__bilder { padding: 2px; border: 0; }
.profilbild--klein .profilbild__foto,
.profilbild--klein .profilbild__schnitt { height: 64px; }

.profilbild--leer {
    font-size: 12px;
    color: var(--text-schwach);
    margin-top: 8px;
}

/* In der Kontrolle des Fensterassistenten ist der Schnitt die Stelle, an der der Monteur Profil
   und Bautiefe noch einmal prüft – dafür muss er lesbar sein. Mit 150 Pixeln unter der Skizze
   war er es nicht; hier steht er gut halb so hoch wie die Zeichnung, Beschriftung daneben –
   in der rechten Spalte unter dem Befund, damit der Dialog nicht höher wird als die Skizze. */
.kontrollbild .profilbild { margin: 16px 0 0; flex-wrap: nowrap; }
.kontrollbild .profilbild__schnitt,
.kontrollbild .profilbild__foto { height: 230px; }

/* Die Kennwertmaske der Profilsysteme: Felder links, der Schnitt daneben wächst mit. */
.profilpflege { display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-start; }
.profilpflege__felder { flex: 1 1 360px; min-width: 0; }
.profilpflege__vorschau { flex: 0 0 auto; }

/* ---------- Bestellmaß neben dem Bestelltext ---------- */

.bestellmass {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    padding: 8px 12px;
    margin-bottom: 10px;
    border-radius: var(--radius-klein);
    background: var(--primaer-blass);
    border: 1px solid var(--rand);
}

.bestellmass__titel {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-schwach);
}

.bestellmass strong { font-size: 15px; color: var(--text); }
.bestellmass__weg { font-size: 12px; color: var(--text-schwach); flex-basis: 100%; }
.bestellmass--leer { background: var(--flaeche); }

.schalterreihe { display: flex; flex-wrap: wrap; gap: 4px 18px; margin-bottom: 4px; }

.bildauswahl {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(116px, 1fr));
    gap: 10px;
}

.bildkachel {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 10px 8px;
    min-height: 88px;
    font: inherit;
    font-size: 12.5px;
    color: var(--text);
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    cursor: pointer;
    transition: border-color .12s ease, box-shadow .12s ease;
}

.bildkachel:hover { border-color: var(--rand-stark); }

/* Die gewählte Kachel trägt einen doppelten Rand statt einer Füllung: Die Zeichnung darin
   soll dieselbe bleiben, damit man Gewähltes und Nichtgewähltes vergleichen kann. */
.bildkachel--gewaehlt {
    border-color: var(--primaer);
    box-shadow: inset 0 0 0 1px var(--primaer);
    color: var(--primaer);
    font-weight: 600;
}

.bildkachel__text {
    text-align: center;
    line-height: 1.25;
}

/* Die Fensterübersicht im Angebot: Bild links, Angaben rechts. Auf schmalem Schirm
   untereinander – auf dem Tablet ist nebeneinander beides zu klein. */
.fensterliste__zeile {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: 22px;
    padding: 18px 20px;
    align-items: center;
}

.fensterliste__zeile + .fensterliste__zeile { border-top: 1px solid var(--rand-zart); }

@media (max-width: 760px) {
    .fensterliste__zeile { grid-template-columns: 1fr; }
}

.fensterliste__bild { background: #fff; border-radius: var(--radius); }

.fensterliste__nummer {
    font-size: 11.5px;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-schwach);
}

.fensterliste__text h3 { margin: 4px 0 12px; }

/* Zwei Spalten aus Begriff und Wert – als Definitionsliste, weil es genau das ist. */
.fensterdaten {
    display: grid;
    grid-template-columns: 150px 1fr;
    gap: 5px 14px;
    margin: 0 0 10px;
    font-size: 13.5px;
}

.fensterdaten dt { color: var(--text-schwach); }
.fensterdaten dd { margin: 0; color: var(--text-stark); }

/* Ein Befund der Plausibilitätsprüfung. */
.befund {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 9px 12px;
    border-radius: var(--radius);
    font-size: 13px;
    line-height: 1.45;
    border-left: 3px solid transparent;
}

.befund + .befund { margin-top: 6px; }

.befund--hinweis {
    background: var(--gelb-blass);
    border-left-color: var(--gelb);
    color: var(--gelb-dunkel);
}

.befund--fehler {
    background: var(--rot-blass);
    border-left-color: var(--rot);
    color: var(--rot-dunkel);
}

/* Der dritte Fall: nichts aufgefallen. Er stand an vier Stellen als `style`-Angabe im Markup
   mit festen Grün- und Weißtönen – und blieb damit im Dunkeln ein hellgrünes Band. Als Klasse
   neben den beiden anderen ist er das, was er ist: eine dritte Stufe desselben Bausteins. */
.befund--gut {
    background: var(--gruen-blass);
    border-left-color: var(--gruen);
    color: var(--gruen-dunkel);
}

/* Die Schrittleiste des Aufmaß-Assistenten. */
.schrittleiste {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}

.schritt {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 12px;
    border-radius: 999px;
    border: 1px solid var(--rand);
    background: var(--flaeche);
    font: inherit;
    font-size: 12.5px;
    color: var(--text-schwach);
    cursor: pointer;
    white-space: nowrap;
}

.schritt--aktiv {
    border-color: var(--primaer);
    background: var(--primaer);
    color: #fff;
    font-weight: 600;
}

.schritt--erledigt { color: var(--text); border-color: var(--rand-stark); }

.schritt__zahl {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background: var(--flaeche-blass);
    font-size: 11px;
    font-weight: 600;
}

.schritt--aktiv .schritt__zahl { background: rgba(255, 255, 255, .25); }

/* Die kleine Karte auf den Detailseiten sitzt unter der Anschrift. */
.karte-klein {
    margin-top: 12px;
    border-top: 1px solid var(--rand-zart);
    padding-top: 12px;
}

.karte-leer {
    padding: 18px;
    border: 1px dashed var(--rand);
    border-radius: var(--radius);
    color: var(--text-schwach);
    font-size: 12px;
    line-height: 1.5;
    text-align: center;
}

/* Fußzeile mit Blätterung: Zähler links, Knöpfe rechts. */
.blaetterung {
    display: flex;
    align-items: center;
    gap: 10px;
}

.blaetterung__luecke { flex: 1 1 auto; }

/* ============================================================
   Sortierbare Spaltenüberschrift
   Die Schaltfläche füllt die ganze Zelle, damit das Ziel so groß ist wie die Überschrift
   aussieht – ein Pfeil allein wäre auf dem Tablet auf der Baustelle kaum zu treffen. Sie
   erbt die Schrift des <th>, sonst stünde eine Spalte plötzlich in Systemschrift da.
   ============================================================ */

.sortierkopf {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    width: 100%;
    font: inherit;
    letter-spacing: inherit;
    text-transform: inherit;
    color: inherit;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
}

.zelle-rechts .sortierkopf { justify-content: flex-end; }

.sortierkopf:hover { color: var(--text); }

.sortierkopf:focus-visible {
    outline: 2px solid var(--primaer);
    outline-offset: 2px;
    border-radius: 3px;
}

table.tabelle th.sortierkopf--aktiv { color: var(--text); }

/* ============================================================
   Filterzeile unter den Spaltenüberschriften
   Der Filter steht dort, wo die Werte stehen. Die Zeile trägt bewusst keine Großbuchstaben
   und keine Laufweite – sie ist Bedienung, nicht Überschrift, und darf sich vom Kopf
   darüber unterscheiden.
   ============================================================ */

table.tabelle th.filterzelle {
    padding: 0 8px 9px;
    background: var(--flaeche);
    border-bottom: 1px solid var(--rand);
    text-transform: none;
    letter-spacing: normal;
    vertical-align: top;
}

.feld--filter {
    height: 30px;
    padding: 0 8px;
    font-size: 12.5px;
    font-weight: 400;
    letter-spacing: normal;
    text-transform: none;
    border-radius: 7px;
    min-width: 0;
}

/* Eingabefelder im Erfassungsgitter des Aufmaßblattes.

   Zwanzig Spalten nebeneinander, und in jeder Zelle ein Feld – mit der gewöhnlichen Feldhöhe
   wäre eine Zeile so hoch wie drei und das Blatt nicht mehr zu überblicken. Deshalb flach und
   randlos: Der Rand der Tabellenzelle grenzt hier schon ab, ein zweiter daneben wäre ein Gitter
   im Gitter.

   `width: 100%` und `min-width: 0`, weil ein Zahlenfeld sonst seine eigene Mindestbreite
   durchsetzt und die Spaltenbreiten der Kopfzeile aushebelt. */
.feld--gitter {
    height: 28px;
    padding: 0 6px;
    font-size: 12.5px;
    font-weight: 400;
    letter-spacing: normal;
    text-transform: none;
    border-radius: 5px;
    border-color: transparent;
    background: transparent;
    width: 100%;
    min-width: 0;
}

.feld--gitter:hover { border-color: var(--rand); }
.feld--gitter:focus { border-color: var(--primaer); background: var(--flaeche); }

/* Dichte Tabelle: weniger Luft je Zeile, damit vierzig Positionen auf einen Bildschirm passen.
   Angefasst wird nur der Innenabstand – Schriftgröße und Farben bleiben die der Tabelle,
   sonst sähe das Gitter nach einem zweiten Programm aus. */
.tabelle--dicht th,
.tabelle--dicht td { padding: 3px 4px; }

/* Ein gesetzter Filter muss auffallen: Sonst sucht man den Fehler in den Daten, während
   in Wahrheit noch eine Eingrenzung von vorgestern steht. */
.feld--gesetzt {
    border-color: var(--primaer);
    box-shadow: inset 0 0 0 1px var(--primaer);
    color: var(--primaer);
}

/* Von und bis stehen untereinander: Nebeneinander bekäme keines der beiden genug Breite,
   und ein Ausklappfeld überschritte die Hülle der Tabelle, die alles Herausragende
   abschneidet, weil sie breite Listen waagerecht scrollen muss. */
.bereichsfilter {
    display: grid;
    gap: 4px;
}

/* Der Streifen über der Tabelle: nur noch das, was für die ganze Liste gilt. */
.filterstand {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 0 12px;
    font-size: 13px;
    color: var(--text-schwach);
}

/* ============================================================
   Klappbarer Kartenkopf
   Der ganze Kopf ist die Schaltfläche – ein kleiner Pfeil allein wäre ein zu schmales Ziel,
   besonders auf dem Tablet auf der Baustelle.
   ============================================================ */

.klapp-kopf {
    width: 100%;
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    border-bottom: 1px solid var(--rand-zart);
    text-align: left;
    cursor: pointer;
}

.klapp-kopf:hover { background: var(--flaeche-blass); }

.klapp-kopf__rechts {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

/* Ein Kästchen mit Beschriftung in der Filterzeile. */
.schalter {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
}

.schalter input { width: 16px; height: 16px; accent-color: var(--primaer); }

.assistent__faden > .karte__koerper {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 10px;
    overflow-y: auto;
    max-height: 62vh;
}

.assistent__eingabe {
    display: flex;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--rand-zart);
}

.assistent__eingabe .feld { flex: 1; }

.assistent__sprung { padding: 0 16px 12px; }
.assistent__sprachmeldung { padding: 0 16px 12px; margin: 0; }

.blase {
    max-width: 78%;
    padding: 10px 14px;
    border-radius: var(--radius-gross);
    line-height: 1.45;
    white-space: pre-wrap;
}

.blase--frage {
    align-self: flex-end;
    background: var(--primaer);
    color: var(--text-invers);
    border-bottom-right-radius: var(--radius-klein);
}

.blase--antwort {
    align-self: flex-start;
    background: var(--flaeche-blass);
    border: 1px solid var(--rand-zart);
    border-bottom-left-radius: var(--radius-klein);
}

.blase--wartet { color: var(--text-schwach); font-style: italic; }

.blase__fuss {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
    font-size: 11px;
    opacity: .75;
}

.blase--frage .blase__fuss { justify-content: flex-end; }

.faden {
    display: block;
    width: 100%;
    text-align: left;
    padding: 10px 12px;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: none;
    cursor: pointer;
}

.faden:hover { background: var(--flaeche-blass); }
.faden.aktiv { background: var(--primaer-blass); border-color: var(--primaer); }

.faden__name { font-weight: 500; color: var(--text-stark); }

.faden__fuss {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 4px;
    font-size: 11px;
    color: var(--text-schwach);
}

/* ---------- Elektrotechnik ---------- */

/*
   Der Übersichtsschaltplan. Er ist breiter als hoch und braucht deshalb eine andere Hülle als
   das Fensterbild: Dort begrenzt die Höhe, hier die Breite.
*/
.anlagenbild-huelle {
    width: 100%;
    max-height: 520px;
    padding: 18px 10px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.anlagenbild-huelle svg { width: 100%; height: auto; max-height: 480px; }

.anlagenbild-huelle--klein { max-height: 120px; padding: 6px; }
.anlagenbild-huelle--klein svg { max-height: 108px; }

/*
   Das Rechenband unter einem Eingabeformular: die gerechneten Werte, die sich mit jeder
   Eingabe ändern. Es steht bewusst zwischen Eingabe und Befunden – erst die Zahl, dann die
   Beurteilung.
*/
.rechenband {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 26px;
    padding: 12px 16px;
    margin-bottom: 14px;
    background: var(--flaeche-blass);
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
}

.rechenband > div { display: flex; flex-direction: column; gap: 2px; }

.rechenband__titel {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-schwach);
}

.rechenband strong { font-size: 15px; color: var(--text-stark); }
.rechenband .zelle-schwach { font-size: 12px; }

/* Ein Wert, der eine Grenze reißt – dieselbe Farbe wie ein Befund der Stufe Fehler. */
.zelle-warnung { color: var(--rot); font-weight: 600; }

/* ---------- Zählerschrank ---------- */

/* Die Frontansicht. Anders als der Schaltplan ist sie hoch statt breit – der Schrank steht
   an der Wand, und so wird er auch gezeichnet. */
.schrankbild-huelle {
    width: 100%;
    max-height: 560px;
    padding: 16px 10px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.schrankbild-huelle svg { max-height: 528px; width: auto; max-width: 100%; }

.schrankbild-huelle--klein { max-height: 150px; padding: 6px; }
.schrankbild-huelle--klein svg { max-height: 138px; }

/* Der Editor: Eingabe links, Ergebnis rechts. Die Ansicht bleibt beim Scrollen stehen – ein
   Schrank mit vier Feldern ist länger als der Bildschirm, und gerade beim untersten Feld will
   man sehen, wo das Gerät landet. Damit sie samt Zahlen und Befunden auch auf einem
   Laptop in die Höhe passt, gibt die Zeichnung hier nach, statt über den Rand zu laufen. */
.schrankeditor {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(300px, 2fr);
    gap: 24px;
    align-items: start;
}

.schrankeditor__eingabe { grid-column: 1; grid-row: 1; }
.schrankeditor__eingabe > .abschnitt:last-child { margin-bottom: 0; }

.schrankeditor__ansicht {
    grid-column: 2;
    grid-row: 1;
    position: sticky;

    /* Unter dem Kopfbereich – aus demselben Grund wie beim `.detail-kopf`. */
    top: calc(var(--kopfbereich-hoehe, 0px) + 16px);
}

.schrankeditor__ansicht .abschnitt { margin-bottom: 14px; }
.schrankeditor__ansicht .schrankbild-huelle { max-height: min(560px, 58vh); }
.schrankeditor__ansicht .schrankbild-huelle svg { max-height: calc(min(560px, 58vh) - 32px); }

/* Schmal rutscht die Ansicht wieder nach oben – sie steht im Markup zuerst. */
@media (max-width: 1000px) {
    .schrankeditor { grid-template-columns: minmax(0, 1fr); }
    .schrankeditor__eingabe,
    .schrankeditor__ansicht { grid-column: auto; grid-row: auto; }
    .schrankeditor__ansicht { position: static; }
}

/* Ein Feld in der Konfiguration. Kein Kärtchen mit Schatten: Felder stehen nebeneinander in
   einem Schrank, nicht frei im Raum. Eine Linie oben genügt, um sie zu trennen. */
.feldkarte {
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    margin-bottom: 12px;
    overflow: hidden;
}

.feldkarte__kopf {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 14px;
    background: var(--flaeche-blass);
    border-bottom: 1px solid var(--rand);
}

.feldkarte__nr {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--text-schwach);
}

.hutschienen { padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }

.hutschiene { display: flex; align-items: center; gap: 10px; }

.hutschiene__nr {
    width: 18px;
    flex: none;
    font-size: 11px;
    color: var(--text-schwach);
    text-align: right;
}

/* Das Raster ist die Hutschiene: eine Spalte je Teilungseinheit. Geräte spannen über so
   viele Spalten, wie sie breit sind – damit stimmt das Bild mit der Wirklichkeit überein,
   ohne dass irgendwo eine Breite in Pixeln steht. */
.hutschiene__plaetze {
    flex: 1 1 auto;
    display: grid;
    gap: 2px;
    background: var(--flaeche-grau);
    border: 1px solid var(--rand);
    border-radius: 4px;
    padding: 3px;
    min-height: 40px;
}

.platz {
    grid-row: 1;
    border: 0;
    border-radius: 3px;
    padding: 0 4px;
    min-height: 32px;
    font: inherit;
    font-size: 11px;
    line-height: 1.15;
    cursor: pointer;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.platz--frei { background: repeating-linear-gradient(45deg, transparent, transparent 3px, var(--rand) 3px, var(--rand) 4px); }
.platz--frei:hover { background: var(--primaer-blass); }

.platz--belegt {
    background: var(--flaeche);
    border: 1px solid var(--text);
    color: var(--text-stark);
    font-weight: 500;
}

.platz--belegt span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.platz--belegt:hover { border-color: var(--primaer); }

.platz--fi { border-color: var(--primaer); color: var(--primaer-dunkel); }
.platz--haupt { border-width: 2px; }
.platz--steuer { border-style: dashed; }
.platz--blind { background: var(--flaeche-grau); border-style: dotted; color: var(--text-schwach); }

/* ==========================================================================
   Online-Hilfe
   Der Knopf steht auf jedem Bildschirm an derselben Stelle: rechts neben der
   Überschrift. Die Tafel schiebt sich von rechts herein und lässt den
   Bildschirm stehen – ein Dialog verdeckte genau das, wonach gefragt wurde.
   ========================================================================== */

.hilfeknopf {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--rand);
    border-radius: 50%;
    background: var(--flaeche);
    color: var(--text-schwach);
    cursor: pointer;
    transition: color .12s, border-color .12s, background .12s;
}

.hilfeknopf:hover {
    color: var(--primaer-dunkel);
    border-color: var(--primaer);
    background: var(--primaer-blass);
}

.hilfeknopf--klein { width: 24px; height: 24px; }

/* ---------- Der Logbuchknopf: derselbe Knopf, andere Farbe ----------
   Die Sprechblase steht neben dem Fragezeichen, in derselben Größe und derselben Form – und
   solange beide grau waren, verschwand sie darin: Wer die Hilfe kennt, liest an dieser Stelle
   „Hilfe" und sieht den zweiten Knopf nicht mehr. Aus dem Betrieb gemeldet, und es ist die
   teurere Hälfte der beiden: Die Hilfe findet man auch über die Suchleiste, das Logbuch eines
   Vorgangs nur hier und in der Akte.

   **Die Farbe kommt aus den Tokens und ist nicht neu erfunden.** `--gruen-blass` als Fläche und
   `--gruen-dunkel` als Zeichen sind dasselbe Paar wie am grünen Abzeichen, am Befundband und am
   Anliegenstreifen; beide Werte sind im dunklen Block eigens gesetzt. Ein fester Grünton stünde
   im Dunkeln als hellgrüner Fleck da – genau das ist dem Band „keine Auffälligkeiten" schon
   einmal passiert. */
.logbuchknopf {
    background: var(--gruen-blass);
    border-color: var(--gruen);
    color: var(--gruen-dunkel);
}

/* Die Regel des Fragezeichens färbt beim Überfahren blau; hier bleibt es bei Grün, nur
   kräftiger. Sie steht deshalb hinter `.hilfeknopf:hover` und nicht davor. */
.logbuchknopf:hover {
    background: color-mix(in srgb, var(--gruen) 22%, var(--flaeche));
    border-color: var(--gruen-dunkel);
    color: var(--gruen-dunkel);
}

.dialog__kopfknoepfe { display: flex; align-items: center; gap: 6px; }

/* ---------- Der Betrachter für Belege und Anhänge ----------

   Ein **Lichtkasten und keine Schublade**, anders als die Hilfe daneben: Die liest man *neben*
   dem Bildschirm, ein Blatt liest man *statt* des Bildschirms. Und dreißig Zentimeter Schublade
   trügen eine A4-Seite gar nicht – sie stünde als Briefmarke da.

   Er nimmt fast das ganze Fenster und legt sich über alles, auch über einen offenen Dialog
   (`z-index` über dem der Hilfe: Ein Beleg wird oft aus einer Maske heraus geöffnet). */
.pdfansicht {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    background: var(--flaeche-grau);
    z-index: 90;
    animation: dialog-grund .16s ease-out;
}

.pdfansicht:focus { outline: none; }

.pdfansicht__kopf {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: none;
    padding: 10px 14px;
    background: var(--flaeche);
    border-bottom: 1px solid var(--rand);
}

/* Ein langer Dateiname darf den Knopf nicht hinausschieben – gekürzt wird der Name, denn
   der ganze steht ohnehin im `title`. */
.pdfansicht__name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    color: var(--text);
}

.pdfansicht__werkzeuge {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: none;
}

/* Der weiße Grund ist hier richtig: Das Blatt kommt **ungefärbt** vom Server, und dunkle
   Striche auf dunklem Grund verschwinden. Dieselbe Ausnahme wie bei den Zeichnungen – sie
   steht in der Liste von `DunkelmodusTests`. */
.pdfansicht__blatt {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    border: none;
    background: #fff;
}

/* Ein Bild kommt in ein `<img>` und nicht in den Rahmen: Im Rahmen sähe ein Belegfoto aus wie
   ein Dokument, und der Zoom des PDF-Betrachters hilft ihm nicht. */
.pdfansicht__blatt--bild {
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: auto;
    padding: 16px;
}

.pdfansicht__blatt--bild img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* Die von pdf.js gezeichneten Seiten – untereinander und scrollbar, für die Geräte ohne
   eigenen PDF-Betrachter. Der Grund bleibt hier **nicht** weiß: Zwischen zwei Blättern soll
   man die Kante sehen, sonst läuft eine dreiseitige Rechnung als ein Band durch. */
.pdfansicht__blatt--seiten {
    overflow: auto;
    background: var(--flaeche-grau);
    padding: 12px;
    -webkit-overflow-scrolling: touch;
}

/* Drucken über die Seite (`handwerkDatei.drucken` ohne Rahmen): nur das Blatt bleibt sichtbar,
   jede Leinwand von pdf.js auf eine eigene Seite. Sichtbarkeit und nicht `display`, weil das
   Blatt tief im Baum hängt und seine Eltern dabei stehen bleiben müssen. */
@media print {
    body.handwerk-druckt * { visibility: hidden; }

    body.handwerk-druckt .pdfansicht__blatt,
    body.handwerk-druckt .pdfansicht__blatt * { visibility: visible; }

    body.handwerk-druckt .pdfansicht { position: static; background: transparent; animation: none; }

    body.handwerk-druckt .pdfansicht__blatt {
        position: absolute;
        left: 0;
        top: 0;
        overflow: visible;
        padding: 0;
        background: transparent;
    }

    body.handwerk-druckt .pdfansicht__blatt canvas {
        width: 100% !important;
        height: auto !important;
        break-after: page;
    }
}

/* Die Fläche, die pdf.js gehört. Blazor rendert hier nichts hinein – der Grund steht im
   Bauteil. */
.pdfansicht__leinwaende {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
}

.pdfansicht__seite {
    display: block;
    height: auto;
    background: #fff;
    box-shadow: var(--schatten);
    border-radius: 2px;
}

.pdfansicht__warten {
    flex: 1 1 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-schwach);
}

/* Der Grund fängt den Klick daneben ab. Er bleibt fast durchsichtig: Die Hilfe legt
   die Seite nicht still, man soll weiterlesen können, was hinter ihr steht. */
.hilfe-grund {
    position: fixed;
    inset: 0;
    background: rgba(11, 35, 55, .18);
    z-index: 80;
    animation: dialog-grund .16s ease-out;
}

.hilfetafel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(30rem, 100vw);
    display: flex;
    flex-direction: column;
    background: var(--flaeche);
    border-left: 1px solid var(--rand);
    box-shadow: var(--schatten-hoch);
    z-index: 81;
    animation: hilfe-herein .2s cubic-bezier(.2, .8, .3, 1);
}

@keyframes hilfe-herein {
    from { transform: translateX(24px); opacity: 0; }
    to { transform: none; opacity: 1; }
}

.hilfetafel__kopf {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--rand-zart);
    flex: none;
}

.hilfetafel__marke {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--primaer-dunkel);
}

.hilfetafel__zurueck {
    display: inline-flex;
    align-items: center;
    padding: 4px;
    border: none;
    background: none;
    color: var(--text-schwach);
    cursor: pointer;
}

.hilfetafel__zurueck:hover { color: var(--text); }

.hilfetafel__koerper {
    padding: 18px 22px 40px;
    overflow-y: auto;
    flex: 1 1 auto;
    line-height: 1.62;
    color: var(--text);
}

.hilfetafel__titel {
    margin: 0 0 6px;
    font-size: 20px;
    line-height: 1.2;
    color: var(--text-stark);
}

.hilfetafel__kurz {
    margin: 0 0 4px;
    color: var(--text-schwach);
}

.hilfetafel__abschnitt {
    margin: 22px 0 6px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-stark);
}

.hilfetafel__koerper p { margin: 0 0 10px; }

/* Feld und Bedeutung stehen untereinander und nicht nebeneinander: Die Tafel ist
   schmal, und zwei Spalten ergäben zwei sehr enge. */
.hilfefelder { margin: 0; }

.hilfefeld {
    padding: 9px 0;
    border-bottom: 1px solid var(--rand-zart);
}

.hilfefeld:last-child { border-bottom: none; }

.hilfefeld dt {
    font-weight: 600;
    color: var(--text-stark);
    margin-bottom: 2px;
}

.hilfefeld dd { margin: 0; }

.hilfe-spruenge { display: flex; flex-direction: column; gap: 6px; }

.hilfe-sprung {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--rand);
    border-radius: var(--radius-klein);
    background: var(--flaeche-blass);
    color: var(--text-stark);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.hilfe-sprung:hover { border-color: var(--primaer); color: var(--primaer-dunkel); }

@media (prefers-reduced-motion: reduce) {
    .hilfetafel, .hilfe-grund { animation: none; }
}

.hilfe-sprung__bereich {
    display: block;
    font-size: 11px;
    color: var(--text-schwach);
    letter-spacing: .04em;
}

/* ---------- Das Logbuch als Schublade ----------
   Sie teilt Form, Grund und Bewegung mit der Hilfetafel und trägt deren Klasse mit; hier steht
   nur, was sie unterscheidet. Eine eigene Schublade daneben wäre dieselbe Sache zweimal, und
   beim ersten geänderten Maß stünden zwei verschieden breite Tafeln im selben Haus. */
.logbuchtafel__vorgang {
    padding: 12px 22px;
    border-bottom: 1px solid var(--rand);
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* **Der Verlauf nimmt den Platz, die Eingabe bleibt stehen.** `min-height: 0` gehört dazu: Ohne
   das wächst ein Flexkind über seinen Kasten hinaus statt zu rollen – dann liefe die
   Eingabezeile aus dem Bild, und zwar genau bei einem langen Verlauf. */
.logbuchtafel__verlauf {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 14px 22px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.logbuchbeitrag {
    background: var(--flaeche-blass);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-klein);
    padding: 9px 11px;
}

/* Was das System geschrieben hat, steht blasser: Es ist Buchführung und nicht Gespräch. */
.logbuchbeitrag--system { background: transparent; }

.logbuchbeitrag__kopf {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--text-stark);
}

.logbuchbeitrag__text {
    margin-top: 4px;

    /* Zeilenumbrüche bleiben stehen: Wer eine Aufzählung tippt, hat sie so gemeint. */
    white-space: pre-wrap;
}

.logbuchbeitrag__fuss {
    margin-top: 6px;
    font-size: 11.5px;
    color: var(--text-schwach);
}

.logbuchtafel__mehr { font-size: 12.5px; }

.logbuchtafel__eingabe {
    flex: 0 0 auto;
    padding: 12px 22px 16px;
    border-top: 1px solid var(--rand);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.logbuchtafel__leiste {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
}

/* Die Namen bekommen eine eigene Höhe und rollen darin. Ohne Deckel schöbe ein Team von
   zwanzig Leuten den Verlauf und die Eingabezeile aus der Schublade – also genau das weg,
   wozu man gerade jemanden ansprechen wollte. */
.logbuchtafel__ansprache {
    display: flex;
    flex-direction: column;
    gap: 6px;
    max-height: 168px;
    overflow-y: auto;
    padding: 8px 10px;
    border: 1px solid var(--rand);
    border-radius: 8px;
    background: var(--flaeche-blass);
}

/* ---------- Lager ---------- */

/* Gewerke und häufig gebrauchtes Material nebeneinander; auf schmalen Schirmen untereinander. */
.lager-raster {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
    gap: 16px;
    align-items: start;
}

/* Ein liegender Balken für Anteile – der Anteil steht als Breite da, nicht als zweite Zahl
   neben dem Betrag. */
.anteilbalken {
    height: 8px;
    border-radius: 4px;
    background: var(--flaeche-grau);
    overflow: hidden;
}

.anteilbalken__fuellung {
    height: 100%;
    border-radius: 4px;
    background: var(--primaer);
}

/* Die Kopfzeile je Lieferant in der Bestellliste. */
.tabelle tr.tabelle__gruppe td {
    background: var(--flaeche-blass);
    border-top: 1px solid var(--rand);
}

.tabelle tr.tabelle__unterzeile td {
    background: var(--flaeche-blass);
    font-size: 13px;
}

/* Eine Knopfreihe, von der genau einer gewählt ist – die Buchungsart. */
.segment {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
/* ---------- PV-Konfigurator ---------- */

/* Eingabe links, Ergebnis rechts – das Ergebnis ist breiter, weil Zeichnung und Liste Platz brauchen. */
.pv-raster {
    display: grid;
    grid-template-columns: minmax(320px, 420px) minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}

@media (max-width: 1100px) {
    .pv-raster { grid-template-columns: minmax(0, 1fr); }
}

.pv-legende {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    font-size: 12px;
    color: var(--text-schwach);
}

.pv-legende span { display: inline-flex; align-items: center; gap: 6px; }

.pv-legende i {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 3px;
}

/* Die beiden Schritte über dem Konfigurator – Reiter, keine Seiten (die Zeichnung lebt nur im Browser). */
.pv-schritte {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.pv-schritte__knopf {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    color: var(--text);
    font: inherit;
    font-weight: 500;
    cursor: pointer;
}

.pv-schritte__knopf--aktiv {
    border-color: var(--primaer);
    background: var(--primaer-blass);
    color: var(--text-stark);
}

.pv-schritte__nr {
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--primaer-dunkel);
    color: #fff;
    font-size: 12px;
}

/* Karte links, Zahlen rechts. Umgebrochen wird an der Breite der Hülle und nicht des Fensters –
   bei ausgeklappter Menüleiste bleibt der Karte sonst zu wenig. */
.dachaufnahme {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(300px, 380px);
    gap: 20px;
    align-items: start;
    container-type: inline-size;
}

@container (max-width: 900px) {
    .dachaufnahme { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 1100px) {
    .dachaufnahme { grid-template-columns: minmax(0, 1fr); }
}

.dachaufnahme__leiste {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    /* Der Kartenkopf verteilt sonst über die Breite – die Knöpfe gehören zusammen. */
    justify-content: flex-start;
    /* Die Leiste behält ihre Höhe, gleich ob gezeichnet wird oder nicht. */
    min-height: 52px;
}

/* Zwei Zeilen Platz, auch wenn eine reicht: Beim Bearbeiten der Module wechselt hier Tipp und
   Meldung, und eine Leiste, die dabei eine Zeile gewinnt, schöbe die Karte unter dem Zeiger weg. */
.dachaufnahme__tipp {
    font-size: 13px;
    line-height: 1.35;
    min-height: 2.7em;
    display: flex;
    align-items: center;
    color: var(--text-schwach);
    flex: 1 1 260px;
}
.dachaufnahme__tipp--meldung { color: var(--text); font-weight: 600; }

/* Die Vorschlagslisten von Kunden- und Adresssuche klappen über den Rand dieser Karte hinaus
   nach unten auf. `.karte` schneidet ab (`overflow: hidden`), und die Luftbildkarte darunter
   legte sich mit ihren Ebenen darüber – die Liste stand hinter dem Luftbild. Am Bildschirm so
   gemeldet. Deshalb hier kein Abschneiden und eine Stapelebene über der Karte. */
.dachaufnahme__finden {
    overflow: visible;
    position: relative;
    z-index: 2;
}

/* Eigene Stapelebene: Leaflet zählt seine Ebenen bis 1000, und ohne sie stünden sie neben allem
   anderen der Seite – über jeder aufklappenden Liste, die die Karte berührt. */
.dachaufnahme__kartenhuelle { position: relative; isolation: isolate; z-index: 0; }

/* Über den Kacheln, unter den Bedienelementen von Leaflet (die stehen bei 800/1000). */
.dachaufnahme__kartenwerkzeug {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 700;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    max-width: calc(100% - 70px);
}

.dachaufnahme__kartenwerkzeug > * { box-shadow: var(--schatten); }

.dachaufnahme__dienst {
    width: auto;
    min-width: 170px;
}


.dachaufnahme__punktmasse {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 14px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--rand-zart);
    font-size: 13px;
}

.dachaufnahme__punktmasse label { display: inline-flex; align-items: center; gap: 6px; }
.dachaufnahme__punktmasse input { width: 80px; }

.dachaufnahme__karte {
    height: 560px;
    max-height: 70vh;
    background: var(--flaeche-grau);
}

.dachaufnahme__fuss {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    padding: 8px 16px;
    font-size: 12px;
}

.dachaufnahme__schritte { margin: 0; padding-left: 20px; font-size: 14px; line-height: 1.6; }

.dachaufnahme__reiter { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }

.dachaufnahme__reiterknopf {
    padding: 6px 10px;
    border: 1px solid var(--rand);
    border-radius: var(--radius-klein);
    background: var(--flaeche);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.dachaufnahme__reiterknopf--aktiv { border-color: var(--primaer); background: var(--primaer-blass); }

.dachaufnahme__zahlen { display: grid; gap: 6px; font-size: 13px; }
.dachaufnahme__zahlen > div { display: flex; justify-content: space-between; gap: 12px; }
.dachaufnahme__zahlen span { color: var(--text-schwach); }
.dachaufnahme__zahlen strong { text-align: right; }

.dachaufnahme__knoepfe { display: flex; flex-wrap: wrap; gap: 8px; }

.dachaufnahme__speichern { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; font-size: 12px; }

.dachaufnahme__gespeicherte { display: grid; gap: 4px; }

.dachaufnahme__gespeichert {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 13px;
}

.dachaufnahme__gespeichert > button:first-child {
    display: grid;
    gap: 2px;
    text-align: left;
    min-width: 0;
}

/* Das Foto der Dachplanung über der Detailplanung und an der Anlage – ein Knopf, weil es die
   Zeichnung öffnet. Der Rand wie bei einer Karte, damit es nicht wie ein bloßes Bild aussieht. */
.dachfoto {
    position: relative;
    display: block;
    width: 100%;
    max-width: 720px;
    margin-bottom: 14px;
    padding: 0;
    overflow: hidden;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche-grau);
    font: inherit;
    cursor: pointer;
}

.dachfoto img { display: block; width: 100%; max-height: 360px; object-fit: cover; }

.dachfoto__text {
    position: absolute;
    left: 10px;
    bottom: 10px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: var(--radius-klein);
    background: rgba(13, 26, 36, .78);
    color: #fff;
    font-size: 13px;
}

.dachfoto:hover { border-color: var(--primaer); }

/* An der Anlage: klein vor dem Namen des Felds. */
.dachfoto--klein {
    display: inline-block;
    width: 72px;
    height: 48px;
    margin: 0 8px 0 0;
    vertical-align: middle;
}

.dachfoto--klein img { height: 48px; max-height: none; }
.dachfoto--klein .dachfoto__text { position: static; padding: 2px 4px; font-size: 10px; }

.dachaufnahme__hindernisse { display: grid; gap: 8px; }

.dachaufnahme__hindernis {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--radius-klein);
    font-size: 13px;
}

.dachaufnahme__hindernis--aktiv { background: var(--rot-blass); }
.dachaufnahme__hindernis label { display: inline-flex; align-items: center; gap: 6px; }
.dachaufnahme__hindernis input { width: 70px; }

/* Maße auf dem Luftbild: ein dunkles Schild, das auf jedem Dach lesbar ist. Die Hülle bleibt
   0 × 0 groß, das Schild steht mittig über dem Punkt. */
.dachkarte__mass-huelle { overflow: visible; }

.dachkarte__mass {
    position: absolute;
    transform: translate(-50%, -50%);
    padding: 1px 6px;
    border-radius: 4px;
    background: rgba(13, 26, 36, .78);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    pointer-events: none;
}

.dachkarte__ecke-huelle { overflow: visible; }

.dachkarte__ecke {
    position: absolute;
    width: 14px;
    height: 14px;
    transform: translate(-50%, -50%);
    border: 3px solid;
    border-radius: 50%;
    background: var(--flaeche);
    cursor: move;
}

/* Griff des gewählten Moduls: groß genug für den Finger, mit Kreuzpfeil-Anmutung über den Rand. */
.dachkarte__modulgriff {
    position: absolute;
    width: 22px;
    height: 22px;
    transform: translate(-50%, -50%);
    border: 3px solid #FFD54F;
    border-radius: 50%;
    background: rgba(13, 26, 36, 0.55);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.7);
    cursor: move;
}

/* Fest gefärbt wie die Zeichnung auf dem Luftbild: Es steht auf einem Foto und nicht auf der Oberfläche. */
.dachkarte__modulweg {
    position: absolute;
    width: 24px;
    height: 24px;
    transform: translate(-50%, -50%);
    border: 2px solid #ffffff;
    border-radius: 50%;
    background: #E53935;
    color: #ffffff;
    font: 700 15px/1 sans-serif;
    padding: 0;
    cursor: pointer;
}

@media (pointer: coarse) {
    .dachkarte__modulgriff { width: 32px; height: 32px; }
    .dachkarte__modulweg { width: 32px; height: 32px; font-size: 18px; }
}

/* Bild und Sinnbild gleich groß, damit die Zeilen der Materialliste auf einer Linie stehen. */
.teilliste__bild {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 8px;
    background: var(--flaeche-blass);
    object-fit: cover;
}
/* ---------- Logbuch ----------
   Ein Zeitstrahl: links die Marke mit dem Sinnbild der Art, rechts der Text. Die Linie
   entsteht aus dem Rand der Marke und nicht aus einem eigenen Element – ein Strich, den
   man zeichnet, hört beim letzten Eintrag nie an der richtigen Stelle auf. */
.verlauf { list-style: none; margin: 0; padding: 0; }

.verlauf__punkt {
    display: flex;
    gap: 12px;
    padding-bottom: 16px;
    position: relative;
}

.verlauf__punkt:not(:last-child)::before {
    content: "";
    position: absolute;
    left: 13px;
    top: 28px;
    bottom: 0;
    width: 2px;
    background: var(--rand);
}

.verlauf__marke {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--flaeche-grau);
    color: var(--text-schwach);
    z-index: 1;
}

.verlauf__marke--blau { background: var(--navy-blass); color: var(--verweis); }
.verlauf__marke--navy { background: var(--navy-blass); color: var(--navy-schrift); }
.verlauf__marke--gruen { background: var(--gruen-blass); color: var(--gruen-dunkel); }
.verlauf__marke--gelb { background: var(--gelb-blass); color: var(--gelb-dunkel); }
.verlauf__marke--rot { background: var(--rot-blass); color: var(--rot-dunkel); }
.verlauf__marke--slate { background: var(--flaeche-grau); color: var(--text-schwach); }

.verlauf__inhalt { flex: 1 1 auto; min-width: 0; }

.verlauf__kopf {
    display: flex;
    gap: 10px;
    align-items: baseline;
    justify-content: space-between;
}

.verlauf__text { margin-top: 2px; white-space: pre-wrap; }

.verlauf__fuss { margin-top: 2px; font-size: 12px; }

/* Anhänge und Ansprache einer Nachricht. Die Kachel ist bewusst klein: Sie zeigt, dass ein
   Bild dabei ist, und nicht das Bild – im Verlauf sollen die Sätze lesbar bleiben. */
.verlauf__anhaenge {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
}

.anhangkachel {
    width: 56px;
    height: 56px;
    padding: 0;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche-grau);
    color: var(--text-schwach);
    cursor: pointer;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.anhangkachel img { width: 100%; height: 100%; object-fit: cover; display: block; }

.anhangzeile {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    padding: 4px 8px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche-grau);
}

.verlauf__anrede {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 6px;
    font-size: 12px;
    color: var(--text-schwach);
}

/* Mehrere Haken nebeneinander – sie brechen um, statt eine Maske breit zu ziehen. */
.hakenfeld {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
}

/* Der Nachrichtenkorb auf der Übersicht. */
.nachrichtenkorb { list-style: none; margin: 0; padding: 0; }

.nachrichtenkorb__zeile {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: flex-start;
    padding: 10px 0;
}

.nachrichtenkorb__zeile:not(:last-child) { border-bottom: 1px solid var(--rand); }

.nachrichtenkorb__inhalt { flex: 1 1 260px; min-width: 0; }

.nachrichtenkorb__kopf {
    display: flex;
    gap: 10px;
    align-items: baseline;
    justify-content: space-between;
}

.nachrichtenkorb__text { margin-top: 2px; white-space: pre-wrap; }

/* Ein Knopf, der wie ein Verweis aussieht – für Nebensächliches im Fließtext. */
.knopf-nackt {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--verweis);
    cursor: pointer;
    text-decoration: underline;
}

.feld--klein { padding: 4px 8px; font-size: 13px; }

/* Der nächste Einrichtungsschritt bei EBICS: ein Kasten, eine Erklärung, ein Knopf.
   Er steht heraus, weil er das Einzige ist, was an dieser Stelle zu tun ist. */
.ebics-schritt {
    display: flex;
    gap: 16px;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    margin: 14px 0;
    padding: 14px 16px;
    border: 1px solid var(--primaer);
    border-radius: var(--radius);
    background: var(--primaer-blass);
}

.ebics-schritt__titel { font-weight: 700; color: var(--text-stark); }

.ebics-schritt__text { font-size: 13px; line-height: 1.5; max-width: 70ch; margin-top: 2px; }

/* Ein Zuordnungsvorschlag im Zahlungsabgleich: Knopf links, Begründung rechts.
   Die Begründung steht daneben und nicht in einem Hinweisfeld – wer 12.000 € bucht,
   soll sie lesen, ohne danach zu suchen.
   Der Name ist ein eigener und nicht `.vorschlag`: So hieß er zuerst, und weil diese Regel weiter
   hinten steht, machte sie jede Zeile der Vorschlagslisten (Projekt, Kunde, Adresse, Position)
   zur Flex-Reihe – Name, Nummer und Zusatz standen als drei gequetschte Spalten nebeneinander,
   ein Wort je Zeile. Gemeldet an der Projektsuche im Termindialog. */
.zuordnungsvorschlag {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 4px 0;
    border-bottom: 1px solid var(--rand-zart);
}

.zuordnungsvorschlag:last-of-type { border-bottom: 0; }

.zuordnungsvorschlag__text { min-width: 0; font-size: 12px; line-height: 1.4; }

/* ============================================================
   Online-Angebotsannahme – die einzige Seite, auf der ein Kunde steht.
   Sie sieht deshalb nach Brief aus und nicht nach Anwendung: eine schmale
   Spalte auf ruhigem Grund, kein Menü, keine Werkzeugleiste.
   ============================================================ */
.freigabe {
    min-height: 100vh;
    background: var(--flaeche-grau);
    padding: 28px 16px 60px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
}

.freigabe__blatt {
    width: 100%;
    max-width: 820px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    box-shadow: var(--schatten);
    padding: 28px 30px;
}

.freigabe__kopf {
    display: flex;
    gap: 20px;
    justify-content: space-between;
    flex-wrap: wrap;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--rand-zart);
}

.freigabe__firma { font-weight: 700; color: var(--text-stark); font-size: 15px; }

.freigabe__kennfeld { text-align: right; }

.freigabe__klein { font-size: 12px; color: var(--text-schwach); }

.freigabe__titel { font-size: 20px; margin: 18px 0 2px; color: var(--text-stark); }

.freigabe__text { margin: 16px 0; white-space: pre-wrap; line-height: 1.55; }

.freigabe__gruppe { background: var(--flaeche-blass); }

.freigabe__gruppensumme td { border-bottom: 1px solid var(--rand-stark); }

.freigabe__zwischentitel { margin: 22px 0 8px; font-size: 15px; font-weight: 600; color: var(--text-stark); }

/* Der Summenblock rechts, wie auf dem Blatt – der Betrag ist das, wonach zuerst
   gesehen wird. */

.freigabe__zeile { margin-top: 22px; display: flex; gap: 10px; }

.freigabe__knoepfe {
    margin-top: 20px;
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

/* Die Antwort steht bewusst groß da: Wer hier landet, hat eben etwas entschieden
   und soll sehen, dass es angekommen ist. */
.freigabe__antwort { text-align: center; padding: 12px 0; }

.freigabe__antwort h2 { margin: 0 0 10px; color: var(--text-stark); }

.freigabe__antwort p { margin: 0 auto 12px; max-width: 46ch; line-height: 1.55; }

/* Der gezeichnete Schriftzug nach der Zusage – auf Weiß, wie er gezeichnet wurde: Die Tinte ist
   dunkel und hat keinen eigenen Grund, im Dunkeln verschwände sie. */
.freigabe__schriftzug {
    display: block;
    max-width: min(320px, 100%);
    max-height: 110px;
    margin: 8px auto 6px;
    padding: 6px 10px;
    background: #fff;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
}

.freigabe__knoepfe--mitte { justify-content: center; }

/* Widerrufsbelehrung und Datenschutzhinweise: zugeklappt zwischen Angebot und Knopf, damit der
   lange Rechtstext die Entscheidung nicht nach unten schiebt – aufgeklappt mit eigener Rolle. */
.freigabe__belehrung {
    margin: 14px 0 0;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    color: var(--text);
    padding: 10px 14px;
}

.freigabe__belehrung summary { cursor: pointer; font-weight: 600; color: var(--text-stark); }

.freigabe__belehrung .freigabe__text { max-height: 360px; overflow-y: auto; font-size: 13px; margin: 10px 0 4px; }

/* Der Haken zum vorzeitigen Beginn trägt einen ganzen Satz – er bricht um und steht oben bündig. */
.freigabe__verlangen { display: flex; gap: 10px; align-items: flex-start; margin: 14px 0 4px; line-height: 1.5; }

.freigabe__verlangen input { margin-top: 3px; flex: 0 0 auto; }

@media (max-width: 640px) {
    .freigabe__blatt { padding: 20px 16px; }
    .freigabe__kennfeld { text-align: left; }
    .freigabe__knoepfe .knopf { flex: 1 1 100%; justify-content: center; }
}

/* ============================================================
   Plantafel – Zeilen (Mitarbeiter und Betriebsmittel) über Tagesspalten.
   Ein Raster und keine Tabelle: Die Spaltenzahl wechselt mit dem Ausschnitt,
   und eine Kachel soll sich über mehrere Tage ziehen lassen.
   ============================================================ */
.plantafel {
    display: grid;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    overflow-x: auto;
}

.plantafel__kopf {
    display: contents;
}

/* Das Wochenband über den Tagen. Seine Höhe steht **einmal** als Maß da, weil zwei Zeilen sie
   brauchen: das Band klebt bei null, die Tageszeile genau darunter. Ein zweites Mal getippt
   liefen sie beim ersten geänderten Schriftgrad um ein paar Pixel auseinander, und dann
   verdeckte die eine die andere – dieselbe Überlegung wie am Kopfbereich, nur eine Ebene
   tiefer. Die Höhe wird gesetzt und nicht aus dem Inhalt gerechnet, damit das Maß auch gilt. */
.plantafel {
    --plantafel-band: 22px;
}

.plantafel__woche {
    position: sticky;
    top: 0;
    z-index: 2;
    height: var(--plantafel-band);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--flaeche-grau);
    border-bottom: 1px solid var(--rand-zart);
    border-left: 1px solid var(--rand-zart);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    color: var(--text-schwach);
    white-space: nowrap;
}

.plantafel__spalte {
    position: sticky;
    top: var(--plantafel-band);
    z-index: 2;
    padding: 8px 10px;
    background: var(--flaeche-blass);
    border-bottom: 1px solid var(--rand);
    font-size: 12px;
    font-weight: 600;
    color: var(--text-schwach);
    text-align: center;
}

.plantafel__spalte--heute { color: var(--primaer); background: var(--primaer-blass); }

.plantafel__spalte--frei { background: var(--flaeche-grau); }

/* Die Namensspalte bleibt beim Wischen stehen – ohne sie weiß man nach der dritten
   Spalte nicht mehr, wessen Woche man liest. */
.plantafel__name {
    position: sticky;
    left: 0;
    z-index: 1;
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 8px 10px;
    background: var(--flaeche);
    border-bottom: 1px solid var(--rand-zart);
    border-right: 1px solid var(--rand);
    min-width: 190px;
}

.plantafel__name--kopf {
    position: sticky;
    top: var(--plantafel-band);
    z-index: 3;
    background: var(--flaeche-blass);
    border-bottom-color: var(--rand);
}

/* Die leere Ecke links oben über dem Wochenband – sie klebt in beide Richtungen, sonst schöbe
   sich beim Wischen die erste Wochenzelle unter die Namensspalte. */
.plantafel__name--band {
    top: 0;
    z-index: 4;
    height: var(--plantafel-band);
    min-height: var(--plantafel-band);
    padding: 0;
    background: var(--flaeche-grau);
    border-bottom-color: var(--rand-zart);
}

.plantafel__gruppe {
    grid-column: 1 / -1;
    padding: 6px 10px;
    background: var(--flaeche-grau);
    border-bottom: 1px solid var(--rand);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-schwach);
}

.plantafel__nadel {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-size: 11px;
    font-weight: 700;
    color: var(--text-invers);
}

/* Name und Zusatz untereinander. Nebeneinander klebten sie aneinander – „HubsteigerHN-AB 123",
   „Bad Koch26-00011" –, denn beide sind Textelemente ohne Abstand. Aufgefallen ist es erst an
   der Projektzeile; das Kennzeichen eines Betriebsmittels stand genauso da. */
.plantafel__zeilentitel {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.plantafel__zeilenname {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-stark);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.plantafel__zeilenzusatz { font-size: 11px; color: var(--text-schwach); }

/* Der Name einer Baustelle ist ein Sprung ins Projekt – er bleibt aber aussehen wie die
   übrigen Zeilennamen, sonst stünde in der Namensspalte eine blaue Liste neben einer schwarzen. */
a.plantafel__zeilenname { text-decoration: none; }
a.plantafel__zeilenname:hover { text-decoration: underline; }

/* Der Feiertag unter dem Datum. Er darf umbrechen: „Tag der Deutschen Einheit" ist länger als
   eine Spalte, und abgeschnitten hieße er „Tag der Deut…". */
.plantafel__feiertag {
    display: block;
    margin-top: 2px;
    font-size: 10px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--text-gedaempft);
    white-space: normal;
}

.plantafel__zelle {
    min-height: 62px;
    padding: 4px;
    border-bottom: 1px solid var(--rand-zart);
    border-left: 1px solid var(--rand-zart);
    display: flex;
    flex-direction: column;
    gap: 3px;
}

/* Die Kacheln einer Tageszelle: untereinander im Raster „Ganze Tage“, in einem eigenen Gitter
   sonst. Die Spalten setzt die Seite (eine je Abschnitt), die Kachel ihre Lage; „dense“ holt
   eine spätere Kachel neben eine frühere hoch, solange dort Platz ist. */
.plantafel__tagesliste {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.plantafel__tagesraster {
    display: grid;
    grid-auto-flow: row dense;
    gap: 3px;
}

.plantafel__tagesraster .plantafel__kachel { min-width: 0; padding: 3px 4px; }

/* Die Abschnitte unter dem Tag im Kopf – dieselben Spalten wie in der Zelle darunter. */
.plantafel__abschnitte {
    display: grid;
    /* Der Kopf trägt 10 Pixel Innenabstand, die Zelle 4 – ohne den Ausgleich stünden die
       Beschriftungen um ein paar Pixel neben ihren Spalten. */
    margin: 4px -6px 0;
    font-size: 10px;
    font-weight: 500;
    color: var(--text-schwach);
}

.plantafel__abschnitte span {
    border-left: 1px solid var(--rand-zart);
    overflow: hidden;
    white-space: nowrap;
}

.plantafel__abschnitte span:first-child { border-left: 0; }

.plantafel__zelle--frei { background: var(--flaeche-blass); }

.plantafel__zelle--heute { background: var(--primaer-blass); }

.plantafel__zelle--ziel { outline: 2px dashed var(--primaer); outline-offset: -3px; }

/* Warum jemand an dem Tag nicht arbeitet – klein unter den Kacheln. Steht dennoch ein Termin
   darauf, ist das die Auskunft, und dann steht es in der Farbe einer Warnung. */
.plantafel__dienstfrei {
    font-size: 11px;
    color: var(--text-schwach);
    line-height: 1.3;
}

.plantafel__dienstfrei--warnung { color: var(--rot-dunkel); font-weight: 600; }

/* Das Plus einer freien Zelle in Kalender und Plantafel: gestrichelt und leise, damit die Tafel
   nicht nach lauter Knöpfen aussieht – deutlich erst unter dem Zeiger. Auf dem Tablet gibt es
   keinen Zeiger, dort steht es gleich kräftiger (die Fläche wächst ohnehin über
   `pointer: coarse`). */
.zellenplus {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 26px;
    width: 100%;
    padding: 0;
    border: 1px dashed var(--rand);
    border-radius: var(--radius-klein);
    background: transparent;
    color: var(--text-schwach);
    font: inherit;
    cursor: pointer;
    opacity: .55;
    transition: opacity .12s, border-color .12s, color .12s;
}

.zellenplus:hover,
.zellenplus:focus-visible {
    opacity: 1;
    border-color: var(--primaer);
    color: var(--primaer);
}

@media (pointer: coarse) {
    .zellenplus { opacity: .9; }
}

.kalender__zelle--dienstfrei { background: var(--flaeche-blass); }

/* Die Karte beim Überfahren eines Termins (Kalender und Plantafel), nach dem Vorbild ToolTime.
   Fest im Fenster und ohne Maus – der Grund steht an `Terminschaukarte.razor`. */
.terminschau {
    position: fixed;
    z-index: 60;
    /* Klein gehalten: Die Karte liegt über dem Kalender, den man gerade liest, und darf nicht
       mehr von ihm verdecken als nötig – sie ist eine Auskunft im Vorbeigehen, kein Dialog. */
    width: 260px;
    padding: 10px 12px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    box-shadow: var(--schatten-mittel);
    color: var(--text);
    font-size: 12px;
    pointer-events: none;
}

.terminschau__kopf {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 7px;
}

.terminschau__titel {
    min-width: 0;
    color: var(--text-stark);
    font-size: 13px;
    font-weight: 600;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

.terminschau__kopf .abzeichen {
    flex: 0 0 auto;
    height: 18px;
    padding: 0 7px;
    font-size: 10.5px;
}

.terminschau__zeilen {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.terminschau__zeilen li {
    display: flex;
    align-items: flex-start;
    gap: 7px;
    line-height: 1.35;
    overflow-wrap: anywhere;
}

.terminschau__zeichen {
    display: inline-flex;
    flex: 0 0 14px;
    align-items: center;
    justify-content: center;
    height: 16px;
    color: var(--text-schwach);
}

.terminschau__punkt {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.terminschau__leer { color: var(--text-schwach); }

/* Auf Tablet und Telefon gibt es kein Überfahren – ein Antippen löste die Karte aus und öffnete
   im selben Augenblick den Termin. */
@media (pointer: coarse) {
    .terminschau { display: none; }
}

.kalender__frei {
    font-size: 11px;
    color: var(--text-schwach);
}

.plantafel__kachel {
    border-left: 3px solid var(--slate);
    border-radius: var(--radius-klein);
    background: var(--flaeche-blass);
    padding: 3px 6px;
    font-size: 11px;
    line-height: 1.3;
    cursor: pointer;
    text-align: left;
    border-top: 0;
    border-right: 0;
    border-bottom: 0;
    width: 100%;
}

.plantafel__kachel:hover { background: var(--flaeche-grau); }

/* Das Auto in der oberen Ecke: Der Monteur fährt mit dem eigenen Wagen. In der Ecke und nicht in
   der Zeile, weil der Titel dort schon um jedes Zeichen kämpft. */
.plantafel__kachel { position: relative; }
.plantafel__privatwagen {
    position: absolute;
    top: 2px;
    right: 3px;
    color: var(--text-schwach);
    line-height: 0;
}

/* Der Konflikt ist der Grund für die ganze Tafel – er bekommt Grund und Rand, nicht nur
   ein Symbol am Rand, das im Gedränge untergeht. */
.plantafel__kachel--konflikt {
    background: var(--rot-blass);
    box-shadow: inset 0 0 0 1px var(--rot);
}

.plantafel__kachel--sperre { background: var(--slate-blass); font-style: italic; }

.plantafel__kachelzeit { font-weight: 700; color: var(--text-stark); }

.plantafel__kacheltext {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text);
}

/* Ein dünner Balken statt einer Prozentzahl: Auf zwanzig Zeilen liest niemand zwanzig
   Zahlen, aber eine zu volle Zeile sieht man sofort. */
.plantafel__last {
    margin-top: auto;
    height: 3px;
    border-radius: 2px;
    background: var(--rand-zart);
    overflow: hidden;
}

.plantafel__last-balken { height: 100%; background: var(--gruen); }

.plantafel__last-balken--voll { background: var(--gelb); }

.plantafel__last-balken--ueber { background: var(--rot); }

/* ---------- Leistungsverzeichnis ---------- *
   Zwei Zeilenarten, die es sonst nirgends gibt: die Titelzeile der Gliederung und die Zeile,
   auf die ein Befund gerade zeigt. Beide Farben kommen aus den Tokens und nicht als feste
   Werte – im Dunkeln stünde sonst ein heller Streifen quer durch die Tabelle. */

.lv-titel {
    background: var(--flaeche-grau);
    font-weight: 600;
}

.lv-titel:hover { background: var(--flaeche-grau); }

/* Das Dreieck vor dem Titel: Es sagt, dass die Zeile etwas auf- und zuklappt. Es steht in einer
   eigenen Hülle fester Breite, damit die Titel aller Stufen an derselben Kante beginnen – sonst
   wandert die Überschrift beim Umklappen um zwei Pixel, und das sieht nach einem Fehler aus. */
.lv-titel__klappe {
    display: inline-flex;
    width: 16px;
    color: var(--text-schwach);
    vertical-align: -2px;
}

/* Der Stand einer Gruppe. **Zeichen und Wort, nicht nur Farbe** – auf einem Ausdruck und für
   einen Farbenblinden gibt es die Farbe nicht; dieselbe Überlegung wie bei `Befundzahl`. */
.lv-stand {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 10px;
    padding: 1px 8px 1px 6px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    border: 1px solid currentColor;
}

.lv-stand--gut { color: var(--gruen-dunkel); }
.lv-stand--offen { color: var(--gelb-dunkel); }

/* Der Kopf einer einklappbaren Karte ist ein Knopf und sieht trotzdem aus wie eine Überschrift:
   Die Zeile ist das Bedienelement, nicht ein Pfeil daneben von 12 Pixeln. */
.lv-klappe {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 0;
    background: none;
    border: none;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.lv-klappe h3 { margin: 0; }

.lv-klappe > svg { color: var(--text-schwach); flex: 0 0 auto; }

/* ---------- Basiskalkulation des Leistungsverzeichnisses ----------
   Zwei Spalten wie im Kalkulationsblatt: links die Sätze, rechts, was daraus folgt. Per
   Containerabfrage und nicht nach der Fensterbreite: Mit ausgeklappter Menüleiste bliebe bei
   1000 Pixeln Fensterbreite zu wenig für zwei Tabellen nebeneinander. */
.lv-basis { container-type: inline-size; }

.lv-basis__kurz {
    margin-left: auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    font-weight: 400;
    color: var(--text-schwach);
}

.lv-basis__raster {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
}

@container (min-width: 820px) {
    .lv-basis__raster { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* Die Satzfelder behalten ihren Platz: In einer automatischen Tabelle ist eine Spaltenbreite
   nur ein Vorschlag, und ohne Mindestbreite blieben einer Prozentzahl zwei Ziffern. */
table.tabelle.lv-basis__saetze input.feld { min-width: 88px; max-width: 120px; }

/* Hier sind die Felder der Inhalt und nicht Beiwerk einer Liste: Anders als die Preisfelder der
   Positionstabelle, die erst beim Überfahren einen Rand zeigen, stehen die zehn Sätze sichtbar
   als Eingaben da – sonst liest man „0“ und hält es für eine Angabe, nicht für ein Feld. */
table.tabelle.lv-basis__saetze input.feld[type="number"] {
    background: var(--flaeche);
    border-color: var(--rand-stark);
}

.lv-basis__gruende {
    margin: 12px 0 0;
    padding-left: 18px;
    font-size: 12px;
    color: var(--text-schwach);
}

.lv-basis__knoepfe {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

.lv-basis__summe td { border-top: 1px solid var(--rand-stark); font-weight: 600; }

.lv-basis__stand {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    font-size: 13px;
}

.lv-basis__stand li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
    border-bottom: 1px solid var(--rand-zart);
}

.lv-basis__stand li:last-child { border-bottom: none; }

.lv-basis__luecke { color: var(--gelb-dunkel); }

/* Die Aufgliederung im Bepreisen-Dialog – dieselben Spalten wie die Übersicht der Basis. */
.lv-aufgliederung { font-size: 13px; }

/* Was beim Einlesen auffiel – eine Liste im Anliegenband über dem Verzeichnis. */
.lv-hinweise { margin: 6px 0 0; padding-left: 18px; }
.lv-hinweise li + li { margin-top: 4px; }

/* Die Leiste über der Positionstabelle. Sie bricht um, damit auf einem schmalen Gerät die
   Knöpfe unter die Zahl rutschen statt aus dem Bild – dieselbe Falle wie beim Seitenkopf. */
.lv-klappleiste {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 0 2px 10px;
    font-size: 13px;
}

.lv-tabelle__fuss {
    caption-side: bottom;
    padding: 8px 12px 0;
    text-align: left;
    font-size: 12px;
    color: var(--text-schwach);
}

.lv-treffer { background: var(--primaer-blass); }

/* Die Angaben des Auftraggebers im Bepreisungsdialog: lesbar, aber sichtbar nicht zum Ändern. */
.lv-vorgabe {
    background: var(--flaeche-blass);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius-klein);
    padding: 12px 14px;
    margin-bottom: 14px;
}

/* Der Langtext ist Klartext mit Umbrüchen, kein Markup – `pre-wrap` setzt die Absätze, die der
   Leser aus der Datei gezogen hat. So bleibt der Text ein Text und geht nicht als Auszeichnung
   in die Seite. */
.lv-vorgabe .lv-langtext {
    margin-top: 8px;
    font-size: 13px;
    line-height: 1.5;
    white-space: pre-wrap;
    max-height: 260px;
    overflow-y: auto;
}

/* Die Liste der offenen Punkte – je Zeile die Ordnungszahl als Sprung und der Satz dahinter. */
.lv-befunde { list-style: none; margin: 0; padding: 0; }

.lv-befunde li {
    display: flex;
    gap: 10px;
    align-items: baseline;
    padding: 6px 0;
    border-bottom: 1px solid var(--rand-zart);
}

.lv-befunde li:last-child { border-bottom: none; }

.lv-befunde__oz {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    color: var(--primaer);
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    text-decoration: underline;
}

/* ---------- Zugangsprüfung ---------- *
   Das Ergebnis einer Prüfung beim Großhändler: je Zeile eine Stufe, der geprüfte Schritt und
   der Satz dazu. Farben kommen aus den Tokens – im Dunkeln stünde sonst ein heller Kasten. */

.pruefung {
    border: 1px solid var(--rand);
    border-radius: var(--radius-klein);
    background: var(--flaeche-blass);
    padding: 12px 14px;
    margin-top: 10px;
}

.pruefung__kopf {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    font-size: 12px;
}

.pruefung__liste { list-style: none; margin: 0; padding: 0; }

.pruefung__zeile {
    display: flex;
    gap: 10px;
    align-items: baseline;
    padding: 6px 0;
    border-top: 1px solid var(--rand-zart);
    font-size: 13px;
    line-height: 1.5;
}

.pruefung__zeile:first-child { border-top: none; }

/* Fest breit, damit die Sätze daneben auf einer Flucht beginnen. */
.pruefung__stufe {
    flex: 0 0 52px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
}

.pruefung__stufe--fehler { color: var(--rot); }
.pruefung__stufe--hinweis { color: var(--text-schwach); }

.pruefung__schritt {
    flex: 0 0 110px;
    font-weight: 600;
}

@media (max-width: 700px) {
    /* Auf dem Telefon untereinander: Drei Spalten auf 375 Pixeln lassen dem Satz nichts übrig. */
    .pruefung__zeile { flex-wrap: wrap; }
    .pruefung__schritt { flex: 1 1 auto; }
}

/* ---------- Programmstand auf der Übersicht ---------- */
/*
   Eine leise Zeile am Fuß: welcher Stand läuft und ein Weg zu dem, was in ihm neu ist. Sie
   trägt keine Fläche und keinen Rahmen – wäre sie eine Karte, sähe sie aus wie ein Inhalt des
   Tages, und das ist sie nicht.

   Die Farben kommen aus den Token und nicht als feste Werte: Im Dunkeln steht die Zeile sonst
   grau auf grau. Dieselbe Regel wie überall im Stilblatt.
*/
.programmstand {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 8px;
    margin: -6px 0 6px;
    font-size: 11.5px;
    color: var(--text-schwach);
}

/* **Der Knopf trägt hier keine Knopfhöhe.** `knopf--klein` ist 34 Pixel hoch, und damit war er
   das, was diese Zeile hoch machte – eine Fußnote aus Kleinschrift, deren Maß von dem Knopf kam,
   den man am seltensten drückt. Mit 22 Pixeln misst die Zeile nur noch ihre eigene Schrift; der
   Knopf bleibt mit seinem Innenabstand trotzdem groß genug, um ihn zu treffen.

   Er behält Grund und Schriftfarbe aus `knopf--still` – wer einem Bedienelement die Fläche
   nimmt, muss sagen, welche Schrift es trägt, sonst bleibt sie im Dunkeln schwarz. */
.programmstand .knopf {
    height: 22px;
    padding: 0 8px;
    font-size: 11.5px;
    gap: 5px;
}

/* Mit dem Finger bleibt die Trefferfläche groß: Unter `pointer: coarse` gilt im Haus ein
   Mindestmaß von 44 Pixeln für alles Bedienbare, und daran ändert diese Zeile nichts. */
@media (pointer: coarse) {
    .programmstand .knopf { height: 44px; padding: 0 12px; }
}

/* Auf schmalen Geräten links: Rechtsbündig bliebe vom Datum sonst ein Wort je Zeile am
   rechten Rand kleben, und die Zeile läse sich von hinten. */
@media (max-width: 700px) {
    .programmstand { justify-content: flex-start; }
}

/* Die Liste im Dialog: wie die Befundliste des Leistungsverzeichnisses, nur ohne Kennung
   davor – hier hat keine Zeile eine Nummer, an der man sie wiederfindet. */
.standliste {
    list-style: none;
    margin: 4px 0 0;
    padding: 0;
}

.standliste li {
    padding: 5px 0 5px 19px;
    border-bottom: 1px solid var(--rand-zart);
    position: relative;
    color: var(--text);
}

.standliste li:last-child { border-bottom: none; }

/* Ein Punkt statt eines Aufzählungszeichens – er sitzt an der Grundlinie der ersten Zeile und
   rutscht bei einem zweizeiligen Satz nicht mit nach unten. */
.standliste li::before {
    content: "";
    position: absolute;
    left: 6px;
    top: 12px;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--rand-stark);
}

/* ---------- Ein neuer Stand ist da ---------- */
/*
   Das Band steht unter dem Kopfband und über dem Inhalt. Es ist keine Warnung, sondern eine
   gute Nachricht – deshalb der Primärton am Rand und keine Ampelfarbe.

   Es nimmt bewusst die volle Breite: Ein Hinweis, den man übersieht, erspart niemandem die
   Fehlermeldung, die er verhindern soll.
*/
/*
   **Eine Leiste und keine Karte.** Sie stand auf `var(--flaeche)` – derselben Farbe, auf der
   jede Karte dieser Oberfläche steht –, mit Rand und Radius und 13 Pixel Schrift. Damit war sie
   optisch ein weiterer Kasten unter dem Kopf, und einen weiteren Kasten liest niemand: Das Auge
   hat gelernt, dass dort Inhalt steht. Jetzt läuft sie über die **volle Breite**, ohne Radius
   und ohne Rand, in einer Farbe, die sonst nirgends als Fläche vorkommt – das ist der
   Unterschied zwischen „noch etwas auf der Seite" und „die Anwendung sagt etwas".

   Zusammen mit dem Kleben (siehe `.kopfbereich`) sind das die beiden Gründe, aus denen sie
   vorher überlesen wurde: Sie sah aus wie alles andere, und sie war nach dem ersten Scrollen
   weg.
*/
.standmeldung {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 12px 26px;
    background: var(--meldung);
    color: var(--text-invers);

    /* Eine dunkle Kante statt eines Rands ringsum: Die Leiste soll auf der Seite aufliegen,
       nicht auf ihr schwimmen. */
    border-bottom: 1px solid rgba(0, 0, 0, .22);
    font-size: 14px;
    line-height: 1.35;

    /* **Einmal hereinkommen, dann stillstehen.** Bewegung ist das, was ein Auge fängt, das
       gerade woanders auf der Seite ist – und ein neuer Stand meldet sich, während jemand
       arbeitet. Eine Leiste, die weiterblinkt, wird dagegen nach zwei Minuten weggeklickt oder
       gar nicht mehr gesehen; genau deshalb läuft es genau einmal. */
    animation: standmeldung-herein .3s ease-out;
}

@keyframes standmeldung-herein {
    from { transform: translateY(-100%); opacity: 0; }
    to   { transform: translateY(0); opacity: 1; }
}

/* Wer Bewegung abbestellt hat, bekommt sie nicht – die Leiste steht dann sofort da, und das
   genügt auch: Auffällig ist sie durch Farbe und Breite, die Bewegung ist die Zugabe. */
@media (prefers-reduced-motion: reduce) {
    .standmeldung { animation: none; }
}

/* ---------- Sprachleiste (Komponenten/Sprachleiste.razor) ----------
   Ein laufendes Sprachgespräch, im Kopfbereich unter der Standmeldung. Keine Meldungsfarbe: Es
   ist kein Ereignis, sondern ein Zustand, der dauert – aber einer, den man nicht übersehen darf,
   deshalb die farbige Kante links und der Punkt, der atmet, solange gehört oder gesprochen wird. */
.sprachleiste {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 8px 26px;
    background: var(--flaeche);
    color: var(--text);
    border-bottom: 1px solid var(--rand);
    border-left: 4px solid var(--primaer);
    font-size: 14px;
}

.sprachleiste__lage { font-weight: 600; }
.sprachleiste__meldung { color: var(--text-schwach); font-size: 13px; }

.sprachleiste__punkt {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--text-gedaempft);
    flex: 0 0 auto;
}

.sprachleiste--aktiv .sprachleiste__punkt {
    background: var(--gruen);
    animation: sprachleiste-atmen 1.2s ease-in-out infinite;
}

@keyframes sprachleiste-atmen {
    0%, 100% { opacity: 1; }
    50%      { opacity: .35; }
}

@media (prefers-reduced-motion: reduce) {
    .sprachleiste--aktiv .sprachleiste__punkt { animation: none; }
}
.standmeldung strong { margin-right: 4px; }
.standmeldung .standmeldung__zeichen { flex: 0 0 auto; }

/* Der Knopf auf farbigem Grund: `knopf--primaer` wäre Blau auf Blau und verschwände. Er dreht
   die Farben deshalb um – weiße Fläche, Bandfarbe als Schrift –, und er ist nicht mehr der
   kleine: Er ist das, was man tun soll. */
.standmeldung .knopf--neuladen {
    background: var(--text-invers);
    border: 1px solid var(--text-invers);
    color: var(--meldung);
    font-weight: 600;
}

.standmeldung .knopf--neuladen:hover {
    background: color-mix(in srgb, var(--text-invers) 88%, transparent);
}

@media (max-width: 700px) {
    /* Auf dem Telefon rutscht der Knopf unter den Satz – nebeneinander bliebe vom Satz ein
       Wort je Zeile. */
    .standmeldung { align-items: flex-start; padding: 12px 14px; }
    .standmeldung > div { flex-basis: 100%; height: 0; }

    /* **Und der Nachsatz fällt weg.** Gemessen bei 375 Pixeln war die Leiste mit ihm 185 Pixel
       hoch – ein knappes Viertel des Bildschirms, und weil sie klebt, dauerhaft. Was dort
       stehen bleibt, ist die Nachricht („neue Version") und die Handlung (der Knopf); welche
       beiden Nummern sich unterscheiden, braucht der Betrieb nicht, sondern der, der einen
       Fehler sucht. */
    .standmeldung__dazu { display: none; }
}

/* ---------- Bepreisen in der Zeile ---------- */
/*
   Der Einheitspreis und der Nachlass stehen als Feld in der Tabelle: Ein Leistungsverzeichnis
   wird der Reihe nach bepreist, und vierhundert Dialoge sind ein Nachmittag statt einer Stunde.

   Die Felder sind schmal und randlos, solange niemand darin steht – eine Tabelle voller
   Eingabekästen liest sich nicht mehr als Tabelle. Erst beim Hineingehen bekommen sie ihren
   Rahmen.
*/
.lv-feld {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 4px 6px;
}

/* Das Abzeichen „offen“ steht neben dem Preisfeld – und nahm ihm genau in den Zeilen den Platz,
   in die man tippt: bei 1024 Pixeln blieben dem Preis 25 Pixel. Mit Mindestbreite und Umbruch
   rutscht das Abzeichen bei Platzmangel unter das Feld, statt es schmaler zu machen. */
/* So spezifisch wie die Regel für alle Zahlenfelder der Tabelle weiter unten – die setzt
   `width: 100%`, und damit stand das Feld immer allein in der Zeile und das Abzeichen darunter. */
table.tabelle .lv-feld input.feld[type="number"] { width: auto; flex: 1 1 72px; min-width: 72px; }
table.tabelle input.lv-nachlass { min-width: 56px; }
table.tabelle input.lv-minuten { min-width: 64px; }

table.tabelle input.feld[type="number"] {
    height: 28px;
    padding: 0 6px;
    font-size: 13px;
    background: transparent;
    border-color: transparent;
    width: 100%;
    min-width: 0;
}

table.tabelle input.feld[type="number"]:hover {
    border-color: var(--rand);
}

table.tabelle input.feld[type="number"]:focus {
    background: var(--flaeche);
    border-color: var(--primaer);
}

/* ---------- Zahlenfelder in Tabellen: ohne Pfeiltasten ----------
   Der Browser blendet beim Hineingehen zwei Pfeile ein, rund 15 Pixel breit – in einer Zelle
   von 80 Pixeln war danach „12500.25“ nicht mehr ganz zu sehen, und zwar genau beim Tippen.
   Bei Schritten von 0,01 nützen die Pfeile ohnehin nichts. */
table.tabelle input.feld[type="number"],
table.positionen input.feld[type="number"],
input.feld.feld--zahl {
    -moz-appearance: textfield;
    appearance: textfield;
}

table.tabelle input.feld[type="number"]::-webkit-inner-spin-button,
table.tabelle input.feld[type="number"]::-webkit-outer-spin-button,
table.positionen input.feld[type="number"]::-webkit-inner-spin-button,
table.positionen input.feld[type="number"]::-webkit-outer-spin-button,
input.feld.feld--zahl::-webkit-inner-spin-button,
input.feld.feld--zahl::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* `feld--zahl` trägt dieselbe Regel außerhalb von Tabellen – an Mengen und Preisen im Lager und
   an den Kilometern der Betriebsmittel. Dort wird eine Zahl abgelesen und getippt, nicht in
   Schritten von eins geklickt, und ein Pfeil unter dem Daumen ändert sie beim Rollen der Seite. */

/* ---------- Positionstabelle (Angebot, Rechnung) ----------
   Die Felder trugen den Innenabstand eines Formularfeldes (13 Pixel je Seite) – in einer
   Tabellenzelle sind das 26 Pixel, die der Zahl fehlen. Und ohne Mindestbreite drückte ein
   schmales Fenster die Zahlenspalten zusammen, bis beim Einkaufspreis gemessen 0 Pixel Text
   übrig blieben. Jetzt behält jede Zahl ihren Platz; wird es zu eng, rollt die Tabelle
   waagerecht (die Hülle kann das), und schmaler wird nur die Bezeichnung. */
table.positionen input.feld[type="number"] { padding: 0 6px; }
table.positionen input.positionen__menge { min-width: 76px; }
table.positionen input.positionen__betrag { min-width: 84px; }
/* Der Steuersatz ist eine Auswahl: „19 %“ passt in jede Spalte, „0 % § 13b“ braucht den Platz
   für Text und Pfeil. Längere Namen kürzt das Feld; der ganze steht am title. */
table.positionen select.positionen__satz { min-width: 122px; padding-left: 6px; padding-right: 22px; }
table.positionen td.positionen__bezeichnung { min-width: 220px; }

/* Solange der Server antwortet, bleibt die Zeile blass – aber sie bleibt stehen. Sie
   auszublenden oder zu sperren nähme dem Tippenden die nächste Zeile weg. */
.lv-zeile--speichert { opacity: .55; }

.lv-zeilenfehler td {
    padding-top: 0;
    color: var(--rot);
    font-size: 12px;
}

/* ---------- Wetter an der Baustelle ---------- */
/* Die Tage stehen als Reihe nebeneinander und brechen um, statt zu scrollen: Eine Kachel, in
   der man waagerecht wischen muss, verdeckt genau die Tage, wegen derer man hinsieht.

   **Die Kachel richtet sich nach ihrer eigenen Breite, nicht nach der des Fensters.** Auf der
   Übersicht steht sie in der schmalen Werkzeugspalte, die auf jedem Bildschirm schmal ist – eine
   `@media`-Regel fragte das Fenster und bekäme dort die falsche Antwort. Mit `container-type`
   trägt dieselbe Kachel beides: breit nebeneinander, schmal untereinander. */
.wetter { container-type: inline-size; }

/* In der Spalte wird der Innenabstand knapper – 18 Pixel ringsum sind auf 420 Pixel Breite ein
   Zehntel der Fläche. */
@container (max-width: 560px) {
    .wetter .karte__koerper { padding: 14px 15px; }
}

.wetter__ort {
    font-size: 12px;
    color: var(--text-schwach);
    margin-bottom: 10px;
}

/* Der Abstand steht hier und nicht als Leerzeichen im Markup: Razor entfernt den Zwischenraum
   vor einem `@if`, und die Zeile las sich als „Heilbronn· 1 km entfernt". Ein `&#160;` täte es
   auch und wäre ein unsichtbares Zeichen im Text – der Abstand ist Gestaltung. */
.wetter__fern { color: var(--text-schwach); margin-left: .28em; }

.wetter__tage {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* Ein `button` und kein `div`, weil ein Klick den Tag nach vorn in die große Anzeige holt – ein
   anklickbares `div` findet keine Tastatur wieder. Grund, Rand und Schriftfarbe müssen dabei
   ausdrücklich stehen: Ein Browser malt den Text eines Knopfes von sich aus schwarz und in
   seiner eigenen Schrift, und genau daran ist in diesem Haus schon einmal eine Zeile im Dunkeln
   unlesbar geworden. */
.wetter__tag {
    flex: 1 1 78px;
    min-width: 78px;
    padding: 8px 6px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    text-align: center;
    background: var(--flaeche-blass);
    font: inherit;
    color: var(--text);
    cursor: pointer;
    transition: border-color .14s ease, transform .14s ease, background .14s ease;
}

.wetter__tag:hover { border-color: var(--rand-stark); transform: translateY(-2px); }

/* Der Tag mit einem Hinweis bekommt einen kräftigeren Rand und keine eigene Fläche: Eine
   gelbe Kachel neben sechs blassen liest sich als Warnung, und das ist es nicht – es ist ein
   Tag, an dem etwas zu bedenken ist. */
.wetter__tag--auffaellig { border-color: var(--rand-staerker); }

/* **Der gewählte Tag bleibt in der Reihe stehen und wird markiert.** Ihn herauszunehmen war der
   erste Entwurf – er steht ja groß daneben –, und am Bildschirm war es falsch: Die Reihe hatte
   dann bei jedem Klick eine andere Besetzung und rückte unter dem Zeiger weg, während man den
   nächsten Tag ansehen wollte. Die Doppelung ist der Preis und sie ist zu erklären: Die kleine
   Zeile ist der **Schalter**, die große Fläche die **Auskunft**. */
.wetter__tag--gewaehlt {
    border-color: var(--primaer);
    background: var(--primaer-blass);
    box-shadow: inset 0 0 0 1px var(--primaer);
}

/* ---------- Der gewählte Tag groß ----------
   Sieben gleich große Kacheln beantworten die Frage nicht, die gestellt wird. Gefragt wird
   zuerst „wie ist es jetzt", und erst danach „hält das die Woche". */
.wetter__band {
    display: grid;
    grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
    gap: 16px;
    align-items: stretch;
}

.wetter__heute {
    position: relative;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px 18px;
    border: 1px solid var(--rand);
    border-radius: var(--radius-gross);
    background: var(--flaeche-blass);
    overflow: hidden;
}

/* Der Hof hinter dem Sinnbild. Er ist aus den Statustoken gemischt und nicht aus festen Werten –
   dieselbe Überlegung wie bei den Rändern der Abzeichen; ein eigener Ton wäre die Stelle, an der
   im Dunkeln wieder etwas leuchtet, das nicht leuchten soll.

   Er **atmet**, und das ist die einzige Dauerbewegung dieses Bildschirms: neun Sekunden je Zug,
   also langsamer als jeder Blick. Die verworfene Alternative war, das Sinnbild selbst zu bewegen
   (drehende Sonne, fallende Tropfen) – das hätte für jede Wetterart eine eigene Zeichnung
   gebraucht und `Symbol.razor` zu einer Animationsbibliothek gemacht. */
.wetter__heute-bild {
    position: relative;
    flex: 0 0 auto;
    color: var(--text);
    line-height: 0;
}

.wetter__heute-bild::before {
    content: "";
    position: absolute;
    inset: -30px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--hof, transparent) 0%, transparent 70%);
    animation: wetter-atmen 9s ease-in-out infinite;
}

.wetter__heute-bild svg { position: relative; }

@keyframes wetter-atmen {
    0%, 100% { transform: scale(1);   opacity: .7; }
    50%      { transform: scale(1.1); opacity: 1; }
}

.wetter__heute[data-art="wetter-klar"],
.wetter__heute[data-art="wetter-heiter"]   { --hof: color-mix(in srgb, var(--gelb) 34%, transparent); }
.wetter__heute[data-art="wetter-regen"],
.wetter__heute[data-art="wetter-schauer"]  { --hof: color-mix(in srgb, var(--primaer) 30%, transparent); }
.wetter__heute[data-art="wetter-schnee"],
.wetter__heute[data-art="wetter-nebel"]    { --hof: color-mix(in srgb, var(--slate) 30%, transparent); }
/* Gewitter in Rot und nicht in der Hausfarbe: Die war bis 2026.10.20 ein Orange und damit von
   selbst eine Warnfarbe; als Blau stünde der Hof eines Gewitters wie der eines Regens da. */
.wetter__heute[data-art="wetter-gewitter"] { --hof: color-mix(in srgb, var(--rot) 30%, transparent); }
.wetter__heute[data-art="wetter-bewoelkt"] { --hof: color-mix(in srgb, var(--slate) 22%, transparent); }

.wetter__heute-tag {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-schwach);
}

.wetter__heute-grad {
    font-size: 38px;
    font-weight: 600;
    line-height: 1.05;
    letter-spacing: -.03em;
    color: var(--text-stark);
    font-variant-numeric: tabular-nums;
}

.wetter__heute-grad span {
    font-size: 17px;
    font-weight: 500;
    color: var(--text-schwach);
    margin-left: 6px;
}

.wetter__heute-wort { font-size: 14px; color: var(--text); margin-top: 2px; }
.wetter__heute-zusatz { font-size: 12px; color: var(--text-schwach); margin-top: 5px; }

/* ---------- In der schmalen Spalte werden aus den Kacheln Zeilen ----------
   Ein Raster war der erste Entwurf und ging nicht auf: Sieben Tage in drei Spalten sind drei,
   drei und einer – die letzte Zeile steht zu zwei Dritteln leer, und der Blick sucht dort den
   Fehler. Vier Spalten ergeben vier und drei, also dasselbe eine Feld zu wenig.

   Eine Liste hat das Problem nicht, und sie ist in einer schmalen Spalte ohnehin die natürlichere
   Form: Wochentag, Sinnbild, Wort, Regen, Temperatur – fünf Angaben, die untereinander eine
   Spalte bilden, statt in einer Kachel übereinanderzustehen. */
@container (max-width: 560px) {
    .wetter__band { grid-template-columns: minmax(0, 1fr); gap: 10px; }
    .wetter__heute { padding: 12px 14px; gap: 13px; }
    .wetter__heute-grad { font-size: 30px; }
    .wetter__heute-zusatz { margin-top: 3px; }
    .wetter__hinweis { margin-top: 6px; }

    .wetter__tage { display: flex; flex-direction: column; gap: 2px; }

    /* **`flex: 0 0 auto` ist hier die tragende Zeile und sieht nach keiner aus.** Oben steht am
       Tag `flex: 1 1 78px` – gedacht als *Breite* einer Kachel in einer liegenden Reihe. Sobald
       die Reihe steht, ist dieselbe Zahl die **Höhe**, und jede Listenzeile wurde 78 Pixel hoch:
       die Kachel 968 statt 628 Pixel, ohne dass eine Regel falsch gewesen wäre. */
    .wetter__tag {
        display: grid;
        grid-template-columns: 42px 26px minmax(0, 1fr) auto auto;
        align-items: center;
        gap: 0 10px;
        text-align: left;
        padding: 4px 10px;
        flex: 0 0 auto;
        min-width: 0;
    }

    /* Der Rand zwischen den Zeilen fällt weg – sieben umrandete Kästchen untereinander sind ein
       Gitter, keine Liste. Es genügt der Wechsel des Grundes beim Überfahren und die Markierung
       des gewählten Tages. */
    .wetter__tag { border-color: transparent; background: none; }
    .wetter__tag--auffaellig { border-color: var(--rand); }
    .wetter__tag--gewaehlt { box-shadow: none; }

    /* **`grid-row: 1` gehört überall dazu.** Mit der Spalte allein setzt das Auto-Placement
       jedes Kind in eine eigene Reihe, sobald eine Spalte zurückspringt – die Zeile wurde 56
       statt 40 Pixel hoch, und die Liste sah aus, als sei sie großzügig gesetzt. Gemessen war
       sie zweireihig.

       Der Niederschlag rückt dabei vor die Temperatur, damit die Gradzahlen ganz rechts eine
       Spalte bilden – sie sind das, was man von oben nach unten vergleicht. Im Markup steht er
       dahinter; die Reihenfolge macht das Raster. */
    .wetter__tag .wetter__wochentag { grid-column: 1; grid-row: 1; }
    .wetter__tag .wetter__bild { grid-column: 2; grid-row: 1; margin: 0; }
    .wetter__tag .wetter__wort { grid-column: 3; grid-row: 1; margin: 0; }
    .wetter__tag .wetter__nass { grid-column: 4; grid-row: 1; margin: 0; }
    .wetter__tag .wetter__grade { grid-column: 5; grid-row: 1; white-space: nowrap; }
    .wetter__tag .wetter__grade strong { font-size: 14px; }
    .wetter__tag .wetter__bild svg { width: 22px; height: 22px; }

    /* Beim Überfahren hebt sich in einer Liste nichts – das Verrücken einer Zeile verschiebt die
       Nachbarn optisch mit. Es genügt der Grund. */
    .wetter__tag:hover { transform: none; background: var(--flaeche-grau); }
}

/* ---------- Die gedrängte Fassung für die Kennzahlenzeile ----------
   Dort steht das Wetter neben „Zeit heute" und hat deshalb die Höhe einer Kennzahl und nicht die
   einer Spaltenkachel.

   **Sie steht hinter der Container-Regel und hebt sie auf**, und das ist kein Zufall der
   Reihenfolge: In der Zahlenzeile ist die Kachel zwar schmal, aber eine Liste aus sieben Zeilen
   wäre dort dreimal so hoch wie ihre Nachbarn. Die Breite allein ist hier also die falsche
   Frage – entschieden wird am Ort, und den kennt nur die Seite.

   **Was wegfällt, ist begründet:** Der gewählte Tag behält Sinnbild, Temperatur und Wort; die
   übrigen tragen nur Wochentag, Sinnbild und Höchstwert. Wort, Tiefstwert und Niederschlag sind
   in einer 40 Pixel schmalen Spalte keine Auskunft mehr, sondern Kleinschrift – wer es genau
   wissen will, klickt den Tag an und liest es groß. */
.wetter--zeile .karte__kopf { padding: 11px 14px; }
.wetter--zeile .karte__koerper { padding: 12px 14px; }
.wetter--zeile .wetter__ort { margin-bottom: 8px; }

.wetter--zeile .wetter__band {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 9px;
}

.wetter--zeile .wetter__heute {
    padding: 9px 12px;
    gap: 11px;
    border-radius: var(--radius);
}

.wetter--zeile .wetter__heute-bild svg { width: 40px; height: 40px; }
.wetter--zeile .wetter__heute-bild::before { inset: -18px; }
.wetter--zeile .wetter__heute-grad { font-size: 25px; }
.wetter--zeile .wetter__heute-grad span { font-size: 13px; margin-left: 4px; }
.wetter--zeile .wetter__heute-wort { font-size: 12.5px; margin-top: 1px; }

/* Der Zusatz – Regen und Böe – steht schon in der Zeile darüber als Zahl am Tag. In der
   gedrängten Fassung wäre er eine vierte Textzeile auf engstem Raum. */
.wetter--zeile .wetter__heute-zusatz { display: none; }

/* Zurück in die liegende Reihe: sieben schmale Spalten, gleich breit, ohne Umbruch. */
.wetter--zeile .wetter__tage {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 3px;
}

.wetter--zeile .wetter__tag {
    display: block;
    padding: 5px 2px;
    text-align: center;
    min-width: 0;
    border-color: transparent;
    background: none;
}

.wetter--zeile .wetter__tag--auffaellig { border-color: var(--rand); }
.wetter--zeile .wetter__tag:hover { transform: none; background: var(--flaeche-grau); }

.wetter--zeile .wetter__tag--gewaehlt {
    background: var(--primaer-blass);
    border-color: var(--primaer);
    box-shadow: none;
}

.wetter--zeile .wetter__wochentag { font-size: 9.5px; letter-spacing: 0; }
.wetter--zeile .wetter__bild { margin: 2px 0 0; }
.wetter--zeile .wetter__bild svg { width: 18px; height: 18px; }
.wetter--zeile .wetter__grade strong { font-size: 12px; }

/* Wort, Tiefstwert und Niederschlag: siehe oben. */
.wetter--zeile .wetter__wort,
.wetter--zeile .wetter__nass,
.wetter--zeile .wetter__grade span { display: none; }

/* Die Hinweise bleiben – sie sind der Grund, warum die Kachel überhaupt dasteht. Gekürzt auf
   eine Zeile je Hinweis: Was nicht hineinpasst, liest man im Tag, den man anklickt. */
.wetter--zeile .wetter__hinweis {
    margin-top: 6px;
    font-size: 12px;
    padding: 6px 9px;
}

.wetter--zeile .wetter__quelle { margin-top: 8px; font-size: 10px; }

.wetter__wochentag {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-schwach);
}

.wetter__wort {
    font-size: 12px;
    margin: 3px 0 5px;
    color: var(--text);
}

.wetter__grade strong {
    font-size: 16px;
    color: var(--text);
}

.wetter__grade span {
    font-size: 13px;
    color: var(--text-schwach);
    margin-left: 4px;
}

.wetter__nass {
    margin-top: 3px;
    font-size: 11px;
    color: var(--primaer);
}

.wetter__hinweis { margin-top: 8px; }

.wetter__quelle {
    margin-top: 10px;
    font-size: 11px;
    line-height: 1.5;
    color: var(--text-schwach);
}

/* Das Sinnbild nimmt die Farbe der Zeile an (currentColor im Symbol) und bleibt damit in beiden
   Farbwelten richtig – ein eigener Ton wäre die Stelle, an der im Dunkeln wieder etwas
   verschwindet. Bei Regen und Schnee färbt es sich mit, weil dort etwas zu bedenken ist. */
.wetter__bild {
    margin: 4px 0 1px;
    color: var(--text-schwach);
    line-height: 0;
}

.wetter__tag--auffaellig .wetter__bild { color: var(--primaer); }

/* ---------- Die Reiter der Suchleiste ---------- */
/* Sie brechen um statt zu scrollen: Sieben Wörter passen auf einem Telefon nicht in eine Zeile,
   und ein Reiterband, in dem man waagerecht wischen muss, verdeckt genau den Reiter, den man
   sucht. */
.suchleiste__reiter {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--rand);
}

/* `font: inherit` und `color` gehören beide dazu – ein Knopf erbt weder die Schrift noch die
   Farbe, und der Browser malt ihn von sich aus schwarz in Arial. Im Hellen fällt das nicht auf,
   im Dunkeln steht es schwarz auf dunkelblau; genau diese Stelle ist in dieser Leiste schon
   einmal gemeldet worden. */
.suchleiste__reiter-knopf {
    font: inherit;
    font-size: 12px;
    color: var(--text-schwach);
    background: none;
    border: 0;
    border-radius: 999px;
    padding: 4px 10px;
    cursor: pointer;
}

.suchleiste__reiter-knopf:hover { background: var(--flaeche-blass); color: var(--text); }

/* Der gewählte Reiter trägt Fläche und kräftigere Schrift – nicht nur eine andere Farbe: Wer
   farbenblind ist, sähe sonst nicht, welcher gilt.

   **Die Schrift ist `--text` und nicht `--primaer-dunkel`, und das ist gemessen.** Blau auf der
   blassen blauen Fläche liest sich im Hellen mit 4,51 : 1 gerade noch; im Dunkeln waren es
   **3,52 : 1** – zu wenig für zwölf Pixel, und ausgerechnet an dem einen Reiter, der lesbar sein
   muss, weil er sagt, wonach gerade gesucht wird. Der Grund ist derselbe, der auch an
   `.suchleiste__quelle` steht: `--primaer-dunkel` trägt zwei Rollen – im Hellen ist es das
   dunklere Blau für Schrift, im Dunkeln das aufgehellte für Flächen –, und die zweite trägt
   keine Schrift. Mit `--text` sind es 8,85 (hell) und 9,79 (dunkel). Die Fläche bleibt blau
   getönt; sie und das Schriftgewicht sagen ohnehin, welcher Reiter gilt. */
.suchleiste__reiter-knopf.aktiv {
    background: var(--primaer-blass);
    color: var(--text);
    font-weight: 600;
}

/* ---------- Farbwahl aus der Farbtabelle ----------
   Das Muster steht links vom Feld, damit man die Farbe sieht, bevor man ihren Namen liest. Es
   trägt einen Rand, weil Weiß auf der hellen Fläche sonst verschwände. */

.farbtonfeld { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.farbtonfeld .feld { flex: 1 1 160px; min-width: 0; }

.farbtonfeld__muster {
    flex: 0 0 auto;
    display: inline-block;
    width: 22px;
    height: 22px;
    border-radius: var(--radius-klein);
    border: 1px solid var(--rand-stark);
    background: repeating-linear-gradient(45deg, transparent 0 4px, var(--rand) 4px 5px);
}

.farbtonfeld__waehler {
    flex: 0 0 auto;
    width: 44px;
    height: 36px;
    padding: 2px;
    border: 1px solid var(--rand);
    border-radius: var(--radius-klein);
    background: var(--flaeche);
}

.farbmarke {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    color: var(--text-schwach);
}

.farbmarke .farbtonfeld__muster { width: 14px; height: 14px; }

/* Der Preis samt heutigem Kupferzuschlag unter dem Katalogpreis. Kleiner und blasser, denn
   der Katalogpreis bleibt die gespeicherte Angabe; ohne Umbruch, sonst stünde der Betrag in
   der 120 Pixel schmalen Preisspalte allein in einer zweiten Zeile. */
.katalog__zuschlag {
    font-size: 11px;
    font-weight: 400;
    white-space: nowrap;
    margin-top: 2px;
}

/* Die EAN unter der Artikelnummer. Ziffern gleicher Breite, damit dreizehn Stellen
   untereinander lesbar bleiben; ohne Umbruch – eine halbe EAN in der zweiten Zeile sucht
   niemand wieder. */
.katalog__ean {
    font-size: 11px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    margin-top: 2px;
}

/* Wartungsvertrag: die technischen Felder der Grundart in einem Raster, das auf dem Telefon
   einspaltig wird – sieben Felder untereinander in voller Breite wären auf dem Rechner eine
   halbe Bildschirmhöhe Leerraum rechts. */
.technikraster {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0 16px;
    margin-top: 4px;
}

.vertragsstand {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
}

.anhangliste {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 10px;
}

.anhangliste__zeile {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Ein entkleideter Knopf – Schrift und Farbe gehören dazu, sonst schwarz auf dunkel. */
.anhangliste__datei {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    background: var(--flaeche);
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.anhangliste__datei:hover { border-color: var(--rand-stark); }

.anhangliste__datei > span:nth-of-type(2) {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.anhangliste__art {
    font-weight: 600;
    white-space: nowrap;
}

/* Der einmal angezeigte Unterschriftslink: Feld und Knopf in einer Zeile, auf dem Telefon untereinander. */
.linkfeld {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.linkfeld .feld {
    flex: 1 1 260px;
    min-width: 0;
}

/* Der QR-Code des Unterschriftslinks: fester weißer Grund, weil eine Kamera einen Code auf dunklem
   Grund nicht liest – dieselbe begründete Ausnahme wie an der App-Code-Tafel. */
.linkqr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    margin-bottom: 10px;
}

.linkqr img {
    width: 180px;
    height: 180px;
    padding: 8px;
    background: #fff;
    border-radius: var(--radius-klein);
    image-rendering: pixelated;
}

/* ---------- Spaltenwahl über langen Listen ----------
   Dieselbe Bauart wie das Benutzermenü: ein Schleier fängt den Klick daneben, die Tafel hängt
   unter dem Knopf. Rechtsbündig, weil der Knopf rechts im Werkzeugblock steht. */
.spaltenwahl {
    position: relative;
    flex: 0 0 auto;
}

.spaltenwahl__schleier {
    position: fixed;
    inset: 0;
    z-index: 45;
}

.spaltenwahl__tafel {
    position: absolute;
    z-index: 50;
    top: calc(100% + 6px);
    right: 0;
    min-width: 230px;
    padding: 6px;
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    box-shadow: var(--schatten-hoch);
}

.spaltenwahl__zeile {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 10px;
    border-radius: var(--radius-klein);
    font-size: 13.5px;
    color: var(--text);
    cursor: pointer;
}

.spaltenwahl__zeile:hover { background: var(--flaeche-blass); }

.spaltenwahl__zeile--fest { cursor: default; color: var(--text-schwach); }

.spaltenwahl__fest {
    margin-left: auto;
    font-size: 11.5px;
    color: var(--text-schwach);
}

.spaltenwahl__zurueck {
    width: 100%;
    margin-top: 4px;
    padding: 8px 10px;
    background: none;
    border: 0;
    border-top: 1px solid var(--rand);
    font: inherit;
    font-size: 13px;
    color: var(--primaer);
    text-align: left;
    cursor: pointer;
}

.spaltenwahl__zurueck:disabled { color: var(--text-schwach); cursor: default; }

/* ---------- Formelvorlage in der Mengenermittlung ---------- */
.formelvorlage {
    margin-top: 12px;
    padding: 12px 14px;
    background: var(--flaeche-blass);
    border: 1px solid var(--rand);
    border-radius: var(--radius-klein);
}

.formelvorlage__kopf {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 8px;
    font-size: 13.5px;
}

/* ---------- Arbeitsplan am Mitarbeiter ----------
   Eine Tafel aus fünf Spalten und nicht fünf feld-reihen: Die Tage sollen untereinander stehen,
   damit man die Uhrzeiten der Woche mit einem Blick vergleicht. */
.arbeitsplan {
    margin-top: 18px;
    padding-top: 14px;
    border-top: 1px solid var(--rand);
}

.arbeitsplan__tafel {
    display: grid;
    grid-template-columns: minmax(118px, 1.3fr) minmax(92px, 1fr) minmax(92px, 1fr) minmax(76px, .8fr) minmax(56px, auto);
    gap: 6px 8px;
    align-items: center;
    margin-top: 10px;
    overflow-x: auto;
}

.arbeitsplan__kopf {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-schwach);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.arbeitsplan__tag {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
    color: var(--text);
}

.arbeitsplan__frei {
    grid-column: span 4;
    font-size: 12.5px;
    color: var(--text-schwach);
}

.arbeitsplan__summe {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-size: 13px;
}

.arbeitsplan__verlauf {
    margin: 4px 0 0;
    padding-left: 18px;
    font-size: 12.5px;
    color: var(--text-schwach);
}

/* Im Reiter der Teammaske ist der Plan ein Block wie die anderen – mit Überschrift und ohne die
   Trennlinie, die er als Anhängsel einer langen Spalte brauchte. */
.arbeitsplan.arbeitsplan--block {
    margin-top: 10px;
    padding-top: 0;
    border-top: none;
}

/* ---------- Teamliste ---------- */

.team-liste__person {
    display: inline-flex;
    align-items: center;
    gap: 10px;
}

/* Die zweite Zeile einer Zelle – Beruf, Telefon, Reichweite, Wochentage. Blass und klein, damit
   die erste Zeile die Zeile bleibt, an der man den Mitarbeiter erkennt. */
.team-liste__zusatz {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--text-schwach);
}

.team-liste__kontakt {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 250px;
}

/* Ausgeschiedene bleiben in der Liste – an ihnen hängen Zeiten und Belege –, treten aber zurück.
   Blass an den Zellen und nicht an der Zeile: Die Zeile trägt den Mauszeiger-Hintergrund. */
.team-liste__inaktiv > td { opacity: .55; }

/* Die Kalenderfarbe als Punkte zum Anklicken. Eine Farbe erkennt man am Sehen – in der
   Klappliste stand „Rosé“ und „Orange“, und man musste raten, wie es im Kalender aussieht. */
.team-farben {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.team-farben__wahl {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 2px solid transparent;
    border-radius: 50%;
    background: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.team-farben__wahl:hover { border-color: var(--rand-stark); }
.team-farben__wahl.aktiv { border-color: var(--text); }
.team-farben__wahl:focus-visible { outline: 2px solid var(--primaer); outline-offset: 2px; }

.team-farben__punkt {
    width: 22px;
    height: 22px;
    border-radius: 50%;
}

/* ---------- Telefonassistent ---------- */

/* Der Hinweis „nicht eingeschaltet“ steht als Karte mit Zeichen und nicht als Fehlerband: Ein
   ausgeschalteter Assistent ist kein Fehler, sondern ein Angebot. */
.telefon-hinweis .karte__koerper {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}

.telefon-hinweis .karte__koerper > svg {
    flex: 0 0 auto;
    color: var(--primaer);
}

.telefon-hinweis p {
    margin: 6px 0 12px;
    color: var(--text-gedaempft);
}

/* Das Anliegen ist Fließtext eines Anrufers – drei Zeilen in der Liste, der Rest im Dialog. */
.telefon-anliegen {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-width: 200px;
}

.telefon-zusammenfassung {
    display: grid;
    grid-template-columns: minmax(110px, max-content) minmax(0, 1fr);
    gap: 6px 16px;
    margin: 0 0 12px;
}

.telefon-zusammenfassung dt {
    color: var(--text-schwach);
}

.telefon-zusammenfassung dd {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.telefon-wege {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* ---------- Rückmeldungen aus dem Benutzermenü ---------- */

.rueckmeldung-vorschau {
    display: grid;
    grid-template-columns: minmax(110px, max-content) minmax(0, 1fr);
    gap: 4px 16px;
    margin: 0;
    padding: 12px;
    border: 1px solid var(--rand);
    border-radius: var(--radius, 8px);
    font-size: 13px;
}

.rueckmeldung-vorschau dt {
    color: var(--text-schwach);
}

.rueckmeldung-vorschau dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.rueckmeldung-text {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    margin: 0 0 12px;
}
/* ---------- Angebot abrechnen (Pages/AngebotAbrechnen.razor) ----------
   Links die Wahl, rechts, was zum Angebot schon gestellt ist – nebeneinander, weil gerade das
   Nebeneinander der Sinn ist. `minmax(0, 1fr)` und nicht `1fr`, sonst schiebt ein langer
   Positionsname die Spalte über den Rand.
   **Umgebrochen wird nach der Breite der Hülle und nicht des Fensters**: Die Menüleiste nimmt
   232 oder 60 Pixel, und bei 976 Pixeln Fensterbreite blieben der Wahl mit einer Media-Regel
   gemessen 318 Pixel – zu schmal für Erklärung und Positionsnamen. */
.abrechnung-huelle { container-type: inline-size; }

.abrechnung {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 20px;
    align-items: start;
}

@container (max-width: 860px) {
    .abrechnung { grid-template-columns: minmax(0, 1fr); }
}

.abrechnung__haupt {
    background: var(--flaeche);
    border: 1px solid var(--rand);
    border-radius: var(--radius);
}

.abrechnung__schritt {
    display: flex;
    gap: 14px;
    padding: 18px 20px;
}

.abrechnung__schritt + .abrechnung__schritt { border-top: 1px solid var(--rand); }

.abrechnung__nummer {
    flex: 0 0 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--primaer-blass);
    color: var(--text-stark);
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
}

.abrechnung__inhalt { flex: 1 1 auto; min-width: 0; }
.abrechnung__inhalt h3 { margin: 3px 0 4px; font-size: 16px; }

.abrechnung__wahlen {
    display: grid;
    gap: 8px;
    margin-top: 12px;
}

.abrechnung__wahl {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 10px 12px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
    cursor: pointer;
}

.abrechnung__wahl input { margin-top: 3px; }
.abrechnung__wahl--aktiv { border-color: var(--primaer); background: var(--primaer-blass); }

.abrechnung__erklaerung {
    display: block;
    margin-top: 2px;
    font-size: 13px;
    color: var(--text-schwach);
}

.abrechnung__tafel { margin-top: 14px; }

.abrechnung__zeile {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 6px 0;
    min-width: 0;
}

.abrechnung__zeile > :last-child { text-align: right; white-space: nowrap; }

.abrechnung__zeile--summe {
    margin-top: 6px;
    padding: 10px 12px;
    border-radius: var(--radius);
    background: var(--flaeche-blass);
    font-weight: 600;
    color: var(--text-stark);
}

.abrechnung__hoehe { display: flex; gap: 6px; }
.abrechnung__hoehe input { width: 120px; text-align: right; }
.abrechnung__hoehe select { width: 64px; }
.abrechnung__bezeichnung { max-width: 260px; }

.abrechnung__positionskopf {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
}

.abrechnung__positionen {
    margin-top: 8px;
    border: 1px solid var(--rand);
    border-radius: var(--radius);
}

.abrechnung__position {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    cursor: pointer;
}

.abrechnung__position + .abrechnung__position { border-top: 1px solid var(--rand); }
.abrechnung__position--gruppe { background: var(--flaeche-blass); font-weight: 500; cursor: default; }
.abrechnung__position--eingerueckt { padding-left: 44px; }

.abrechnung__positionsname {
    flex: 1 1 0;
    min-width: 0;
    overflow-wrap: anywhere;
}

.abrechnung__klappe {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    padding: 0;
    border: none;
    background: none;
    color: var(--text);
    cursor: pointer;
}

.abrechnung__vorbeleg { padding: 10px 0; }
.abrechnung__vorbeleg + .abrechnung__vorbeleg { border-top: 1px solid var(--rand); }

/* Abschlag: Betrag oder Leistungsstand – unter den Wegen, eingerückt wie eine Unterfrage. */
.abrechnung__unterwahl {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 20px;
    margin-top: 12px;
    padding-left: 12px;
}

/* Die Überschrift eines einbezogenen Angebots innerhalb der Positionsliste. */
.abrechnung__angebot {
    padding: 8px 12px;
    border-top: 1px solid var(--rand);
    background: var(--flaeche-blass);
    color: var(--primaer-dunkel);
    font-weight: 600;
    font-size: 13px;
}

.abrechnung__angebot:first-child { border-top: none; }

/* Zeilen mit Mengenfeld: kein Zeiger, man klickt dort, um zu schreiben. */
.abrechnung__position--menge { cursor: default; flex-wrap: wrap; }
div.abrechnung__position { cursor: default; }

.abrechnung__mengenangabe {
    display: block;
    color: var(--text-schwach);
    font-size: 12px;
}

.abrechnung__mengeneingabe {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
}

/* Eine Menge braucht ihre Stellen: Die Tabelle drückt sonst das Feld unter die Zahl. */
.abrechnung__mengenfeld { width: 96px; min-width: 96px; text-align: right; }

/* Die Einheit in fester Breite – „Pauschal“ schöbe sonst sein Feld aus der Spalte der anderen. */
.abrechnung__einheit {
    width: 64px;
    color: var(--text-schwach);
    font-size: 12px;
    overflow-wrap: anywhere;
}

.abrechnung__betrag {
    flex: 0 0 auto;
    min-width: 90px;
    text-align: right;
    white-space: nowrap;
}

.abrechnung__alle {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    font-size: 13px;
}

/* Unbezahltes ist die Auskunft – im Wort steht der Betrag, die Farbe hebt ihn nur heraus. */
.abrechnung__offen { color: var(--rot-dunkel); font-weight: 600; }

.abrechnung__frage {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 6px;
    padding: 8px 10px;
    border: 1px solid var(--rand-stark);
    border-radius: var(--radius);
    font-size: 12px;
}

.abrechnung__frage > :last-child { display: flex; gap: 6px; flex-wrap: wrap; }

/* ---------- Gebäudeaufnahme ----------
   Links die Zeichnung des Raums, rechts was zu ihm gehört. Die Zeichnung bringt ihren weißen
   Grund selbst mit (wie jede Zeichnung im Haus), also braucht die Spalte keinen. Umgebrochen wird
   unter 900 Pixeln – eine Zeichnung von 200 Pixeln Breite neben einer Wandtabelle zeigt keine Maße. */
.aufnahmeraum {
    display: grid;
    grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}

@media (max-width: 900px) {
    .aufnahmeraum { grid-template-columns: minmax(0, 1fr); }
}

/* Nur die Zeichnung selbst – ein `svg` ohne `>` träfe auch das Zeichen im Knopf darüber und
   blähte es auf die ganze Spaltenbreite auf. */
.aufnahmeraum__zeichnung > svg {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius);
}

.aufnahmeraum__umschalter { margin-bottom: 8px; }

/* ---------- Planung der Gebäudeaufnahme ----------
   Nach dem Vorbild des Heizlastrechners: oben die Kennzahlen, links die Annahmen als Regler,
   Chips und Schalter, rechts was daraus folgt – als Balken, nicht als Tabelle. Die Ergebnisspalte
   klebt, damit man beim Ziehen eines Reglers sieht, was er bewirkt. Umgebrochen wird nach der
   Breite der Seite (Container), nicht des Fensters: Die Menüleiste nimmt 60 oder 232 Pixel weg. */
.seiten-koerper:has(> .planung) { container-type: inline-size; }

.planung {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
    margin-bottom: 22px;
}

.planung__ergebnis {
    display: flex;
    flex-direction: column;
    gap: 18px;
    position: sticky;
    top: calc(var(--kopfbereich-hoehe, 0px) + 12px);
}

.planung__ergebnis > .karte { margin-bottom: 0; }

@container (max-width: 920px) {
    .planung { grid-template-columns: minmax(0, 1fr); }
    .planung__ergebnis { position: static; }
}

.planung__satz {
    font-size: 12px;
    color: var(--text-schwach);
    margin: 6px 0 10px;
    line-height: 1.5;
}

.planung__raumkopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 6px 0 10px;
}

.planung__raumkopf h2 { font-size: 17px; margin: 0; }

/* Ein Abschnitt der Annahmen – zuklappbar, und im Kopf steht schon, was gilt. */
.planabschnitt {
    border-top: 1px solid var(--rand-zart);
    padding: 4px 0 6px;
}

.planabschnitt > summary {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 0;
    cursor: pointer;
    font-weight: 600;
    color: var(--text-stark);
    list-style: none;
}

.planabschnitt > summary::-webkit-details-marker { display: none; }

.planabschnitt > summary > span {
    margin-left: auto;
    font-weight: 400;
    font-size: 12px;
    color: var(--text-schwach);
    text-align: right;
}

.planabschnitt > summary::after {
    content: "";
    width: 7px;
    height: 7px;
    border-right: 2px solid var(--text-schwach);
    border-bottom: 2px solid var(--text-schwach);
    transform: rotate(-45deg);
    transition: transform .15s ease;
    flex: 0 0 auto;
}

.planabschnitt[open] > summary::after { transform: rotate(45deg); }

.planabschnitt--klein { margin-top: 10px; }
.planabschnitt--klein > summary { font-weight: 500; font-size: 13px; }

/* ---------- Regler ----------
   Schieber und Zahl nebeneinander. Leer ist die Bahn grau und der Knopf blass: Ein Regler hat
   immer eine Stellung, aber ohne Wert soll sie nicht wie eine Angabe aussehen. */
.regler { margin: 4px 0 12px; }

.regler__kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 2px;
}

.regler__titel { font-size: 13px; color: var(--text); }

.regler__wert {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: var(--text-schwach);
}

.regler__zahl {
    width: 78px;
    padding: 4px 8px;
    border: 1px solid var(--rand-stark);
    border-radius: var(--radius);
    background: var(--flaeche);
    color: var(--text-stark);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.regler__zahl::placeholder { font-weight: 400; color: var(--text-schwach); }

/* Leer steht dort ein Satz statt einer Zahl – breiter, aber nie breiter als die Spalte. */
.regler--leer .regler__zahl { width: min(150px, 100%); }
.regler--leer .regler__wert { max-width: 100%; }

.regler__weg {
    width: 22px;
    height: 22px;
    border: none;
    border-radius: 50%;
    background: none;
    color: var(--text-schwach);
    font: inherit;
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
}

.regler__weg:hover { background: var(--flaeche-grau); color: var(--text-stark); }

.regler__bahn {
    width: 100%;
    accent-color: var(--primaer);
    cursor: pointer;
}

.regler--leer .regler__bahn { accent-color: var(--rand-staerker); opacity: .55; }

.regler__hinweis { font-size: 11.5px; color: var(--text-schwach); }

/* ---------- Chipwahl ----------
   Wenige Antworten nebeneinander statt in einem Klappfeld. Ist keine gewählt, die die Reihe
   kennt, steht ein gelber Rand darum – eine fehlende Antwort soll auffallen. */
.chipwahl { margin: 4px 0 12px; }

.chipwahl__titel {
    display: block;
    font-size: 13px;
    color: var(--text);
    margin-bottom: 5px;
}

.chipwahl__reihe {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.chipwahl__chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 11px;
    border: 1px solid var(--rand-stark);
    border-radius: 999px;
    background: var(--flaeche);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    transition: background .12s ease, border-color .12s ease;
}

.chipwahl__chip:hover { border-color: var(--primaer); }

.chipwahl__chip--an {
    background: var(--primaer-blass);
    border-color: var(--primaer);
    color: var(--primaer-dunkel);
    font-weight: 600;
}

.chipwahl__punkt {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: 0 0 auto;
}

.chipwahl--klein { margin: 4px 0 0; }
.chipwahl--klein .chipwahl__chip { padding: 3px 9px; font-size: 12px; }

.chipwahl--offen .chipwahl__reihe {
    padding: 4px;
    margin: -4px;
    border-radius: 999px;
    box-shadow: 0 0 0 2px var(--gelb);
}

/* Das Feld für einen Wert, den die Chips nicht kennen – schmal, damit es in der Reihe bleibt. */
.chipwahl__eigen { display: inline-flex; align-items: center; gap: 4px; }
.chipwahl__eigen .feld { width: 74px; padding: 4px 8px; }
.chipwahl__eigen--paar .feld { width: 58px; }

/* ---------- Schaltzeile: Wort links, Kippschalter rechts ---------- */
.schaltzeile {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 4px 0 12px;
    padding: 10px 12px;
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius);
    background: var(--flaeche-blass);
    cursor: pointer;
}

.schaltzeile__text { display: flex; flex-direction: column; gap: 2px; }
.schaltzeile__text strong { font-size: 13px; font-weight: 600; color: var(--text-stark); }
.schaltzeile__text small { font-size: 12px; color: var(--text-schwach); }

/* ---------- Verlustbalken ----------
   Eine Farbe für alle Beträge; grau, was im Haus bleibt; schraffiert, was noch offen ist. */
.verlust { display: flex; flex-direction: column; gap: 10px; }

.verlust__kopf {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-size: 13px;
    margin-bottom: 4px;
}

.verlust__kopf span { color: var(--text); min-width: 0; overflow-wrap: anywhere; }
.verlust__kopf strong { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--text-stark); }
.verlust__kopf small { font-weight: 400; color: var(--text-schwach); margin-left: 4px; }

.verlust__bahn {
    height: 10px;
    border-radius: 999px;
    background: var(--flaeche-grau);
    overflow: hidden;
}

.verlust__fuell {
    height: 100%;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--primaer), var(--primaer-dunkel));
    transition: width .35s ease;
}

.verlust__fuell--grau { background: var(--rand-staerker); }

.verlust__fuell--offen {
    background: repeating-linear-gradient(135deg, var(--gelb) 0 6px, color-mix(in srgb, var(--gelb) 45%, transparent) 6px 12px);
}

.verlust__zeile--klick { cursor: pointer; border-radius: var(--radius); padding: 3px 5px; margin: -3px -5px; }
.verlust__zeile--klick:hover { background: var(--flaeche-blass); }

/* ---------- Zusammensetzung der Leistung des Wärmeerzeugers ---------- */
.stapel {
    display: flex;
    height: 14px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--flaeche-grau);
    margin-bottom: 10px;
}

.stapel__teil--last { background: var(--primaer); }
.stapel__teil--sperre { background: var(--gelb); }
.stapel__teil--wasser { background: var(--gruen); }

.stapel__legende {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-size: 13px;
}

.stapel__legende li { display: flex; align-items: center; gap: 8px; }
.stapel__legende strong { margin-left: auto; font-variant-numeric: tabular-nums; }
.stapel__punkt { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }

/* ---------- Deckung: reicht die Heizfläche? ---------- */
.deckung { margin: 6px 0 10px; }
.deckung .balken { margin-top: 6px; }

.deckung__kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 12px;
    font-size: 13px;
}

/* ---------- Raumkarten ----------
   Zugeklappt eine Zeile mit Name, Maßen und Heizlast; aufgeklappt Reiter statt vier Tabellen
   untereinander. Der Kopf ist ein Knopf – Knöpfe erben Schrift und Farbe nicht von selbst. */
.raumkarte { margin-bottom: 10px; }

.raumkarte__kopf {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 13px 16px;
    border: none;
    background: none;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.raumkarte__kopf:hover { background: var(--flaeche-blass); }
.raumkarte--offen > .raumkarte__kopf { border-bottom: 1px solid var(--rand-zart); }

.raumkarte__name { font-weight: 600; color: var(--text-stark); }
.raumkarte__masse { font-size: 12px; color: var(--text-schwach); }
.raumkarte__last { margin-left: auto; display: inline-flex; align-items: baseline; gap: 6px; white-space: nowrap; }
.raumkarte__last small { font-size: 12px; color: var(--text-schwach); }

.raumkarte__leiste {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 8px 14px;
    margin-bottom: 14px;
}

.raumkarte__reiter { margin-bottom: 0; flex: 1 1 auto; }

.raumkarte__werkzeuge {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding-bottom: 6px;
}

.raumkarte__ergebnis {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}

@media (max-width: 900px) {
    .raumkarte__ergebnis { grid-template-columns: minmax(0, 1fr); }
    .raumkarte__masse { display: none; }
}

/* ---------- Die Wände eines Raums ---------- */
.wandliste__kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 10px;
    margin: 14px 0 6px;
}

.wandliste__kopf h4 { margin: 0; font-size: 13px; }
.wandliste__alle { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-schwach); }

.wandliste {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius);
    margin-bottom: 14px;
}

.wandliste__zeile {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) auto;
    gap: 10px;
    align-items: center;
    padding: 8px 10px;
}

.wandliste__zeile + .wandliste__zeile { border-top: 1px solid var(--rand-zart); }

.wandliste__nummer {
    width: 26px;
    height: 26px;
    border: 2px solid;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: 700;
    color: var(--text-stark);
}

.wandliste__angaben { font-size: 12px; color: var(--text-schwach); }
.wandliste__angaben strong { color: var(--text-stark); font-size: 13px; }

.wandliste__felder { display: flex; gap: 8px; }

.wandliste__felder label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 11px;
    color: var(--text-schwach);
}

.wandliste__felder .feld { width: 82px; padding: 4px 8px; }

@media (max-width: 640px) {
    .wandliste__zeile { grid-template-columns: 30px minmax(0, 1fr); }
    .wandliste__felder { grid-column: 2; }
}

/* Die Legende zu den Farben der Wände in der Zeichnung. */
.wandlegende {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    font-size: 11.5px;
    color: var(--text-schwach);
}

.wandlegende li { display: inline-flex; align-items: center; gap: 5px; }
.wandlegende span { width: 14px; height: 4px; border-radius: 2px; }

/* Das 3D-Modell eines Raums. Der Grund ist ein Token und nicht Weiß wie bei den Zeichnungen:
   Die Flächen des Modells sind hell und schattiert, sie tragen auf beiden Gründen – eine weiße
   Fläche stünde im Dunkeln dagegen als Loch im Bildschirm. */
.raum3d {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.raum3d:focus { outline: none; }

.raum3d__werkzeuge {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
}

.raum3d__schalter { font-size: 13px; }

.raum3d__gross { margin-left: auto; }

.raum3d__titel {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    color: var(--text);
}

/* Quadratisch in der Spalte: Ein Raum ist selten so lang, dass ein Querformat mehr zeigte, und
   die Höhe steht fest, bevor die Leinwand gezeichnet ist – sonst sprängen die Felder daneben. */
.raum3d__flaeche {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--flaeche-grau);
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius);
    overflow: hidden;
}

/* Ohne `touch-action` rollte die Seite, während jemand das Modell mit dem Finger dreht. */
.raum3d__leinwand {
    display: block;
    width: 100%;
    height: 100%;
    touch-action: none;
    cursor: grab;
}

.raum3d__leinwand:active { cursor: grabbing; }

.raum3d__hinweis,
.raum3d__leer {
    font-size: 12px;
    color: var(--text-schwach);
}

.raum3d__leer {
    padding: 14px;
    border: 1px dashed var(--rand);
    border-radius: var(--radius);
}

/* Groß ist ein Lichtkasten wie der Belegbetrachter, nur eine Stufe darunter: Ein Beleg, der aus
   dieser Seite geöffnet wird, soll darüber liegen. Dieselbe Leinwand – nur die Hülle wird größer. */
.raum3d--gross {
    position: fixed;
    inset: 0;
    z-index: 88;
    padding: 12px 14px;
    background: var(--flaeche);
    animation: dialog-grund .16s ease-out;
}

.raum3d--gross .raum3d__flaeche {
    flex: 1 1 auto;
    min-height: 0;
    aspect-ratio: auto;
}

/* Der Bauplan steht in fester Breite, damit ein Klick in Bildpunkte umgerechnet werden kann;
   breiter als der Dialog rollt er in seiner Hülle. Die Zeichnung darüber nimmt keine Klicks an –
   sonst träfe ein Klick auf eine Ecke den Kreis statt des Bildes. */
.bauplan__huelle {
    max-height: 62vh;
    overflow: auto;
    border: 1px solid var(--rand-zart);
    border-radius: var(--radius);
}

.bauplan {
    position: relative;
    cursor: crosshair;
}

.bauplan img { display: block; max-width: none; }
