@import '_content/BlazorFlags/BlazorFlags.bundle.scp.css';

/* _content/D3.Web/Components/Layout/D3DesktopLayout.razor.rz.scp.css */
/* Mindesthöhe des Detailbereichs. Lag als globaler <style>-Block im Markup.

   Das !important ist entfallen: bereichsbezogenes CSS hängt ein
   Attribut an den Selektor (.d3-detail-container[b-xxx]) und gewinnt damit
   ohnehin gegen jede einfache Klassenregel. */
.d3-detail-container[b-pky7szvryh] {
    min-height: 92vh;
}
/* _content/D3.Web/Components/Layout/LoginLayout.razor.rz.scp.css */
/* Hintergrundfläche der Anmeldung. Die Regeln standen im globalen
   <style>-Block von Pages/Login/Login.razor und trafen dort `.rz-card` --
   also *jede* Karte im Dokument, und im Dokument stehen zwei: diese hier aus
   dem Layout und die Anmeldekarte in der Seite. Nur die äußere war gemeint.

   Deshalb liegt dieser Teil hier: bereichsbezogenes CSS der Seite erreicht
   die Karte des Layouts nicht -- sie ist kein Nachfahre, sondern der Rahmen
   um @Body, und ::deep zeigt nach innen. LoginLayout hat genau einen Nutzer
   (Login.razor, geprüft), die Verlegung ins Layout zieht also keine andere
   Seite mit.

   ── Warum die Regeln über .login-scope ::deep laufen ─────────────────────
   Blazor setzt das Bereichsattribut **nur auf einfache HTML-Elemente** des
   eigenen Markups, nie auf Komponenten. `.login-backdrop` sitzt auf einer
   RadzenCard, also wäre `.login-backdrop { … }` zu `.login-backdrop[b-x]`
   geworden -- ein Attribut, das die Karte nie trägt.

   Am laufenden Server gemessen, bevor der Anker eingezogen wurde: die Fläche
   war weiß und `display: block` statt grau und zentriert. Die Hülle
   `<div class="login-scope">` ist ein einfaches Element, bekommt das
   Attribut, und ::deep schiebt es auf den Vorfahren. `display: contents`
   hält sie aus dem Layout heraus, damit die Karte weiterhin direktes Kind
   von RadzenBody bleibt.

   #eee -> --qb-background (#EEF1F4 hell, #0A1118 dunkel). Die Rolle ist
   „Seitenhintergrund hinter der Karte", genau das. Sichtbar ändert sich ein
   Hauch Blaugrau; dafür folgt die Fläche jetzt dem Modus.

   Offen und hier nicht angefasst: dass diese Fläche eine RadzenCard ist, mit
   Kartenpolster und Kartenradius. Ein Seitenhintergrund ist keine Karte. Das
   gehört zum Umbau der Anmeldemaske, nicht zum Verlegen der Stile. */

.login-scope[b-shbe3jegpn] {
    display: contents;
}

.login-scope[b-shbe3jegpn]  .login-backdrop {
    background-color: var(--qb-background);
    display: flex;
    justify-content: center;
    align-items: center;
}

/* Die 680 px Höhe sind frei gewählt und haben keinen Token -- die
   Bruchpunkte sind fachlich noch offen (Inventar, „Offen (fachlich)").
   Bewusst unverändert übernommen. */
@media (min-height: 680px) {
    .login-scope[b-shbe3jegpn]  .login-backdrop {
        height: 95vh;
    }
}

@media (max-height: 680px) {
    .login-scope[b-shbe3jegpn]  .login-backdrop {
        height: 85vh;
    }
}
/* _content/D3.Web/Components/Layout/MainLayout.razor.rz.scp.css */
#blazor-error-ui[b-v7ljm3jlpv] {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-v7ljm3jlpv] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* _content/D3.Web/Components/Pages/AiAssistant.razor.rz.scp.css */
/* SKAILA-Chat. Lag als globaler <style>-Block im Markup (376 Zeilen, der
   letzte der 21).

   Dieser Block war anders als die übrigen zwanzig: keine Notbehelfe, sondern
   eine bewusst gesetzte lokale Palette mit ausgeschriebener Begründung und
   Kontrastzahlen. Die Zahlen des Verfassers stimmen -- #eef4f4 auf #264D4D
   liegt gemessen bei 8.39:1, die genannten „~8,4:1" also genau. Die Palette
   bleibt deshalb erhalten. Zwei ihrer *Begründungen* sind seit dem
   Theme-Umbau überholt, und die zwei Werte daran sind umgestellt; beides
   steht unten an der jeweiligen Stelle.

   ── Zwei verschiedene Gründe für ::deep, nicht verwechseln ───────────────
   1. **Elementtyp.** Blazor setzt das Bereichsattribut nur auf einfache
      HTML-Elemente des eigenen Markups, nie auf Komponenten. `.kia-card`
      sitzt auf einer RadzenCard, `.kia-welcome-body` auf einem RadzenText --
      beide brauchen einen Anker auf einem einfachen Element. Deshalb steht im
      Markup die Hülle `<div class="kia-scope">` mit `display: contents`.

      Am laufenden Server gemessen, bevor der Anker eingezogen wurde: die
      Karte war `display: block` statt Flex-Spalte, und `--skaila-accent` war
      **leer** -- die ganze Palette existierte nicht, und damit war jede
      Blasenregel wirkungslos, die auf `var(--skaila-*)` zeigt.

      Alles andere in dieser Datei hängt an einfachen Elementen und hat von
      Anfang an gegriffen. Nachgemessen wurden acht davon (`.kia-header`,
      `.kia-header-icon`, `.kia-messages`, `.kia-welcome`,
      `.kia-welcome-icon`, `.kia-suggestions`, `.kia-input-area`, das
      `textarea`) -- alle wertgleich mit dem alten Block.

   2. **Laufzeit-HTML.** Der Markdig-Teil weiter unten -- eigener Absatz.

   ── Warum hier so viel ::deep steht ──────────────────────────────────────
   Der Antworttext kommt aus Markdig und wird als @((MarkupString)…) in
   .kia-bubble-content gesetzt. Solche Elemente entstehen zur Laufzeit und
   bekommen **kein** Bereichsattribut -- der Razor-Compiler sieht sie nicht.
   Ohne ::deep würde aus `.kia-bubble-content p` ein
   `.kia-bubble-content p[b-x]`, und das trifft kein einziges Markdig-p: die
   komplette Markdown-Darstellung (Absätze, Überschriften, Listen, Links,
   Code, Tabellen, Zitate) wäre still verschwunden. Mit ::deep wandert das
   Attribut auf den Vorfahren: `.kia-bubble-content[b-x] p`.

   Das ist der teuerste Fehler, den man in dieser Datei machen kann, denn er
   fällt in einem grünen Build und auf einer leeren Chatseite nicht auf.

   Umgekehrt die schon bekannte Falle: das `<textarea class="rz-textarea">` im
   Eingabebereich des Markups ist **unser eigenes** HTML-Element, keine
   Radzen-Komponente. Es bekommt das Attribut direkt, ::deep wäre hier
   falsch. Nur .rz-button-text und .rz-button gehören wirklich Radzen.

   ── Was an Werten gerichtet ist ──────────────────────────────────────────
   Rückfallketten gestrichen, alle drei am Browser nachgemessen:

     var(--qb-surface-border) -> var(--qb-surface-border)
        --rz-stroke-weak ist im Kompilat **leer** -- die Kette lief immer auf
        die erste Ausweichstufe. --rz-base-300 und --qb-surface-border sind
        beide #D9E0E6, gemessen als Randfarbe rgb(217,224,230). Kein
        sichtbarer Unterschied, aber der Rückfall verbarg einen Token, den es
        nicht gibt.
     var(--rz-primary)    -> var(--qb-primary)  (#16324C, wertgleich)
     var(--rz-text-color) -> var(--qb-text)     (#1C2B36, wertgleich)

   ── Die zwei überholten Begründungen ─────────────────────────────────────
   1. „--rz-text-tertiary-color liegt bei ~4:1 und ist für diese
      Schriftgrößen zu blass" -- das galt, gilt aber nicht mehr. Der Token
      ist heute #51636F und liegt bei 6.24:1, das eigene #5a6572 bei 5.93:1.
      Der Token ist also *besser* als der Handwert, nach genau dem Kriterium
      des Verfassers. --skaila-muted-fg ist deshalb entfallen und die
      Zeitangabe steht auf --qb-text-muted.
   2. „Petrol ist der abgedunkelte zweite Markenton (--rz-base-900 #4C7E7E)"
      -- --rz-base-900 ist heute #1C2B36. Das Petrol hängt an keinem Token
      mehr. Es **bleibt** trotzdem stehen: es trägt die
      Sprecherunterscheidung (Petrol SKAILA, Marineblau Benutzer), und
      --qb-surface-inverse (#1C2B36) liegt so nah am Benutzer-Marineblau
      (--qb-primary #16324C), dass die beiden Sprecher optisch
      zusammenfielen. Was fehlt, ist ein Token für diese Rolle; das gehört
      in die Tokens, nicht in diese Datei.

   ── Abstände ─────────────────────────────────────────────────────────────
   Neun Abstände liegen genau auf der Leiter und stehen jetzt als Token
   (1rem, 0.75rem, 0.5rem). Die übrigen liegen dazwischen
   (0.2/0.3/0.4/0.45/0.6/0.8/0.85/1.25/1.4 rem) und sind unverändert
   geblieben -- sie zu runden wäre kein Verlegen mehr, sondern ein Umbau der
   Maske. Ebenso die Radien: 1.1rem für die Blase hat in der Leiter
   (--qb-radius-card 3px, --qb-radius-control 2px) keine Entsprechung.

   ── Ersatzlos entfallen ──────────────────────────────────────────────────
   .kia-input-actions (5 Deklarationen). Die Klasse steht auf keinem Element
   im Projekt -- geprüft, sie kam im ganzen Repository nur in diesem Block
   selbst vor. Rest einer älteren Fassung, in der die zwei Knöpfe in einer
   Hülle saßen. */

.kia-scope[b-um1vp362l6] {
    display: contents;
}

/* Die Palette sitzt auf der Karte und wird von dort geerbt -- auch in den
   Markdig-Teilbaum, denn Vererbung folgt dem DOM, nicht den Selektoren. */
.kia-scope[b-um1vp362l6]  .kia-card {
    /* Petrol als Sprecherfarbe SKAILA -- siehe Punkt 2 im Kopf. */
    --skaila-accent: #4C7E7E;
    --skaila-answer-bg: #264D4D;
    /* Nicht reines Weiß: reduziert das Ausfransen der Buchstaben (Halation)
       auf dunklem Grund. Gemessen 8.39:1, WCAG AAA. */
    --skaila-answer-fg: #eef4f4;
    --skaila-answer-border: #3d6b68;

    /* Auf dunklem Grund: Volltonweiß für Hervorhebungen, Petrol-Pastell
       für Links und Zitate. Gemessen: Link 5.69:1, Zitat 7.12:1. */
    --skaila-on-dark: #fff;
    --skaila-link: #9FD4D0;
    --skaila-quote-border: #8FC0BD;
    --skaila-quote-fg: #d5e4e3;

    /* Durchscheinende Flächen und Rahmen -- passen auf beide Blasenfarben.
       GRUNDANNAHME aller Regeln unten: BEIDE Blasen haben einen dunklen
       Grund, die Antwort --skaila-answer-bg, die eigene Eingabe --qb-primary.
       Alle Markdown-Elemente sind deshalb einheitlich hell gehalten. Wer die
       Blasen aufhellt, muss --skaila-overlay-* und --skaila-on-dark
       mitumstellen. */
    --skaila-overlay-dark: rgba(0, 0, 0, 0.28);
    --skaila-overlay-light: rgba(255, 255, 255, 0.22);
    --skaila-overlay-light-soft: rgba(255, 255, 255, 0.1);
    --skaila-shadow: rgba(0, 0, 0, 0.25);

    /* Höhe zentral, damit die Medienabfrage sie mobil anpassen kann. */
    height: calc(100vh - 120px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.kia-header[b-um1vp362l6] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--qb-surface-border);
    flex-shrink: 0;
}

/* Stand als style="font-size:1.5rem; color:var(--rz-text-color);" im Markup. */
.kia-header-icon[b-um1vp362l6] {
    font-size: 1.5rem;
    color: var(--qb-text);
}

.kia-messages[b-um1vp362l6] {
    flex: 1;
    /* Wichtig: erlaubt dem Flex-Kind, unter die Inhaltshöhe zu schrumpfen,
       damit dieser Bereich scrollt statt Eingabe und Knöpfe aus dem
       Container zu drängen. */
    min-height: 0;
    overflow-y: auto;
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: var(--qb-space-md);
    scroll-behavior: smooth;
}

/* ── Willkommens-Bildschirm ── */
.kia-welcome[b-um1vp362l6] {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--qb-space-sm);
    margin: auto;
    padding: var(--qb-space-xl);
    text-align: center;
}

.kia-welcome-icon[b-um1vp362l6] {
    font-size: 3.5rem;
    color: var(--qb-text);
    opacity: 0.8;
}

/* Stand als style="color:var(--skaila-welcome-fg); max-width:32rem;
   text-align:center;" im Markup. Die Farbe ist ersatzlos entfallen:
   --skaila-welcome-fg war #38434f (10.08:1), also ein von Hand leicht
   aufgehelltes Fließtextschwarz ohne Rolle. Die Standardfarbe des Textes
   ist --qb-text (#1C2B36, 14.5:1) -- dunkler und modusabhängig. Der
   Verfasser hat im Markup vermerkt, dass er den Kontrast dieses Texts
   ausdrücklich *nicht* absenken wollte („kein opacity"); das folgt dem.
   Sichtbare Änderung: der Begrüßungstext wird dunkler.

   ::deep über .kia-welcome, weil der Text ein RadzenText ist -- Anker ist
   das einfache <div class="kia-welcome"> darüber. */
.kia-welcome[b-um1vp362l6]  .kia-welcome-body {
    max-width: 32rem;
    text-align: center;
}

.kia-suggestions[b-um1vp362l6] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--qb-space-xs);
    justify-content: center;
    margin-top: var(--qb-space-xs);
}

/* ── Chat-Blasen ── */
.kia-bubble[b-um1vp362l6] {
    display: flex;
    align-items: flex-end;
    gap: 0.6rem;
    max-width: 78%;
}

.kia-bubble--user[b-um1vp362l6] {
    align-self: flex-end;
}

.kia-bubble--assistant[b-um1vp362l6] {
    align-self: flex-start;
    /* Antworten sind strukturiert (Checklisten, Tabellen) und brauchen mehr
       Zeilenlänge als die kurzen eigenen Eingaben. */
    max-width: 92%;
}

.kia-avatar[b-um1vp362l6] {
    width: 2rem;
    height: 2rem;
    border-radius: 50%;
    /* Petrol für SKAILA, Marineblau für den Benutzer: die beiden Sprecher
       sind damit auch bei flüchtigem Blick auseinanderzuhalten. */
    background: var(--skaila-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 1rem;
    color: var(--skaila-on-dark);
}

.kia-avatar--user[b-um1vp362l6] {
    background: var(--qb-primary);
    color: var(--skaila-on-dark);
}

.kia-bubble-body[b-um1vp362l6] {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.kia-bubble--user .kia-bubble-body[b-um1vp362l6] {
    align-items: flex-end;
}

.kia-bubble-content[b-um1vp362l6] {
    padding: var(--qb-space-sm) var(--qb-space-md);
    border-radius: 1.1rem;
    /* 1rem = 16px: Untergrenze für längere Lesetexte. */
    font-size: 1rem;
    line-height: 1.65;
    word-break: break-word;
}

/* Weiß auf --qb-primary, gemessen 13.17:1. */
.kia-bubble--user .kia-bubble-content[b-um1vp362l6] {
    background: var(--qb-primary);
    color: var(--skaila-on-dark);
    border-bottom-right-radius: 0.25rem;
}

.kia-bubble--assistant .kia-bubble-content[b-um1vp362l6] {
    background: var(--skaila-answer-bg);
    color: var(--skaila-answer-fg);
    border: 1px solid var(--skaila-answer-border);
    border-bottom-left-radius: 0.25rem;
    box-shadow: 0 1px 3px var(--skaila-shadow);
}

/* ── Markdown-Darstellung (Markdig) ───────────────────────────────────────
   Ab hier überall ::deep -- Begründung im Kopf der Datei. */

/* Hervorhebungen (der Prompt setzt Feldbezeichnungen fett) abheben. */
.kia-bubble--assistant .kia-bubble-content[b-um1vp362l6]  strong,
.kia-bubble--assistant .kia-bubble-content[b-um1vp362l6]  b {
    font-weight: 700;
    color: var(--skaila-on-dark);
}

.kia-bubble--assistant .kia-bubble-content[b-um1vp362l6]  pre {
    border-radius: 0.4rem;
    padding: 0.6rem 0.8rem;
    /* Code und Tabellen nicht kleiner als der Fließtext setzen. */
    font-size: 0.95rem;
    overflow-x: auto;
    margin: 0.4rem 0;
    white-space: pre-wrap;
}

/* Erste und letzte Blockränder entfernen, damit die Blase kompakt bleibt. */
.kia-bubble-content[b-um1vp362l6]  > :first-child {
    margin-top: 0;
}

.kia-bubble-content[b-um1vp362l6]  > :last-child {
    margin-bottom: 0;
}

.kia-bubble-content[b-um1vp362l6]  p {
    margin: var(--qb-space-xs) 0;
}

.kia-bubble-content[b-um1vp362l6]  h1,
.kia-bubble-content[b-um1vp362l6]  h2,
.kia-bubble-content[b-um1vp362l6]  h3,
.kia-bubble-content[b-um1vp362l6]  h4,
.kia-bubble-content[b-um1vp362l6]  h5,
.kia-bubble-content[b-um1vp362l6]  h6 {
    margin: 0.6rem 0 0.3rem;
    line-height: 1.3;
    font-weight: 600;
}

/* Auf den größeren Fließtext (1rem) angehoben, damit die Hierarchie
   erhalten bleibt. */
.kia-bubble-content[b-um1vp362l6]  h1 { font-size: 1.3rem; }
.kia-bubble-content[b-um1vp362l6]  h2 { font-size: 1.2rem; }
.kia-bubble-content[b-um1vp362l6]  h3 { font-size: 1.1rem; }

.kia-bubble-content[b-um1vp362l6]  h4,
.kia-bubble-content[b-um1vp362l6]  h5,
.kia-bubble-content[b-um1vp362l6]  h6 { font-size: 1.05rem; }

.kia-bubble-content[b-um1vp362l6]  ul,
.kia-bubble-content[b-um1vp362l6]  ol {
    margin: 0.4rem 0;
    padding-left: 1.4rem;
}

/* Mehr Luft zwischen Listenpunkten: Checklisten sind der häufigste
   Antworttyp. */
.kia-bubble-content[b-um1vp362l6]  li {
    margin: 0.3rem 0;
}

/* Setzt die dunkle Grundannahme beider Blasen voraus -- siehe Kopf. */
.kia-bubble-content[b-um1vp362l6]  a {
    color: var(--skaila-link);
    text-decoration: underline;
}

/* Codeblock und Inline-Code (kein Codeblock). */
.kia-bubble--assistant .kia-bubble-content[b-um1vp362l6]  pre,
.kia-bubble-content[b-um1vp362l6]  :not(pre) > code {
    background: var(--skaila-overlay-dark);
    border: 1px solid var(--skaila-overlay-light);
    color: var(--skaila-answer-fg);
}

.kia-bubble-content[b-um1vp362l6]  :not(pre) > code {
    border-radius: 0.3rem;
    padding: 0.05rem 0.3rem;
    font-size: 0.95rem;
}

.kia-bubble-content[b-um1vp362l6]  table {
    border-collapse: collapse;
    margin: var(--qb-space-xs) 0;
    font-size: 0.95rem;
    width: 100%;
}

.kia-bubble-content[b-um1vp362l6]  th,
.kia-bubble-content[b-um1vp362l6]  td {
    border: 1px solid var(--skaila-overlay-light);
    /* Mehr Zellenluft: Trefferlisten (Kennung/Bezeichnung) werden zeilenweise
       verglichen. */
    padding: 0.45rem 0.6rem;
    text-align: left;
}

.kia-bubble-content[b-um1vp362l6]  th {
    background: var(--skaila-overlay-light-soft);
    color: var(--skaila-on-dark);
    font-weight: 700;
}

.kia-bubble-content[b-um1vp362l6]  blockquote {
    margin: 0.4rem 0;
    padding-left: 0.8rem;
    border-left: 3px solid var(--skaila-quote-border);
    /* Kein opacity -- das senkt den Kontrast des Zitattextes wieder ab. */
    color: var(--skaila-quote-fg);
}

/* Steht außerhalb der Blase auf hellem Grund. --skaila-muted-fg (#5a6572,
   5.93:1) ist entfallen, --qb-text-muted (#51636F) liegt bei 6.24:1 --
   Begründung Punkt 1 im Kopf. */
.kia-bubble-time[b-um1vp362l6] {
    font-size: 0.78rem;
    color: var(--qb-text-muted);
    padding: 0 0.3rem;
}

/* ── Tipp-Animation ── */
.kia-typing[b-um1vp362l6] {
    display: inline-flex;
    gap: 0.3rem;
    padding: 0.15rem 0;
}

.kia-typing span[b-um1vp362l6] {
    width: 0.45rem;
    height: 0.45rem;
    border-radius: 50%;
    /* Weiß statt --qb-primary: die Punkte stehen in der dunklen
       Antwort-Blase und wären im Marineblau praktisch unsichtbar. */
    background: var(--skaila-on-dark);
    animation: kia-bounce-b-um1vp362l6 1.2s infinite;
}

.kia-typing span:nth-child(2)[b-um1vp362l6] { animation-delay: 0.2s; }
.kia-typing span:nth-child(3)[b-um1vp362l6] { animation-delay: 0.4s; }

@keyframes kia-bounce-b-um1vp362l6 {
    0%, 80%, 100% { transform: translateY(0); opacity: 0.5; }
    40% { transform: translateY(-5px); opacity: 1; }
}

/* ── Eingabe ── */
.kia-input-area[b-um1vp362l6] {
    display: flex;
    gap: var(--qb-space-sm);
    align-items: stretch;
    padding: 0.75rem 1.25rem 1rem;
    border-top: 1px solid var(--qb-surface-border);
    flex-shrink: 0;
}

/* Unser eigenes <textarea class="rz-textarea">, kein Radzen-Bauteil --
   deshalb ohne ::deep. min-width erlaubt ihm, unter die Inhaltsbreite zu
   schrumpfen, sonst werden die Knöpfe rechts aus dem Container gedrängt.
   Die vier folgenden Deklarationen standen als style="..." am Element. */
.kia-input-area textarea[b-um1vp362l6] {
    min-width: 0;
    flex: 1;
    resize: none;
    font-size: 1rem;
    line-height: 1.5;
}

/* ── Mobil und schmale Fenster ── */
@media (max-width: 640px) {
    .kia-scope[b-um1vp362l6]  .kia-card {
        /* Dynamische Sichtfeldhöhe: berücksichtigt ein- und ausblendende
           Browser-Leisten. */
        height: calc(100dvh - 64px);
        border-radius: 0;
    }

    .kia-header[b-um1vp362l6] {
        padding: 0.6rem 0.8rem;
    }

    /* Im Kopf nur das Symbol zeigen. .rz-button-text gehört Radzen. */
    .kia-header[b-um1vp362l6]  .rz-button .rz-button-text {
        display: none;
    }

    .kia-messages[b-um1vp362l6] {
        padding: 0.85rem;
    }

    .kia-bubble[b-um1vp362l6] {
        max-width: 90%;
    }

    .kia-input-area[b-um1vp362l6] {
        gap: 0.4rem;
        /* Sichere Zone (iOS Home-Indicator) berücksichtigen. */
        padding: 0.5rem 0.6rem calc(0.6rem + env(safe-area-inset-bottom));
    }

    /* Senden und Mikrofon: nur Pfeil- bzw. Mikrofonsymbol, kein Text. */
    .kia-input-area[b-um1vp362l6]  .rz-button {
        min-width: 2.75rem;
        padding-left: 0;
        padding-right: 0;
    }

    .kia-input-area[b-um1vp362l6]  .rz-button .rz-button-text {
        display: none;
    }
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Positionsdetail/ColumnDropDown.razor.rz.scp.css */
/* Die Hülle hält das Feld in einer Tabellenzelle ohne eigene Breite offen, sonst schrumpfte es auf den Spaltenkopf.
   Das Aufklappfeld selbst erreicht diese Datei nicht (es hängt beim Öffnen am Seitenkörper) — siehe ColumnDropDown.razor. */
.qb-coldd[b-4huo01ghy5] {
    width: 100%;
}

/* Die Mindestbreite nur in der Tabellenzelle (Fahrzeuggitter). Im Feldraster gibt die Zelle die Breite vor: am Telefon ist das
   Blatt 100 % minus Leiste breit (PositionDetailSheet.razor.css:24, 52 px), eine Rasterzelle bei 375 px also rund 122 px. Mit
   9rem ragte das Feld rechts aus dem Raster, der Blattrumpf (overflow-y: auto) wurde quer rollbar, und Radzen schließt jedes
   Aufklappfeld, sobald ein Vorfahr rollt (Radzen.Blazor.js 11.2.3, openPopup: scroll → closeAllPopups) — Pro ging sofort zu. */
td > .qb-coldd[b-4huo01ghy5] {
    min-width: 9rem;
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Positionsdetail/PositionDetailAllgemein.razor.rz.scp.css */
/* Das Freitextfeld des Einsatzorts sitzt in Radzens Wertanzeige und sieht aus wie deren Text; den Rahmen trägt das Dropdown.
   Ohne ::deep: das Feld steht selbst in dieser Datei und trägt deren Bereichsattribut. `::deep .x` verlangte einen Vorfahren mit
   dem Attribut, den es hier nicht gibt (alle Hüllen sind Komponenten) — die Regel griff nie, das Feld zeigte den Browserrahmen. */
.pd-einsatzort-text[b-eyfjetv2g4] {
    width: 100%;
    border: 0;
    outline: none;
    background: transparent;
    padding: 0;
    font: inherit;
    color: inherit;
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Positionsdetail/PositionDetailEinzeltage.razor.rz.scp.css */
/* Die Eingabefelder einer geöffneten Einzeltagzeile. RadzenNumeric und RadzenDatePicker sind inline-block-Hüllen mit einem Input auf
   width: 100% (odysys-base.css: .rz-numeric, .rz-datepicker) — ohne eigene Breite schrumpfen sie in der Tabellenzelle auf die Breite der
   Spaltenüberschrift und schneiden den Wert ab. Die min-width aus AuftragPositionTab.razor.css (.qb-pos-edit) ist scoped und erreicht diese
   Zellen nicht. Feste Breiten wie in PositionDetailStuecklisteBearbeiten.razor.css, damit die Zeile beim Öffnen nicht springt; auf schmalen
   Fenstern rollt die Tabelle quer (PosTable). Die Zellen stehen im Markup dieses Reiters, die Radzen-Felder nicht — deshalb td ::deep. */

td[b-oz2kxrp7qv]  .et-input--s {
    width: 4rem;
}

td[b-oz2kxrp7qv]  .et-input--m {
    width: 5rem;
}

td[b-oz2kxrp7qv]  .et-input--zeit {
    width: 6rem;
}

td[b-oz2kxrp7qv]  .et-input--datum {
    width: 8rem;
}

td[b-oz2kxrp7qv]  .et-input--auswahl {
    min-width: 9rem;
}

/* GenericDropDown reicht keine Klasse durch; die Zelle trägt sie. */
td.et-cell--fahrer[b-oz2kxrp7qv]  .rz-dropdown {
    min-width: 12rem;
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Positionsdetail/PositionDetailKalkulation.razor.rz.scp.css */
/* „kein weiterer Erloes" -- Haekchen und Beschriftung bleiben zusammen. Falle:
   `white-space: nowrap` allein reicht nicht, es wirkt auf Text, nicht auf die
   Flex-Kinder der OptionRow; deshalb eine eigene Flex-Huelle. */
.pd-kalk-keinerloes[b-6xohn1m270] {
    display: inline-flex;
    align-items: center;
    gap: var(--qb-space-xs);
    flex: 0 0 auto;
    white-space: nowrap;
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Positionsdetail/PositionDetailSheet.razor.rz.scp.css */
/* Das seitliche Einfahrfenster.

   Maße aus dem Prototyp `SKAI4 Kompakt-Konzept2 1 - Positionsdetail seitlich.html`
   (`.sheet`, Z. 398-409): von rechts, 500 px breit, über die volle Höhe, Bewegung
   .22 s. Farben, Abstände und Ebene aus den Token.

   Falle: `position: fixed` hält nur, solange keine Hülle darüber (MaskShell,
   BasicdataWrapper, PositionsSicht) transform, filter oder contain setzt -- sonst
   säße das Blatt mitten in der Maske. */
.qb-possheet[b-ey2fgtfege] {
    position: fixed;

    /* UNTER der Kopfleiste (Abweichung vom Prototyp `top: 0`, der keine hat) --
       Vorgabe des Kunden; wie NavigationSidebar.razor.css. */
    inset-block-start: var(--qb-header-height);
    inset-block-end: 0;
    inset-inline-end: 0;
    z-index: var(--qb-z-drawer);

    /* Etwa die Hälfte des Auftragsdetailbereichs (Fenster ohne die Navigationsleiste,
       NavigationSidebar.razor.css), nicht schmaler als die 500 px des Prototyps, nie breiter als das Fenster ohne die Leiste.
       Die Navigationsleiste bleibt auch auf dem Telefon stehen und liegt über dem Blatt; mit 100 % verschwand dort dessen linker
       Rand unter ihr (Screenshot Anwender 2026-10-08, ~375 px). */
    width: min(calc(100% - var(--skai4-rail-width)), max(500px, calc((100vw - var(--skai4-rail-width)) / 2)));

    display: flex;
    flex-direction: column;

    background: var(--qb-surface);
    border-inline-start: 1px solid var(--qb-border-strong);
    box-shadow: var(--qb-shadow-overlay);

    /* Geschlossen: draußen UND unsichtbar.

       Die Sichtbarkeit braucht die Verzögerung, sonst verschwände das Blatt sofort
       und die Ausfahrt wäre nicht zu sehen. Beim Einfahren gilt sie nicht -- dort
       muss es vor der Bewegung sichtbar sein.

       Warum überhaupt `visibility` und nicht nur `transform`: ein Element, das nur
       verschoben ist, bleibt bedienbar und in der Tabreihenfolge. `inert` im Markup
       deckt das in heutigen Browsern ab; `visibility` ist der zweite Riegel und
       wirkt auch dort, wo `inert` fehlt. */
    transform: translateX(105%);
    visibility: hidden;
    transition: transform var(--qb-transition-base), visibility 0s linear 0.2s;
}

.qb-possheet--open[b-ey2fgtfege] {
    transform: none;
    visibility: visible;
    transition: transform var(--qb-transition-base), visibility 0s;
}

/* Wer Bewegung abgestellt hat, bekommt keine -- und dann darf auch die
   Sichtbarkeit nicht mehr verzögert sein, sonst bliebe das Blatt 0,2 s stehen. */
@media (prefers-reduced-motion: reduce) {
    .qb-possheet[b-ey2fgtfege],
    .qb-possheet--open[b-ey2fgtfege] {
        transition: none;
    }
}

/* Das Blatt selbst nimmt den Fokus (tabindex="-1"), damit Esc ankommt. Ein Rahmen
   darum wäre irreführend -- fokussiert ist die Fläche, nicht ein Bedienelement. */
.qb-possheet:focus[b-ey2fgtfege] {
    outline: none;
}

/* ── Kopfzeile ───────────────────────────────────────────────────────────────
   Prototyp Z. 410-418: Wortmarke, Positionsbezeichnung, rechts die Schritt- und
   Schließknöpfe. */
.qb-possheet-head[b-ey2fgtfege] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    flex-wrap: wrap;

    padding: var(--qb-space-sm) var(--qb-space-md);
    border-block-end: 1px solid var(--qb-surface-border);
}

.qb-possheet-title[b-ey2fgtfege] {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.7px;
    text-transform: uppercase;
    color: var(--qb-text-muted);
}

.qb-possheet-pos[b-ey2fgtfege] {
    font-size: 13px;
    font-weight: 600;
    color: var(--qb-text);

    /* In der schmalen Spalte ist der Positionstext der erste, der zu lang wird.
       Er steht deshalb zusätzlich im Kurztipp (im Markup gesetzt). */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.qb-possheet-nav[b-ey2fgtfege] {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: var(--qb-space-xxs);
}

.qb-possheet-idx[b-ey2fgtfege] {
    font-size: 12px;
    color: var(--qb-text-subtle);
    font-variant-numeric: tabular-nums;
}

.qb-possheet-step[b-ey2fgtfege] {
    width: 26px;
    height: 26px;

    border: 1px solid var(--qb-border-strong);
    border-radius: var(--qb-radius-control);
    background: var(--qb-surface);
    color: var(--qb-text-muted);

    font-size: 13px;
    line-height: 1;
    cursor: pointer;
}

.qb-possheet-step:hover[b-ey2fgtfege] {
    background: var(--qb-surface-hover);
    color: var(--qb-text);
}

/* Auf Touch und schmalen Bildschirmen 44 px Tippfläche (WCAG 2.5.5, Apple HIG); 26 px treffen dort zwei Knöpfe zugleich. Die
   Desktop-Optik bleibt. 480 px ist die Schmal-Grenze der Grundlage (REFERENZ-REGELN, Arbeitsvorrat-Kacheln). */
@media (max-width: 480px), (pointer: coarse) {
    .qb-possheet-step[b-ey2fgtfege] {
        min-width: 44px;
        min-height: 44px;
        font-size: 16px;
    }
}

/* ── Reiter, Ebene 1: Segmentschalter ────────────────────────────────────────
   „Zwei Reiterreihen gleichen Aussehens übereinander sind verboten. Die innere
   Ebene ist ein Segmentschalter" (MUSS). Hier ist es die ÄUSSERE, die zum Segment
   wird -- so löst es auch der Prototyp (`.tabs.seg`, Z. 391-396), und der
   Unterschied zwischen den beiden Reihen ist derselbe: eine Reihe trägt Kacheln,
   die andere Unterstriche.

   `flex-wrap`, weil sechs Reiter in 500 px nicht in eine Zeile passen -- der
   Prototyp macht es an derselben Stelle ebenso (Z. 409). */
.qb-possheet-seg[b-ey2fgtfege] {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;

    margin: var(--qb-space-xs) var(--qb-space-md) 0;
    padding: 3px;

    background: var(--qb-surface-sunken);
    border-radius: 9px;
}

.qb-possheet-segtab[b-ey2fgtfege] {
    appearance: none;
    border: 0;
    background: transparent;
    border-radius: 7px;
    padding: 6px 14px;

    font: inherit;
    font-size: 12px;
    color: var(--qb-text-muted);
    cursor: pointer;
}

.qb-possheet-segtab:hover:not(:disabled)[b-ey2fgtfege] {
    background: var(--qb-surface-hover);
    color: var(--qb-text);
}

/* Gesperrt: gedämpft, aber lesbar -- D3 graut „Einzeltage" bzw.
   „Monatsbetrachtung" aus, statt den Reiter zu entfernen
   (FormDetailExtraPosG.FormDetailExtraPos_Load:144-149). Der Grund steht im
   Kurztipp. Dieselbe Behandlung wie auf Ebene 2. */
.qb-possheet-segtab:disabled[b-ey2fgtfege] {
    color: var(--qb-text-disabled);
    cursor: not-allowed;
}

.qb-possheet-segtab--active[b-ey2fgtfege] {
    background: var(--qb-surface);
    color: var(--qb-text);
    font-weight: 600;
    box-shadow: 0 1px 2px rgb(16 32 45 / 18%);
}

/* ── Reiter, Ebene 2: Unterstrichreihe ───────────────────────────────────── */
.qb-possheet-sub[b-ey2fgtfege] {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    row-gap: 0;

    margin-inline: var(--qb-space-md);
    border-block-end: 1px solid var(--qb-surface-border);
}

.qb-possheet-subtab[b-ey2fgtfege] {
    appearance: none;
    border: 0;
    border-block-end: 2px solid transparent;
    background: transparent;
    padding: 5px 10px 6px;

    font: inherit;
    font-size: 12px;
    color: var(--qb-text-muted);
    cursor: pointer;
}

.qb-possheet-subtab:hover:not(:disabled)[b-ey2fgtfege] {
    color: var(--qb-text);
    background: var(--qb-surface-sunken);
}

.qb-possheet-subtab--active[b-ey2fgtfege] {
    color: var(--qb-interactive-strong);
    font-weight: 600;
    border-block-end-color: var(--qb-interactive);
}

/* Gesperrt: gedämpft, aber lesbar -- D3 graut diese Reiter aus, statt sie zu
   entfernen (FormDetailExtraPos_Load:131-142). Der Grund steht im Kurztipp. */
.qb-possheet-subtab:disabled[b-ey2fgtfege] {
    color: var(--qb-text-disabled);
    cursor: not-allowed;
}

/* Schmal waagerecht wischbar statt umgebrochen: auf dem Telefon würden beide Reiterreihen drei bis vier Zeilen hoch, und dem
   Rumpf bliebe kaum Höhe. Dieselbe Regel wie bei den Arbeitsvorrat-Kacheln (REFERENZ-REGELN: „Unter 480 px wird die Reihe
   waagerecht wischbar statt zu stapeln"). Im 500-px-Blatt
   bleibt der Umbruch des Prototyps. */
@media (max-width: 480px) {
    .qb-possheet-seg[b-ey2fgtfege],
    .qb-possheet-sub[b-ey2fgtfege] {
        flex-wrap: nowrap;
        overflow-x: auto;
        overscroll-behavior-x: contain;
    }

    .qb-possheet-segtab[b-ey2fgtfege],
    .qb-possheet-subtab[b-ey2fgtfege] {
        flex: none;
        white-space: nowrap;
    }
}

/* ── Der Marker „hier steht etwas" ───────────────────────────────────────────
   D3 färbt die Zusatztext-Kappe grün, sobald einer der beiden Zusatztexte
   gefüllt ist (FormDetailExtraPosG:110-115). Grün allein trägt die Aussage
   nicht -- „Farbe ist nie der einzige Träger einer Aussage" (MUSS, Kapitel 9.9).
   Deshalb ein Punkt, der auch ohne Farbwahrnehmung zu sehen ist; der Kurztipp
   der Kappe und der Text daneben sagen, wofür er steht. */
.qb-possheet-marker[b-ey2fgtfege] {
    margin-inline-start: 4px;
    font-size: 8px;
    vertical-align: 2px;
    color: var(--qb-success);
}

/* Nur für Vorlesehilfen: der Punkt hat keinen lesbaren Text, und ein Kurztipp
   allein erreicht sie nicht. */
.qb-possheet-srtext[b-ey2fgtfege] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ── Rumpf ──────────────────────────────────────────────────────────────── */
.qb-possheet-body[b-ey2fgtfege] {
    flex: 1;
    min-height: 0;
    overflow-y: auto;

    padding: var(--qb-space-sm) var(--qb-space-md) var(--qb-space-md);
}

/* In 500 px hat ein vierspaltiges Feldraster keine lesbare Spaltenbreite mehr. Der
   Prototyp staucht dort alles auf zwei (`.sheet .cols-3 … .cols-6`, Z. 406); hier
   trifft dieselbe Regel die Rasterklassen von FieldGrid.

   ::deep, weil das Raster in einem anderen Bauteil entsteht -- bereichsbezogenes
   CSS reicht sonst nicht über die Komponentengrenze. */
.qb-possheet-body[b-ey2fgtfege]  .qb-fieldgrid--3,
.qb-possheet-body[b-ey2fgtfege]  .qb-fieldgrid--4,
.qb-possheet-body[b-ey2fgtfege]  .qb-fieldgrid--5,
.qb-possheet-body[b-ey2fgtfege]  .qb-fieldgrid--6 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* ── Der Textkörper einer Text- und der Summentext einer Summenposition ──────
   In D3 sind beides RTF-Editoren, die die Maske von oben her füllen: `llRTFx`
   (Textmaske, y=6) und `llRTFs` (Summenmaske, y=0). Kein einzeiliges Feld --
   sie tragen mehrere Zeilen, und bei einer Textposition IST dieser Text die
   Position.

   Hier eine mehrzeilige Fläche mit eigenem Rollbereich: Zeilenumbrüche des
   gespeicherten Textes bleiben erhalten (pre-wrap), lange Texte schieben das
   Blatt nicht auseinander. Anzeigen, nicht bearbeiten -- das Bearbeiten kommt
   mit dem Schreibweg und wird dann ein Editor.

   ::deep, weil der Wert in FieldShell/Wert entsteht und bereichsbezogenes CSS
   sonst nicht über die Komponentengrenze reicht. */
/* ── „Hier steht nichts" ─────────────────────────────────────────────────────
   Ein Reiter ohne Daten zeigt einen Satz und keine leere Fläche -- dieselbe
   Regel wie „Leere Werte zeigen einen Gedankenstrich" (MUSS, Muster
   „Feldzustände"), eine Ebene höher.

   NICHT zu verwechseln mit SectionPlaceholder: die gestrichelte Fläche sagt
   „noch nicht gebaut", dieser Satz sagt „gebaut, aber zu dieser Position ist
   nichts hinterlegt". Der Unterschied ist für den Anwender der ganze Punkt.

   ::deep, weil der Satz in den Reiter-Bauteilen entsteht und bereichsbezogenes
   CSS sonst nicht über die Komponentengrenze reicht. */
.qb-possheet-body[b-ey2fgtfege]  .qb-tab-leer {
    margin: 0;
    padding: var(--qb-space-md);

    font-size: 12px;
    color: var(--qb-text-muted);
}

.qb-possheet-body[b-ey2fgtfege]  .qb-longtext {
    display: block;
    max-height: 14em;
    overflow-y: auto;

    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/* ── Unterform eines Radioknopfs ─────────────────────────────────────────────
   D3 setzt die Unterformen der Pauschale und der Hauptsumme in eigene Rahmen
   (panel6 und panel1 der S-Maske), eingerückt unter ihrem Knopf. Die Einrückung
   ist die Zuordnung: ohne sie stünden neun Knöpfe gleichrangig untereinander,
   und welcher zu welchem gehört, wäre nicht mehr zu sehen. */
.qb-possheet-body[b-ey2fgtfege]  .qb-unterform {
    padding-inline-start: var(--qb-space-md);
    border-inline-start: 2px solid var(--qb-surface-border);
}

/* Die Häkchen INNERHALB einer Unterform gehören nicht zur Unterform als Ganzes,
   sondern zu dem Knopf, unter dem sie stehen -- in panel6 der S-Maske sitzen sie
   bei x=46 gegenüber x=15 des Knopfes, also noch einmal eingerückt. Ohne die
   zweite Stufe stünden Knopf und Häkchen auf derselben Kante, und der Knopf
   DARUNTER sähe genauso zugehörig aus wie der darüber. */
.qb-possheet-body[b-ey2fgtfege]  .qb-unterform--checks {
    padding-inline-start: calc(var(--qb-space-md) + var(--qb-space-sm));
}

/* Der Knopf nach den Häkchen braucht die Lücke, die ihn von ihnen trennt. In D3
   liegen zwischen Häkchenzeile (y=23) und zweitem Knopf (y=41) 18 px gegenüber
   16 px zwischen erstem Knopf und Häkchen -- die Häkchen hängen oben an, unten
   lösen sie sich. Im Fließsatz des Gitters ist der Abstand sonst überall gleich
   groß und die Zuordnung damit offen. */
.qb-possheet-body[b-ey2fgtfege]  .qb-unterform--after-checks {
    margin-block-start: var(--qb-space-xs);
}

/* Ein Gitter, auf das direkt Felder folgen, braucht Luft dazwischen -- sonst
   kleben Fahrer 1 und Fahrer 2 an der Unterkante des Fahrzeug-Gitters. In D3
   stehen sie nebeneinander und die Frage stellt sich nicht; in 500 px stehen sie
   darunter. */
.qb-possheet-body[b-ey2fgtfege]  .qb-pos-wrap + .qb-fieldgrid {
    margin-block-start: var(--qb-space-md);
}

/* Die markierte Zeile des Orte-Gitters. D3 hebt sie blau hervor und füllt daneben
   die Frachtgüter dieses Ortes -- ohne sichtbare Markierung wäre nicht zu sehen,
   worauf sich die Tabelle darunter bezieht. */
.qb-possheet-body[b-ey2fgtfege]  tr.qb-pos-selected > td {
    background: var(--qb-surface-sunken);
    font-weight: 600;
}

.qb-possheet-body[b-ey2fgtfege]  tr.qb-pos-selected {
    cursor: default;
}

/* ── Zustandszeile unter dem Kopf ────────────────────────────────────────────
   „Ungespeichert in …" wie im Maskenkopf (PageHead.razor.css, .qb-dirty),
   sonst der Grund, warum das Blatt nur anzeigt. */
.qb-possheet-state[b-ey2fgtfege] {
    padding: var(--qb-space-xxs) var(--qb-space-md);
    font-size: 12px;
    color: var(--qb-warning);
    border-block-end: 1px solid var(--qb-surface-border);
}

.qb-possheet-state--readonly[b-ey2fgtfege] {
    color: var(--qb-text-muted);
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Positionsdetail/PositionDetailStueckliste.razor.rz.scp.css */
/* Die Eckkraft-Tafel des Stuecklisten-Reiters.

   D3 stellt sie als EINE Beschriftung („Eckkraft:") mit zwei Zeilen daneben dar:
   „vertikal [Wert] (o) kN ( ) kNm" und darunter dasselbe fuer „horizontal". Die
   Zusammengehoerigkeit der beiden Zeilen ist die Aussage -- zwei gleichrangige
   Felder „Eckkraft vertikal" und „Eckkraft horizontal" verlieren sie.

   Bereichsbezogenes CSS: die Klassen stehen im Markup dieses Reiters, deshalb
   greifen sie ohne ::deep. Das Einheitenpaar selbst bringt seine eigene Huelle
   (.pd-einheit) mit und wird hier nur ausgerichtet. */

.pd-eckkraft[b-u0gjlbsxul] {
    display: flex;
    flex-direction: column;
    gap: var(--qb-space-xs);
}

.pd-eckkraft__zeile[b-u0gjlbsxul] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-sm);
}

/* Feste Breite, damit „vertikal" und „horizontal" untereinander bündig stehen und
   die Werte eine gemeinsame Kante bekommen -- in D3 leistet das die Spalte des
   TableLayoutPanels. */
.pd-eckkraft__achse[b-u0gjlbsxul] {
    flex: 0 0 5.5rem;
    color: var(--qb-text-subtle);
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Positionsdetail/PositionDetailStuecklisteBearbeiten.razor.rz.scp.css */
/* Die Eingabefelder einer geöffneten Stücklistenzeile. Feste Breiten, damit die Zeile beim Öffnen nicht springt; auf schmalen
   Fenstern rollt die Tabelle quer (PosTable). Die Zellen stehen im Markup dieses Reiters, die Radzen-Felder nicht — deshalb
   td ::deep. */

td[b-zlxwfbmbl4]  .stl-input--s {
    width: 4rem;
}

td[b-zlxwfbmbl4]  .stl-input--m {
    width: 5rem;
}

td[b-zlxwfbmbl4]  .stl-input--l {
    width: 6rem;
}

td[b-zlxwfbmbl4]  .stl-input--xl {
    width: 8rem;
}

td[b-zlxwfbmbl4]  .stl-input--xxl {
    width: 14rem;
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Positionsdetail/StuecklisteTechDataDialog.razor.rz.scp.css */
/* Die Eingabefelder einer geöffneten Zeile. Feste Breiten, damit die Zeile beim Öffnen nicht springt; auf schmalen Fenstern rollt die
   Tabelle quer (PosTable). Die Zellen stehen im Markup dieses Dialogs, die Radzen-Felder nicht — deshalb td ::deep. */

td[b-a7r9gd1asx]  .td-input--pos {
    width: 4rem;
}

td[b-a7r9gd1asx]  .td-input--text {
    width: 14rem;
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/PositionsSicht.razor.rz.scp.css */
/* Die Hülle trägt nur die Höhe weiter: der Rollbereich der Positionstabelle rechnet
   mit ihr (max-height), und ohne durchgereichte Höhe fällt er auf den Inhalt zusammen.

   min-height: 0 gehört dazu -- ein Flex-Kind hat als Vorbelegung
   `min-height: auto` und schrumpft dann NICHT unter seinen Inhalt, womit der
   Rollbereich nie entsteht und die Tabelle die Maske aufbläht. */
.qb-possicht[b-4tvo8gqz62] {
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: 100%;
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Tabs/AuftragPositionTab.razor.rz.scp.css */
/* Werkzeugzeile über der Tabelle: Hinweis links, Knöpfe rechtsbündig.

   Das Konzept führt beides im `.sec-head` der Sicht (Z. 2144–2150, `span.hint` und
   `span.right`). Bei uns steht die Überschrift seit dem 2026-09-01 als SectionHead in
   PositionsSicht, also eine Ebene höher; Hinweis und Knöpfe bleiben hier, weil der
   Fahrer-App-Knopf an der markierten Zeile hängt und die nur diese Sicht kennt. Das
   TODO dazu steht in PositionsSicht.razor.

   Der Abstand nach unten ist der Kartenabstand des Konzepts (12 px = --qb-space-sm),
   nicht der Gruppenabstand: darunter folgt unmittelbar die Tabelle, nicht die nächste
   Gruppe.

   Die Textspalte (.qb-pos-text) stand bis zum 2026-08-31 hier. Sie ist nach
   PosTable.razor.css gewandert: dieselbe Spalte gibt es in allen acht Sichten und in
   der Übersichtskarte, und eine bereichsbezogene Klasse reicht nicht über die
   Komponentengrenze. */
.qb-postools[b-iecl270gcu] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    flex-wrap: wrap;

    margin-block-end: var(--qb-space-sm);
}

.qb-postools-rechts[b-iecl270gcu] {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: var(--qb-space-xxs);
}

/* Bearbeitungszeile der Tabelle: die Eingabefelder füllen ihre Zelle. */
.qb-pos-edit[b-iecl270gcu] {
    padding-top: 0;
    padding-bottom: 0;
}

.qb-pos-edit[b-iecl270gcu]  .rz-numeric,
.qb-pos-edit[b-iecl270gcu]  .rz-dropdown {
    width: 100%;
    min-width: 4.5rem;
}
/* _content/D3.Web/Components/Pages/Auftraege/Detail/Tabs/AuftragUebersichtTab.razor.rz.scp.css */
/* Die Bereichsüberschrift stand hier bis zum 2026-09-01 als `.qb-uebersicht-titel`.
   Sie ist jetzt das Bauteil `SectionHead` -- die Regel steht 56-mal im Konzept und
   gehört damit nicht in eine einzelne Maske.

   Die Zeile mit der großen Ampel und ihrer Bewertung im Klartext.

   Der Prototyp zeigt die große Ampel (`.ampelbox`) links und die Bewertung als
   Wertzeile daneben. Hier stehen Ampel und Satz als eigene Zeile über den Wertzeilen,
   weil der Satz Pflicht ist (MUSS: „Neben der großen Ampel steht die Bewertung im
   Klartext samt Bedingung") und in einer 44-Prozent-Bezeichnungsspalte umbrechen würde.

   Der Abstand nach unten ist die Zeilenlücke der Dichte: darunter folgen unmittelbar die
   Wertzeilen, und die tragen ihre Trennlinien selbst. */

.qb-ampelzeile[b-d8ofj0w2yo] {
    display: flex;
    /* Oben ausgerichtet und nicht mittig: die Karte ist in der Dreispaltigkeit nur ein
       Drittel breit, und der Satz bricht dort auf zwei bis drei Zeilen. Mittig zentriert
       staende die Ampel dann neben der MITTLEREN Zeile und saehe verrutscht aus. */
    align-items: flex-start;
    gap: var(--qb-space-sm);

    margin-block-end: var(--qb-density-gap-y);
}

.qb-ampelzeile-text[b-d8ofj0w2yo] {
    /* min-width: 0 erlaubt dem Text, unter seine eigene Wortbreite zu schrumpfen --
       ohne das dehnt ein langes Wort die Flexzeile und damit die Karte. */
    min-width: 0;

    font-size: 0.875rem;
    line-height: 1.35;
    color: var(--qb-text);
}

/* Hülle um eine Hinweiszeile in einer Übersichtskarte.

   `Hint` zeichnet ein inline `span` und bringt keinen eigenen Abstand mit — richtig so,
   denn im Maskenkopf steht er in einer Reihe mit den Kernfakten. Nach einer Zeitleiste
   oder einer Tabelle klebt er dadurch unmittelbar am Vorgänger.

   Die Hülle löst das hier, statt `Hint` von außen zu stylen: „Keine Anwendung stylt eine
   Komponente von außen" (MUSS, §1.2). Ein `::deep .qb-hint` wäre genau das — und würde
   den Abstand zugleich jedem anderen Hinweis in dieser Maske aufzwingen. */
.qb-uebersicht-hinweis[b-d8ofj0w2yo] {
    display: block;
    margin-block-start: var(--qb-space-xs);
}
/* _content/D3.Web/Components/Pages/Home.razor.rz.scp.css */
/* Startseite. Lag als globaler <style>-Block im Markup.

   ── Korrektur zur dritten Staffel ────────────────────────────────────────
   Hier stand, bereichsbezogenes CSS erreiche diese Klassen direkt, „weil
   Radzen das Bereichsattribut auf sein Wurzelelement durchreicht". **Das ist
   falsch.** Blazor setzt das Attribut nur auf einfache HTML-Elemente des
   eigenen Markups, nie auf Komponenten -- Radzen bekommt es nie zu sehen und
   kann es also auch nicht durchreichen.

   Folge: die Regeln dieser Datei waren seit der dritten Staffel **alle
   wirkungslos**. Am laufenden Server gemessen: die Uhrkarte rendert weiß
   (#FFFFFF, die Kartenfarbe des Themes) statt --qb-primary, und der
   Uhrentext steht in --qb-text statt --qb-on-primary. Lesbar war es -- weiß
   auf weiß entstand nicht, weil auch die Textfarbe ausfiel --, aber die
   Marke war weg.

   Deshalb steht im Markup jetzt eine Hülle <div class="home-page">. Sie ist
   ein einfaches Element, bekommt das Attribut, und ::deep schiebt es auf den
   Vorfahren. Kein display: contents nötig: die Hülle sitzt um zwei
   Wurzelkarten, die ohnehin Blockelemente untereinander sind.

   Auch der zweite Teil des alten Kommentars war irreführend: er las das
   rz-Präfix von .rz-carousel-container als Eigentumsfrage („unsere Klasse,
   also kein ::deep"). Die Eigentumsfrage war richtig beantwortet, die
   Schlussfolgerung falsch -- ::deep hängt nicht daran, wem die Klasse
   gehört, sondern auf welchem **Elementtyp** sie sitzt.

   ── Korrektur eines Farbwerts ────────────────────────────────────────────
   Hier stand „--qb-primary (#2B3455)". In der Odysys-Palette ist
   --qb-primary = $fill-brand-strong = **#16324C**; #2B3455 ist $text-brand
   und liegt auf --qb-primary-accent. Am Browser bestätigt. Die Uhrkarte wird
   damit *dunkler* als das alte #0e395d, nicht heller. Wer Hex-Werte in
   Kommentare schreibt, muss die Palette dazu nennen -- die Anwendung fährt
   odysys.

   ── Was hier verlegt wurde ───────────────────────────────────────────────
   - .clock-card trug #0e395d, ein hart eingebautes Dunkelnavy ohne Rolle.
     Jetzt --qb-primary. Die Karte folgt damit Marke und Modus.
   - .white-text war color: white. Das ist nicht „weiß", sondern „Text auf
     der Markenfläche": --qb-on-primary. Gemessen 13.17:1 gegen --qb-primary.
   - .rz-images-D3Logo ist **ersatzlos entfallen**: die Klasse steht auf
     keinem Element im Projekt (geprüft, sie kam nur in dieser Datei vor).
     Das Logo im Karussell trägt .rz-h-100.

   ── Regel 2 der Bibliotheksregeln ────────────────────────────────────────
   Die Grundlage verlangt: „Keine Anwendung stylt eine Komponente von außen.
   Wer etwas nicht einstellen kann, bekommt ein Token oder einen Parameter --
   nie einen Selektor." Die vier Regeln unten tun genau das, was dort
   verboten ist, nur eben über ::deep statt global. Das ist Übergang, nicht
   Ziel.

   Ein eigenes Bauteil lohnt hier bewusst nicht: die Datei sagt selbst, sie
   sei „a placeholder page and should not be used in the final product", und
   Kapitel 9.19 baut die Startseite als Verteiler mit vier Kennzahlen und
   Gruppenkarten neu. Dann verschwinden diese vier Regeln mitsamt der Hülle. */
.home-scope[b-bus07j5sev]  .clock-card {
    background-color: var(--qb-primary);
}

.home-scope[b-bus07j5sev]  .white-text {
    color: var(--qb-on-primary);
}

.home-scope[b-bus07j5sev]  .text-clock {
    font-weight: 700;
    font-size: 1.8rem;
}

.home-scope[b-bus07j5sev]  .text-date {
    font-size: 1.2rem;
}

.home-scope[b-bus07j5sev]  .rz-carousel-container {
    height: 400px;
    max-width: 600px;
}
/* _content/D3.Web/Components/Pages/Login/Login.razor.rz.scp.css */
/* Anmeldemaske. Lag als globaler <style>-Block im Markup.

   ── Warum fast jede Regel über .login-card-scope ::deep läuft ────────────
   Blazor setzt das Bereichsattribut **nur auf einfache HTML-Elemente** des
   eigenen Markups, nie auf Komponenten. Alle hier gestylten Klassen sitzen auf
   Radzen-Komponenten (`RadzenCard`, `RadzenTemplateForm`, `RadzenStack`,
   `RadzenText`, `RadzenImage`), also greift ein direktes `.rz-card-login { … }`
   nicht -- daraus wird `.rz-card-login[b-x]`, und dieses Attribut trägt die
   Karte nie.

   Am laufenden Server gemessen, bevor der Anker eingezogen wurde: Karte
   853 px statt 320, Titel 16 px statt 35.2, **Logo 1290 px statt 112**,
   Hintergrund weiß statt grau, keine Zentrierung. Der ganze Block war
   wirkungslos. Die Hülle `<div class="login-card-scope">` ist ein einfaches
   Element, bekommt das Attribut, und ::deep schiebt es auf den Vorfahren.
   `display: contents` hält sie aus dem Layout heraus.

   Ausnahme: `.login-failed` sitzt auf einem `<span>` im eigenen Markup und
   bekommt das Attribut direkt -- dort ist ::deep nicht nötig.

   ── Korrektur zur Übergabe ───────────────────────────────────────────────
   Das Inventar nannte „21 Verweise auf Radzen-Interna". Das war eine Zählung
   des Präfixes `rz-`. Genau nachgezählt benutzte der Block **sieben**
   Klassennamen: fünf eigene (`.rz-template-login`, `.rz-card-login`,
   `.rz-stack-login`, `.rz-font-title`, `.rz-images-login`) und zwei fremde
   (`.rz-card` sowie die Kombination `.rz-button.rz-primary.rz-shade-default`).
   Eine sechste eigene Klasse, `.rz-button-login`, steht im Markup, wurde vom
   Block aber nie gestylt.

   Die fünf eigenen kommen nirgends sonst im Projekt vor (geprüft). Sie tragen
   nur das rz-Präfix, genau die Falle aus `Home.razor`. Dass sie trotzdem
   ::deep brauchen, hat einen anderen Grund: nicht Fremdheit der Klasse,
   sondern der Elementtyp, auf dem sie sitzt.

   Wirklich fremd waren zwei Selektoren, und beide sind weg:

   1. `.rz-card` -- traf beide Karten im Dokument. Der Teil, der die äußere
      Fläche meinte, liegt in Layout/LoginLayout.razor.css; Begründung dort.

   2. `.rz-button.rz-primary.rz-shade-default` samt :hover -- ein lokaler
      Nachbau des Hauptknopfs auf eigener Palette:

        --Odysys-Web-Darkblue: #0e395d  als Fläche
        --Odysys-Web-Blue:     #0094ff  als Schrift

      **Ersatzlos entfallen.** Der Knopf ist ein Hauptknopf, und das Theme
      setzt `.rz-button.rz-primary` auf `var(--rz-primary)`/`var(--rz-on-primary)`,
      was in diesem Fork auf `--qb-primary`/`--qb-on-primary` zeigt. Der Block
      hat also die Token überschrieben, statt sie zu benutzen.

      Das behebt einen Mangel: gemessen war #0094ff auf #0e395d bei
      **3.79:1** -- unter den 4.5:1, die Knopfschrift braucht. Weiß auf
      --qb-primary (#16324C) liegt bei 13.17:1, am laufenden Server
      nachgemessen. Diese eine Änderung wirkte übrigens schon vor dem Anker,
      weil eine *Löschung* kein Bereichsattribut braucht.

      Mit dem Knopf sind der frei gewählte Schlagschatten und das
      translateY(-2px) beim Überfahren entfallen; das Theme hat einen eigenen
      Überfahr-Zustand.

   Der :root-Block mit den vier --Odysys-* ist ebenfalls entfallen.
   --Odysys-Yellow und --Odysys-Darkyellow referenzierte niemand, auch nicht
   im Block selbst; die beiden Blau-Werte nur die gelöschten Knopfregeln.
   Nebenbei: ein :root in einer Komponente setzt globale Variablen, solange
   diese Seite im DOM steht -- eine Definition, die mit der Navigation kommt
   und geht. */

.login-card-scope[b-f61yc50rmu] {
    display: contents;
}

/* align-items: center ist entfallen -- an einem display: block wirkt es
   nicht. Der Block bleibt: das Formular ist Flex-Kind der Karte. */
.login-card-scope[b-f61yc50rmu]  .rz-template-login {
    display: block;
}

/* Die Anmeldekarte zentriert ihren Inhalt. Falle: ohne Flex greift die
   Spaltenbreite (Size="4", also ein Drittel) auf den 270-px-Stapel durch und
   die Maske bricht auseinander.

   background-color: white ist entfallen. Es hat nur die lokale
   `.rz-card`-Regel (#eee) zurückgenommen, die es nicht mehr gibt; die
   Kartenfarbe des Themes ist --qb-surface-overlay und in beiden Modi
   derselbe Wert wie --qb-surface. Ebenso die vier `height: auto` aus den
   Höhen-Abfragen: sie haben die 95vh/85vh der äußeren Regel abgewehrt, die
   diese Karte jetzt nicht mehr trifft. */
.login-card-scope[b-f61yc50rmu]  .rz-card-login {
    display: flex;
    justify-content: center;
    align-items: center;
}

/* Die Fehlmeldung stand als style="color: var(--rz-danger-dark)" im Markup --
   dieselbe Umleitung wie in der Fehlerseite, hier zusätzlich inline. Die
   Rolle für Text auf der Fläche ist der Akzent. Gemessen gegen die weiße
   Karte: 6.07:1. Kein ::deep -- das <span> ist unser eigenes Element. */
.login-failed[b-f61yc50rmu] {
    color: var(--qb-error-accent);
}

/* Zwei Größenstufen, unverändert übernommen. 480 px entspricht
   --qb-breakpoint-mobile -- als Token nicht einsetzbar, Medienabfragen lesen
   keine Custom Properties. Die 680 px Höhe hat keinen Token.

   Stehengelassen, aber vermerkt: bei genau 480 px Breite bzw. 680 px Höhe
   greifen beide Abfragen, und die zweite gewinnt durch ihre Stellung. Die
   Bruchpunkte sind fachlich offen (Inventar), deshalb hier keine Korrektur. */
@media (min-width: 480px), (min-height: 680px) {
    .login-card-scope[b-f61yc50rmu]  .rz-stack-login {
        width: 270px;
    }

    .login-card-scope[b-f61yc50rmu]  .rz-card-login {
        width: 320px;
    }

    .login-card-scope[b-f61yc50rmu]  .rz-font-title {
        font-size: 2.2rem;
    }

    .login-card-scope[b-f61yc50rmu]  .rz-images-login {
        width: 7rem;
    }
}

@media (max-width: 480px), (max-height: 680px) {
    .login-card-scope[b-f61yc50rmu]  .rz-stack-login {
        width: 200px;
    }

    .login-card-scope[b-f61yc50rmu]  .rz-card-login {
        width: 250px;
    }

    .login-card-scope[b-f61yc50rmu]  .rz-font-title {
        font-size: 1.6rem;
    }

    .login-card-scope[b-f61yc50rmu]  .rz-images-login {
        width: 6rem;
    }
}
/* _content/D3.Web/Components/Pages/Plantafel/Plantafel.razor.rz.scp.css */
body[b-vm1b60ctvv],
html[b-vm1b60ctvv] {
    margin: 0;
    display: flex;
    flex-direction: column;
    height: 100vh;
    font-family: Poppins, "Open Sans", Helvetica, Arial, sans-serif;
    font-size: 14px;
    background-color: lightgray;
}

#head-container[b-vm1b60ctvv] {
    flex-direction: column;
    padding: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

#container[b-vm1b60ctvv] {
    position: relative;
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    transform: translate(0, 0);
    overflow: hidden;
}

#plantafel-container[b-vm1b60ctvv] {
    display: flex;
    flex-direction: row;
    height: auto;
    flex: 0%;
}

.b-gridbase.b-autoheight[b-vm1b60ctvv] {
    height: 100%;
    flex: 0%;
}

.test[b-vm1b60ctvv] {
    color: #000;
    font-weight: bolder;
}


.ungrid[b-vm1b60ctvv] {
    background-color: #0000ff;
    color: #fff;
    font-weight: bolder;
}

/* Unplanned Events Grid */
.unplanned-event[b-vm1b60ctvv] {
    display: flex;
}

.unplanned-event-container[b-vm1b60ctvv] {
    display: flex;
    flex-direction: column;
    /* margin-right: 5% 0;  */
    padding: 7.5px;
    width: 100%;
    overflow: hidden;
    background-color: blue;
    /* border-top-right-radius: 12px;  */
    /* border-bottom-right-radius: 12px;  */
    font-weight: 900;
    /* box-shadow:  2px 2px 2px rgba(0,0,0,1); */
}

.unplanned-event-footer[b-vm1b60ctvv] {
    color: #d4d4d4;
    text-align: right;
}

.unplanned-event-time[b-vm1b60ctvv] {
    color: #d4d4d4;
    padding-top: 2.5px
}

.unplanned-event-header[b-vm1b60ctvv] {
    color: white;
}

/* Tooltip */
.info-container[b-vm1b60ctvv] {
    padding-left: 1rem;
    flex-direction: column;
    display: flex;
    flex-direction: row;
    padding-bottom: 0.2rem;
    margin: 1px;
    box-shadow: 1px 1px 1px rgba(0,0,0,1);
    background-color: #535352;
    font-size: 12px;
}

    .info-container a[b-vm1b60ctvv] {
        color: #fff;
    }

.info-container-header[b-vm1b60ctvv] {
    padding-left: 0.1rem;
    padding-top: 0.2rem;
    width: 10em;
    font-weight: bold;
    font-size: 13px;
}

.info-container-content[b-vm1b60ctvv] {
    flex-direction: column;
    padding-right: 0.1rem;
    padding-top: 0.2rem;
    max-width: 15em;
    hyphens: auto;
}

/* Events */
.event-container[b-vm1b60ctvv] {
    display: flex;
    flex-direction: column;
    margin-right: 5%;
    padding: 7.5px;
    overflow: hidden;
    border-top-right-radius: 12px;
    border-bottom-right-radius: 12px;
    font-weight: 900;
}

.event-container-content[b-vm1b60ctvv] {
    padding-top: 7.5px;
    font-weight: 300;
}
/* _content/D3.Web/Components/Pages/Rechnungsportal/Components/Workflow/WorkflowStepItem.razor.rz.scp.css */
/* Schrittsymbol der Workflow-Kette. Lag als globaler <style>-Block im Markup.

   Aufgeräumt: .workflow-step-open war zweimal definiert, einmal für Fläche
   und Rahmen, einmal nur für die Schriftfarbe. Zusammengeführt.

   Rückfallwerte entfernt (#2196F3, #E0E0E0, #9E9E9E waren Material-Töne,
   die im Dunkelmodus gewonnen hätten). Die Schriftfarbe lag auf "white" --
   gemeint ist "Text auf der gefüllten Fläche", also die on-Rolle je
   Variante; deshalb erbt .step-number sie jetzt statt sie selbst zu setzen.

   ACHTUNG, offener Punkt: Kapitel 9.16 verlangt ein anderes Zustandsmodell --
   erledigt (gefüllt mit Haken, Akzent), aktuell (Ring mit Punkt,
   Odysys-Gelb), offen (leerer Ring). Hier sind es heute Erfolg / Info /
   gedämpft, also drei andere Aussagen. Das ist ein Umbau, kein Verlegen von
   Stilen, und im Inventar bei 9.16 vermerkt. Diese Datei bildet den heutigen
   Zustand ab, nur mit Rollen statt Zahlen. */
.workflow-step-icon[b-qjtop9w0ja] {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.workflow-step-completed[b-qjtop9w0ja] {
    background-color: var(--qb-success);
    color: var(--qb-on-success);
}

.workflow-step-open[b-qjtop9w0ja] {
    background-color: var(--qb-info);
    border: 2px solid var(--qb-info);
    color: var(--qb-info-accent);
}

.workflow-step-disabled[b-qjtop9w0ja] {
    background-color: var(--qb-surface-border);
    color: var(--qb-text-muted);
}

.step-number[b-qjtop9w0ja] {
    font-weight: 600;
    font-size: 0.875rem;
    color: inherit;
}
/* _content/D3.Web/Components/Pages/Rechnungsportal/RechnungsportalPage.razor.rz.scp.css */
/* Rechnungsportal. Lag als globaler <style>-Block im Markup.

   ── Die drei Typografieklassen sind hier weg ─────────────────────────────
   .text-header-small, .text und .text-subtitle standen nach der dritten
   Staffel byte-identisch in vier Dateien. Diese Datei benutzte sie im eigenen
   Markup **gar nicht** -- vor der Migration wirkte ihre eine Definition aus
   dem globalen <style>-Block in die Kindkomponenten hinein, und beim Verlegen
   bekam jedes Kind eine Kopie, während hier eine ohne Aufrufstelle
   zurückblieb.

   Wirksam war ohnehin keine: die Klassen saßen auf RadzenText, und Blazor
   setzt das Bereichsattribut nur auf einfache HTML-Elemente. Alle vier
   Kopien sind durch das Bauteil SectionLabel abgelöst; Begründung dort.

   ── Warum .invoice-tabs einen Anker braucht ──────────────────────────────
   Dieselbe Ursache: die Klasse sitzt auf <RadzenTabs>, einer Komponente. Ohne
   Anker wäre `.invoice-tabs { … }` zu `.invoice-tabs[b-x]` geworden -- und
   damit war auch die ::deep-Kette darunter wirkungslos, denn ihr *Anker* trug
   das Attribut nicht. Ein korrekt geschriebenes ::deep hilft nichts, wenn das
   Element davor eine Komponente ist.

   Die Hülle <div class="invoice-tabs-scope"> trägt `display: contents`: die
   Reiter sind Flex-Kind der umgebenden RadzenCard (`flex: 1` inline), und ein
   zusätzlicher Block dazwischen hätte diese Kette unterbrochen.

   ── Regel 2 der Bibliotheksregeln ────────────────────────────────────────
   Die Grundlage verlangt: „Keine Anwendung stylt eine Komponente von außen.
   Wer etwas nicht einstellen kann, bekommt ein Token oder einen Parameter --
   nie einen Selektor." Die vier Regeln unten verstoßen dagegen. Sie bleiben,
   solange die Reiter von Radzen kommen -- Kapitel 9.13 sagt ausdrücklich,
   dass ein Eigenbau erst infrage kommt, wenn er Reiterrolle, Auswahlzustand,
   Pfeiltasten und wandernden Tabindex mitbringt. Bis dahin ist das eine
   bewusste, hier vermerkte Schuld, kein Versehen.

   Das !important an `flex: none` ist entfallen: mit dem Anker erreicht der
   Selektor 0,3,0 und gewinnt gegen Radzens Regel. Falls die Reiter doch
   wieder auseinanderlaufen, ist das der Grund -- dann nachmessen, nicht
   !important zurückholen. */

.invoice-tabs-scope[b-s5jv1oyr8r] {
    display: contents;
}

.invoice-tabs-scope[b-s5jv1oyr8r]  .invoice-tabs {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.invoice-tabs-scope[b-s5jv1oyr8r]  .invoice-tabs > .rz-tabview-nav {
    flex-shrink: 0;
}

.invoice-tabs-scope[b-s5jv1oyr8r]  .invoice-tabs > .rz-tabview-nav li {
    flex: none;
}

.invoice-tabs-scope[b-s5jv1oyr8r]  .invoice-tabs > .rz-tabview-panels {
    flex: 1;
    overflow: auto;
}
/* _content/D3.Web/Components/Pages/Rechnungsportal/Tabs/Components/History/HistoryItem.razor.rz.scp.css */
/* Verlaufseintrag. Lag als globaler <style>-Block im Markup.

   Vier harte Material-Töne abgelöst -- sie entsprachen genau den
   Severity-Rollen, waren aber Zahlen und blieben deshalb im Dunkelmodus
   stehen:

     #4CAF50 -> --qb-success
     #FF9800 -> --qb-warning
     #F44336 -> --qb-error
     #2196F3 -> --qb-info

   Das ist eine sichtbare Änderung: die QB-Palette ist gedeckter als die
   Material-Töne. Dafür folgen die Symbole jetzt Modus und Marke.

   Die Symbolfarbe lag auf "white". Gemeint ist "Symbol auf der gefüllten
   Fläche", also die on-Rolle je Variante -- deshalb setzt jede Variante ihre
   Farbe und das Symbol erbt sie. ::deep ist nötig, weil .rzi von RadzenIcon
   gerendert wird, nicht in diesem Component. */
.history-icon[b-72s4oo9bk0] {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.history-icon[b-72s4oo9bk0]  .rzi {
    font-size: 1.25rem;
    color: inherit;
}

.history-icon-success[b-72s4oo9bk0] {
    background-color: var(--qb-success);
    color: var(--qb-on-success);
}

.history-icon-warning[b-72s4oo9bk0] {
    background-color: var(--qb-warning);
    color: var(--qb-on-warning);
}

.history-icon-error[b-72s4oo9bk0] {
    background-color: var(--qb-error);
    color: var(--qb-on-error);
}

.history-icon-info[b-72s4oo9bk0] {
    background-color: var(--qb-info);
    color: var(--qb-on-info);
}

/* Der Kommentarblock. --rz-base-400 als Kante war der Feldrahmenton; die
   Rolle hier ist die stärkere Trennlinie, also --qb-border-strong. */
.history-comment[b-72s4oo9bk0] {
    background-color: var(--qb-surface-raised);
    border-inline-start: 3px solid var(--qb-border-strong);
    padding-block: var(--qb-space-sm);
    padding-inline: var(--qb-space-md);
    margin-block-start: var(--qb-space-xs);
    border-radius: 0 var(--qb-radius-card) var(--qb-radius-card) 0;
}
/* _content/D3.Web/Components/Pages/Rechnungsportal/Tabs/PositionTab.razor.rz.scp.css */
/* Fußbereich der Positionsliste. Lag als globaler <style>-Block im Markup.

   ── Anker nachgezogen ────────────────────────────────────────────────────
   Beide Klassen sitzen auf Radzen-Komponenten (RadzenStack, RadzenText), und
   Blazor setzt das Bereichsattribut nur auf einfache HTML-Elemente. Ohne
   Anker waren die Regeln seit der dritten Staffel wirkungslos -- der
   Fußbereich stand ohne gedämpfte Fläche, ohne Radius und ohne Polster,
   die Summe in normaler Textgröße.

   Die Hülle <div class="positions-footer-scope"> trägt display: contents,
   weil der Fußbereich Flex-Kind des umgebenden RadzenStack ist.

   Regel 2 der sechs Bibliotheksregeln („nie einen Selektor") ist damit
   weiterhin nicht erfüllt; das ist Übergang. Für .positions-footer-background
   ist das Ziel eine QB-Karte mit gedämpfter Fläche als Parameter. Die
   Summenzeile ist bewusst *kein* SectionLabel geworden: 1.125rem/700 ist eine
   vierte Rolle, und es ist eine Wertanzeige, keine Beschriftung -- ein
   Bauteil dafür lohnt bei einer Aufrufstelle nicht.

   ── Werte, unverändert aus der dritten Staffel ───────────────────────────
   - var(--qb-surface-raised) -> --qb-surface-raised. Der Rückfallwert war
     ein Grauton, der im Dunkelmodus gewonnen hätte, wäre er je erreicht
     worden.
   - border-radius: var(--rz-gap) war ein Abstandstoken als Radius. Jetzt
     --qb-radius-card, weil das ein Behälter ist.
   - var(--rz-text-title-color) -> --qb-text. Eine eigene Titelfarbe gibt es
     im QB-Vokabular nicht; Titel unterscheiden sich über Größe und
     Gewicht. */

.positions-footer-scope[b-shjfdshrsy] {
    display: contents;
}

.positions-footer-scope[b-shjfdshrsy]  .positions-footer-background {
    background: var(--qb-surface-raised);
    border-radius: var(--qb-radius-card);
    padding: var(--qb-space-md);
}

.positions-footer-scope[b-shjfdshrsy]  .position-footer-summary-text {
    color: var(--qb-text);
    font-weight: 700;
    font-size: 1.125rem;
}
/* _content/D3.Web/Components/Pages/Stammdaten/Bauvorhaben/Tabs/BauvorhabenAllgemein/BauvorhabenAllgemeinTab.razor.rz.scp.css */
/* Aktionszeile unter der Ueberschrift der Karte "Beteiligte Unternehmen".

   Dieselbe Aufteilung wie `.slots-head` in NiederlassungBankverbindungenTab:
   die Aktion rechts, unter der Ueberschrift statt daneben -- die Ueberschrift
   traegt in der Variante Fieldgroup ihre eigene Linie ueber die ganze Breite
   und laesst daneben keinen Platz.

   ACHTUNG, das ist die zweite Stelle mit dieser Form. Wird es eine dritte,
   gehoert sie in ein Bauteil (vermerkt in UI-TODO 7b). */
.unternehmen-head[b-quthpcymne] {
    display: flex;
    justify-content: flex-end;
    margin-block-end: var(--qb-space-sm);
}
/* _content/D3.Web/Components/Pages/Stammdaten/Sperrvermerke/Tabs/SperrvermerkTab.razor.rz.scp.css */
/* Maske Sperrvermerke nach dem Designer-Konzept (Downloads/Sperrvermerke.html, 2026-09-09).

   Werte aus dem Konzept, mit den qb-Token statt der Konzeptfarben (Konzeptfarbe -> Token):

     Karte      KEINE eigene Breite. Das Konzept zeigt die Karte 1184 px breit; eine
                Begrenzung gehoert aber ans gemeinsame Bauteil (CardStack/MaskShell,
                REFERENZ-REGELN Bauplan: hoechstens 760 px), nicht an eine einzelne Maske --
                Entscheidung 2026-09-09. Bis dahin laeuft sie wie alle Karten ueber die volle Breite.
     Kopfzeile  NICHT aus dem Konzept: SectionLabel/Fieldgroup des Hauses (Akzentfarbe,
                Linie), Filter in der Zeile darunter wie bei den anderen Karten
     Spalten    grid 2, Abstand 24 -> --qb-space-lg
     Zeile      grid 24px minmax(0,1fr) 74px, gap 10 -> --qb-space-xs (8), Hoehe 34
                -> --qb-density-row-height (28/32/36); Linien wie PosTable
                (Zeile --qb-surface-border, Kopf --qb-border-strong) statt der
                Konzeptwerte -- Tabellenlinien sind Hausform, nicht Modulform
     Zeilenkopf 10.5px/700, .6px, Versalien, #8494a0 -> --rz-grid-header-*
     Nr         12px/600, #8494a0 -> --qb-text-subtle, Tabellenziffern
     Eingabe    26px -> --qb-density-field-height (26/30/34), Radius aus dem Theme;
                belegt: Rand #bcc7d0 = Theme-Standard (--qb-border-strong), Flaeche weiss;
                frei:   Rand #e2e8ed -> --qb-surface-border, Flaeche #f6f8fa -> --qb-surface-raised
     Punkt      5px rund, links vom Feld (-7px), #1a86b0 -> --qb-interactive
     Schalter   36 x 19 Pille, Knopf 15 weiss; an #1a86b0/#116588 -> --qb-interactive/-strong;
                aus #eef3f5/#bcc7d0 -> --qb-surface-sunken/--qb-border-strong;
                gesperrt #f6f8fa/#e2e8ed -> --qb-surface-raised/--qb-surface-border

   Die Radzen-Token (--rz-input-*) stehen auf dem eigenen Element -- so wie QbDataGrid
   --rz-grid-border-radius und NavigationSidebar --rz-icon-size setzen; kein Selektor auf
   die Komponente. 24/74 px der Nummern- und Schalterspalte bleiben Zahlen, weil sie
   Spaltenbreiten dieser Tabelle sind und keine Abstaende der Layoutskala (PosTable). */

/* Titelzeile: das SectionLabel behaelt die volle Breite, damit seine Linie wie im Konzept
   unter der ganzen Zeile durchlaeuft. Der Filter liegt rechts UEBER der Linie auf dem leeren
   Teil der Titelzeile. Unterkante des Filters = Oberkante der Linie: das SectionLabel traegt
   unter der Linie 12 px Abstand und die Linie selbst 1 px (SectionLabel.razor.css, .fgh),
   deshalb 13 px vom unteren Rand. Die Kaestchenzeile (Feldhoehe 30 px) ragt damit ein paar
   Pixel ueber den Titeltext hinaus, in das Polster der Karte -- nicht in die Linie. */
.sv-head[b-la3tpoihel] {
    position: relative;
    /* flow-root: der untere Abstand des SectionLabels (12 px) darf nicht durch den Wrapper
       nach aussen kollabieren -- sonst ist der Wrapper nur 26 px hoch, und der Filter mit
       "13 px vom unteren Rand" landet 11 px ueber der Linie statt darauf (gemessen 2026-09-09:
       Filterunterkante 154, Linie 165). */
    display: flow-root;
}

.sv-toolbar[b-la3tpoihel] {
    position: absolute;
    inset-inline-end: 0;
    inset-block-end: 13px;
    white-space: nowrap;
}

.sv-columns[b-la3tpoihel] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--qb-space-lg);
}

.sv-col[b-la3tpoihel] {
    min-width: 0;
}

.sv-row[b-la3tpoihel] {
    display: grid;
    grid-template-columns: 24px minmax(0, 1fr) 74px;
    align-items: center;
    gap: var(--qb-space-xs);
    min-height: var(--qb-density-row-height);
    /* Keine Linie zwischen den Zeilen: die Felder tragen ihren Rand selbst, eine Linie
       dazu waere eine zweite Kontur je Zeile (Entscheidung 2026-09-09). Nur die Kopfzeile
       behaelt ihre Linie. */
}

.sv-row--head[b-la3tpoihel] {
    min-height: 26px;
    font-size: var(--rz-grid-header-font-size);
    line-height: var(--rz-grid-header-line-height);
    font-weight: var(--rz-grid-header-font-weight);
    text-transform: var(--rz-grid-header-text-transform);
    color: var(--rz-grid-header-color);
    letter-spacing: 0.6px;
    border-block-end: 1px solid var(--qb-border-strong);
}

.sv-nr[b-la3tpoihel] {
    text-align: right;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--qb-text-subtle);
    font-variant-numeric: tabular-nums;
}

.sv-c[b-la3tpoihel] {
    text-align: center;
}

.sv-field[b-la3tpoihel] {
    --rz-input-height: var(--qb-density-field-height);
    position: relative;
    min-width: 0;
    /* 4 px Luft oben und unten: das Konzept setzt ein 26-px-Feld in eine 34-px-Zeile, also
       8 px Abstand zwischen zwei Feldern. Unser Feld ist in der Normaldichte 30 px, die Zeile
       wird damit 39 px (30 + 8 + 1 px Linie), Abstand Feld zu Feld 9 px -- gemessen
       2026-09-09. Ohne das Polster klebten die Felder mit 2 px aneinander; die
       Zeilenhoehe des Rasters (--qb-density-row-height, 32) allein reicht nicht, weil das
       Feld sie fast ausfuellt. */
    padding-block: var(--qb-space-xxs);
}

.sv-field--frei[b-la3tpoihel] {
    --rz-input-background-color: var(--qb-surface-raised);
    --rz-input-border: 1px solid var(--qb-surface-border);
    --rz-input-border-block-end: 1px solid var(--qb-surface-border);
}

/* 6 px statt der 5 px des Konzepts und ganzzahliger Versatz: bei 5 px mit -2,5 px landete der
   Punkt auf halben Pixeln und wurde unscharf, "gequetscht" (Entscheidung 2026-09-09). */
.sv-dot[b-la3tpoihel] {
    position: absolute;
    inset-inline-start: -7px;
    top: calc(50% - 3px);
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: transparent;
}

.sv-dot--on[b-la3tpoihel] {
    background: var(--qb-interactive);
}

.sv-toggle[b-la3tpoihel] {
    display: flex;
    justify-content: center;
}

.sv-switch[b-la3tpoihel] {
    position: relative;
    width: 36px;
    height: 19px;
    padding: 0;
    border: 1px solid var(--qb-border-strong);
    border-radius: 99px;
    background: var(--qb-surface-sunken);
    cursor: pointer;
}

.sv-switch--on[b-la3tpoihel] {
    border-color: var(--qb-interactive-strong);
    background: var(--qb-interactive);
}

.sv-switch:disabled[b-la3tpoihel] {
    border-color: var(--qb-surface-border);
    background: var(--qb-surface-raised);
    cursor: default;
}

.sv-switch:focus-visible[b-la3tpoihel] {
    outline: var(--rz-outline-width) solid var(--qb-interactive);
    outline-offset: 1px;
}

.sv-switch-knob[b-la3tpoihel] {
    position: absolute;
    top: 1px;
    inset-inline-start: 1px;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--qb-surface);
    box-shadow: var(--rz-shadow-1);
    transition: var(--qb-transition-fast);
}

.sv-switch--on .sv-switch-knob[b-la3tpoihel] {
    inset-inline-start: 18px;
}

@media (prefers-reduced-motion: reduce) {
    .sv-switch-knob[b-la3tpoihel] {
        transition: none;
    }
}

/* Unter der Formularbreite werden die zwei Spalten eine. Kein Inhalt verschwindet (MUSS). */
@media (max-width: 720px) {
    .sv-columns[b-la3tpoihel] {
        grid-template-columns: minmax(0, 1fr);
    }
}
/* _content/D3.Web/Components/Pages/Systemdaten/Firmen/Tabs/FirmaTab.razor.rz.scp.css */
/* Zeile unter der Ueberschrift der Adresskarte: links der Adressart-Radio, direkt danach die
   Aktion "PLZ/Ort". Beides linksbuendig in einer Zeile.

   Warum links und nicht "Radio links, Knopf rechts" (so stand es bis zum 2026-09-11):
   der Knopf nimmt die PLZ des Zweigs, den der Radio waehlt -- die beiden gehoeren zusammen.
   Practical UI (Layout: Naehe zeigt Zusammengehoerigkeit; Buttons: linksbuendig, rechts
   werden sie auf grossen Bildschirmen uebersehen und liegen weit weg vom Feld, auf das sie
   wirken). Ueber 1.500 px Leerraum dazwischen sagte das Gegenteil; Rückmeldung: "das eine ganz
   links und das andere ganz rechts sieht UI-technisch nicht so gut aus".

   Der Abstand Radio-Gruppe -> Knopf (--qb-space-lg) ist groesser als der zwischen den
   beiden Radios (16 px), damit lesbar bleibt: zwei Dinge, aber eine Zeile.

   Aktion UNTER der Ueberschrift statt daneben, weil SectionLabel in der Variante Fieldgroup
   seine Linie ueber die ganze Breite traegt (BauvorhabenAllgemeinTab.razor.css). Bauvorhaben
   setzt seine Kartenaktion rechts -- dort steht sie allein in der Zeile und wirkt auf die
   Liste darunter; fuer "Knopf neben Radio" gibt es im Haus kein Vorbild. */
.adresse-head[b-hr454yyaum] {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    gap: var(--qb-space-lg);
    margin-block-end: var(--qb-space-sm);
}
/* _content/D3.Web/Components/Pages/Systemdaten/Niederlassungen/Tabs/NiederlassungBankverbindung/NiederlassungBankverbindungenTab.razor.rz.scp.css */
/* Kopfzeile der Slotliste: Hinweis links, Aktion rechts.

   Der Prototyp fuehrt beides in `.sec-head` neben der Ueberschrift
   (`display:flex; align-items:baseline; gap:10px`, die Aktion ueber
   `.right{margin-left:auto}`). Bei uns traegt die Ueberschrift der Karte das
   SectionLabel in der Variante Fieldgroup und bringt ihre eigene Trennlinie
   mit -- Hinweis und Knopf stehen deshalb in der Zeile darunter, mit
   derselben Aufteilung. */
.slots-head[b-h8rfjnqlsk] {
    display: flex;
    align-items: baseline;
    gap: var(--qb-space-sm);
    margin-block-end: var(--qb-space-sm);
}

.slots-head[b-h8rfjnqlsk]  .rz-button {
    margin-inline-start: auto;
}

.zurueck[b-h8rfjnqlsk] {
    margin-block-end: var(--qb-space-sm);
}

/* Die Kennzeichnung der Standardverbindung.

   Der Prototyp zeigt hier `.chip.on` -- den Zustandschip mit Punkt. Der ist
   Teil der zurueckgestellten Phase 4 (`StatusChip`). Hier steht
   deshalb bewusst KEIN zweiter Chip, sondern nur der Text in der Akzentrolle:
   sobald StatusChip kommt, wird diese Stelle darauf gezogen statt zwei
   Chip-Definitionen zusammenfuehren zu muessen. */
.standard[b-h8rfjnqlsk] {
    color: var(--qb-interactive-strong);
    font-weight: 600;
}
/* _content/D3.Web/Components/Pages/Systemdaten/Niederlassungen/Tabs/NiederlassungZusatz2/NiederlassungZusatz2Tab.razor.rz.scp.css */
/* Spaltenabstände der Tabellendarstellung. Lag als globaler <style>-Block.

   Werte auf die Abstandsskala gelegt: 32 -> --qb-space-xl,
   24 -> --qb-space-lg, 8 -> --qb-space-xs. Alle drei lagen schon auf dem
   4-px-Raster, es ist also eine reine Umbenennung ohne Wertänderung.

   Die Klassennamen tragen einen Schreibfehler (tabel statt tabelle).
   Bewusst nicht umbenannt: das berührt die Aufrufstellen und gehört zum
   Umbau der Maske, nicht zum Verlegen der Stile. */
.tabel-item1[b-69jt2culs0] {
    padding-inline-end: var(--qb-space-xl);
}

.tabel-item2[b-69jt2culs0] {
    padding-inline-end: var(--qb-space-lg);
}

.tabel-header[b-69jt2culs0] {
    padding-inline-end: var(--qb-space-xs);
}
/* _content/D3.Web/Components/Shared/Basicdata/ControlStrip.razor.rz.scp.css */
/* Werte aus .savebar des Prototyps: Fläche und Linie oben, seitliches Polster
   wie der Seitenkörper, senkrecht auf die Abstandsleiter gerundet (Prototyp
   7 px).

   Kein position: fixed wie im Prototyp -- die Leiste liegt als letztes
   Flex-Kind von .qb-mask schon unter dem Rollbereich und steht damit ohnehin.
   Deshalb braucht der Inhalt auch die 70 px Bodenfreiraum nicht, die der
   Prototyp reserviert, weil seine Leiste über dem Inhalt liegt. */
.qb-savebar[b-7du2nwzmll] {
    flex: 0 0 auto;

    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);

    padding: var(--qb-space-xs) var(--rz-layout-body-padding);

    background: var(--qb-surface);
    border-top: 1px solid var(--qb-surface-border);
}

/* Nimmt den freien Platz, damit die Knöpfe rechts stehen -- im Prototyp
   macht das .savebar .grow. */
.qb-savebar-msg[b-7du2nwzmll] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xxs);
    flex: 1 1 auto;
    min-width: 0;
}

/* Werte aus .savebar .msg des Prototyps: 12 px in gedecktem Ton. Der Punkt
   kommt als ::before in Signalfarbe -- so liegen Punkt und Text auf derselben
   Mitte, ohne dass ein fremder Aussenrand das Zentrieren verschiebt. */
.qb-savebar-hint[b-7du2nwzmll] {
    display: inline-flex;
    align-items: center;
    gap: var(--qb-space-xxs);

    font-size: 0.75rem;
    color: var(--qb-text-muted);
}

.qb-savebar-hint[b-7du2nwzmll]::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--qb-warning);
}
/* _content/D3.Web/Components/Shared/Components/Ampel.razor.rz.scp.css */
/* Ampel. Maße aus dem Kompakt-Konzept v3:

     .ampel      display:inline-flex; align-items:center; gap:4px;
                 padding:3px 8px; border-radius:99px            (Z. 195–196)
     .ampel i    8px, rund                                       (Z. 197)
     .ampelbox   Spalte, gap:4px, radius:7px, padding:6px 5px    (Z. 189–190)
     .ampelbox i 13px, rund                                      (Z. 191)

   ABWEICHUNG vom Prototyp, bewusst: dort ist das Gehäuse `#3a4048` und die
   dunkle Lampe `#22262b`. Für „dunkles Gehäuse" gibt es im Tokensatz keine
   Rolle, und der Dunkelmodus belegt jede Rolle neu -- ein hartes Hex wäre im
   Dark entweder unsichtbar oder falsch, und Rückfallwerte in var() sind
   verboten (§1.2). `--qb-surface-inverse` wäre der nächste Kandidat, kippt im
   Dark aber auf Hell (#E2E9EE) und damit ins Gegenteil.

   Gebaut ist das Gehäuse deshalb aus zwei Rollen, die in beiden Modi tragen:
   Fläche `--qb-surface-sunken` (dieselbe wie beim schreibgeschützten Feld) mit
   1-px-Kante `--qb-surface-border`. Es liest sich als Instrument, nicht als
   Loch. LÜCKE für §10: eine Rolle „Gehäuse/Instrumentenfläche" fehlt.

   Die dunkle Lampe ist `--qb-border-strong` -- die Rolle des Feldrahmens, in
   beiden Modi deutlich gegen die Gehäusefläche und erkennbar „aus". */

.qb-ampel[b-n8s64dwa7o] {
    display: inline-flex;
    align-items: center;
    gap: var(--qb-space-xxs);

    padding: 3px var(--qb-space-xs);
    border: 1px solid var(--qb-surface-border);
    border-radius: 99px;
    background: var(--qb-surface-sunken);

    flex-shrink: 0;
}

.qb-ampel-lampe[b-n8s64dwa7o] {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--qb-border-strong);
}

/* Nur Grün kann heute leuchten (AmpelBewertung). Rot und Amber haben keine
   eigene --an-Regel, weil sie ohne fachliche Schwellen nicht gesetzt werden
   dürfen -- eine Regel ohne Treffer wäre eine stille Behauptung. */
.qb-ampel-lampe--gruen.qb-ampel-lampe--an[b-n8s64dwa7o] {
    background: var(--qb-ampel-green);
}

/* Große Ausführung: senkrecht, wie .ampelbox des Prototyps. Der Radius ist die
   Kartenrolle, nicht die 7px des Prototyps -- zwei Radiusrollen, mehr gibt es
   nicht (§5.2). */
.qb-ampel--lg[b-n8s64dwa7o] {
    flex-direction: column;
    gap: var(--qb-space-xxs);
    padding: 6px 5px;
    border-radius: var(--qb-radius-card);
}

.qb-ampel--lg .qb-ampel-lampe[b-n8s64dwa7o] {
    width: 13px;
    height: 13px;
}

/* Der Schein macht den Unterschied zwischen „leuchtet" und „ist grün gefärbt".
   Nur an der großen Lampe, wie im Prototyp (`.ampelbox i.g.on`); die kleine im
   Maskenkopf bleibt flach, dort wäre der Schein bei 8 px ein Fleck. */
.qb-ampel--lg .qb-ampel-lampe--gruen.qb-ampel-lampe--an[b-n8s64dwa7o] {
    box-shadow: 0 0 6px var(--qb-ampel-green);
}
/* _content/D3.Web/Components/Shared/Components/CardStack.razor.rz.scp.css */
/* Abstand zwischen Karten — die eine Stelle, an der diese Zahl steht.

   Prototyp:
     .card    { margin-bottom: 20px }   eigenständige Karte
     .fgcard  { margin-bottom: 14px }   Karte, die aus einer Gruppe entstand

   Gebraucht wird 14: das Skript „Feldgruppen-Karten (V5-Muster)" zerlegt beim
   Laden jede Karte mit Gruppen in eine Karte je Gruppe und gibt ihr `.fgcard`
   (Kompakt-Konzept v3, Z. 330 und 3832). Nachgezählt werden alle 25 Gruppen
   des Prototyps dazu — die Gruppenkarte ist der Regelfall, nicht die Ausnahme.

   Vorher stand hier in 17 Dateien `Gap="16px"`. Die 16 war weder die eine noch
   die andere Prototypzahl, sondern die nächste Stufe unserer Abstandsleiter —
   und damit dieselbe Falle wie beim Zellpolster der Slotliste: einen
   Prototypwert auf die eigene Leiter ziehen. 14 liegt nicht darauf, steht also
   als Zahl. */

.qb-cardstack[b-d8lnq1wlsx] {
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
}

/* ── Breite und Spaltenzahl des Formularbereichs ────────────────────────────

   Positiv gefasst: Vorgabe bleibt die breite Form, deren Raster das FieldGrid
   selbst setzt; die Regeln unten sagen nur, WANN stattdessen die schmale Form
   gilt. Andersherum stünden die Werte des FieldGrid hier ein zweites Mal.

   Schmale Form heißt: Karte 440 px breit (Designer-Vorgaben 2026-09-21,
   Abschnitt 2), die Felder liegen in drei gleichen Spalten. Sie gilt ab 530 px
   Fensterhöhe: höchster gemessener Fall 4 Zeilen, Komfort 330 px Karte plus
   190 px Rahmen (Browser 2026-09-23, Mengeneinheiten und Abteilungen).
   Darunter fällt sie auf die breite Form samt deren Deckel zurück (Review
   PR 311, 2026-09-26). */

/* Deckel 1272 px (Designer-Vorgaben 2026-09-21, Abschnitt 2). Für die schmale
   Form schlägt ihn ab 530 px die Medienregel unten durch die Reihenfolge. */
.qb-cardstack--narrow[b-d8lnq1wlsx],
.qb-cardstack--wide[b-d8lnq1wlsx] {
    max-width: 1272px;
}

/* Breitenklassen als Spaltenzahl: short 1, medium 2, full alle (Entscheidung
   2026-09-24, drei Spalten statt fester Breiten). Schlägt `.qb-fieldgrid--N`
   samt dessen 1150-px-Regel durch das zusätzliche Kartenstapel-Attribut. */
@media (min-height: 530px) {
    .qb-cardstack--narrow[b-d8lnq1wlsx] {
        max-width: 440px;
    }

    .qb-cardstack--narrow[b-d8lnq1wlsx]  .qb-fieldgrid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .qb-cardstack--narrow[b-d8lnq1wlsx]  .qb-fieldgrid > .qb-field--medium {
        grid-column: span 2;
    }

    .qb-cardstack--narrow[b-d8lnq1wlsx]  .qb-fieldgrid > .qb-field--full {
        grid-column: 1 / -1;
    }
}
/* _content/D3.Web/Components/Shared/Components/DensityToggle.razor.rz.scp.css */
/* Dichte-Pille der Kopfleiste. Werte aus dem Kompakt-Konzept v3, `.densbtn`:

     height: 26px; padding: 0 9px;
     border: 1px solid var(--border-strong); border-radius: 2px;
     background: var(--surface); color: var(--text-2);
     font: 600 11px/1 "Source Sans 3"
     :hover { color: var(--text); background: var(--surface-2) }

   Alle sechs Farbwerte des Prototyps sind wertgleich mit den QB-Token
   (2026-08-13 am Browser geprüft), deshalb hier direkt die Token.

   Kein ::deep und keine Hülle: das <button> ist unser eigenes Element und
   bekommt das Bereichsattribut direkt.

   Die 26 px und die 9 px liegen nicht auf dem 4-px-Raster. Das ist die Vorgabe
   des Prototyps; die Pille ist bewusst kleiner als die 32-px-Symbolknöpfe
   daneben, damit sie als Anzeige und nicht als Aktion gelesen wird. */
.qb-density-toggle[b-yb561pavmc] {
    height: 26px;
    padding: 0 9px;
    border: 1px solid var(--qb-border-strong);
    border-radius: var(--qb-radius-control);
    background: var(--qb-surface);
    color: var(--qb-text-muted);
    font-family: var(--qb-font-body);
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color var(--qb-transition-fast), color var(--qb-transition-fast);
}

.qb-density-toggle:hover[b-yb561pavmc] {
    color: var(--qb-text);
    background: var(--qb-surface-raised);
}
/* _content/D3.Web/Components/Shared/Components/Divider.razor.rz.scp.css */
.qb-divider[b-9kvgcp5nmc] {
  --qb-divider-colour: var(--qb-surface-border);
  --qb-divider-thickness: 1px;

  border: none;
  border-top: var(--qb-divider-thickness) solid var(--qb-divider-colour);
  margin-block: var(--qb-space-md);
  margin-inline: 0;
}
/* _content/D3.Web/Components/Shared/Components/DividerHorizontal.razor.rz.scp.css */
.qb-divider-h[b-96fmv6nj04] {
  --qb-divider-colour: var(--qb-surface-border);
  --qb-divider-thickness: 1px;

  width: 100%;
  height: var(--qb-divider-thickness);
  background-color: var(--qb-divider-colour);
  margin-block: 2px;
  margin-inline: 0;
}
/* _content/D3.Web/Components/Shared/Components/Fact.razor.rz.scp.css */
.qb-fact b[b-j55sdlqs9m] {
    font-weight: 600;
    color: var(--qb-text);
}

.qb-fact-num[b-j55sdlqs9m] {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
/* _content/D3.Web/Components/Shared/Components/FieldError.razor.rz.scp.css */
/* Fehlertext unter einem Feld. Rolle "Text auf der Flaeche" ist der Akzent --
   dieselbe Umleitung wie in Login.razor.css (--rz-danger-dark -> --qb-error-accent). */
.qb-field-error[b-htgfocgmg5] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin-top: 2px;
    color: var(--qb-error-accent);
    font-size: var(--rz-text-caption-font-size);
    line-height: var(--rz-text-caption-line-height);
}
/* _content/D3.Web/Components/Shared/Components/FieldGrid.razor.rz.scp.css */
/* Feldraster, `.grid.cols-N` des Konzepts.

   Falle: `minmax(0, 1fr)` und nicht `1fr`, sonst dehnt ein langer Wert die
   Spalte über ihren Anteil hinaus. */

.qb-fieldgrid[b-mmkg8ue87q] {
    display: grid;
    /* Prototyp `.grid{gap: var(--gapy) 14px}`. Waagerecht stand hier
       --qb-space-md = 16 px, also 2 px zu viel. 14 ist ein Prototypmass und
       liegt nicht auf der Abstandsleiter, deshalb als Zahl.

       Senkrecht bleibt --qb-density-gap-y, weil der Wert der Dichte folgen
       muss. Er ist in jeder Dichte 1 px vom Prototyp entfernt (12/16/8 gegen
       13/17/7) -- das ist ein Theme-Token und gehoert ins Radzen-Projekt,
       nicht hierher. Vermerkt in UI-TODO 7b. */
    gap: var(--qb-density-gap-y) 14px;
}

.qb-fieldgrid--2[b-mmkg8ue87q] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.qb-fieldgrid--3[b-mmkg8ue87q] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.qb-fieldgrid--4[b-mmkg8ue87q] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.qb-fieldgrid--5[b-mmkg8ue87q] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.qb-fieldgrid--6[b-mmkg8ue87q] { grid-template-columns: repeat(6, minmax(0, 1fr)); }

@media (max-width: 1150px) {
    .qb-fieldgrid--3[b-mmkg8ue87q],
    .qb-fieldgrid--4[b-mmkg8ue87q],
    .qb-fieldgrid--5[b-mmkg8ue87q],
    .qb-fieldgrid--6[b-mmkg8ue87q] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* ── Spannen ──────────────────────────────────────────────────────────────
   Prototyp:  .span2 { grid-column: span 2 }   14 Fundstellen
              .span3 { grid-column: span 3 }    2 Fundstellen
              @media (max-width:1150px) { .span2, .span3 { grid-column: span 2 } }

   Wozu sie da sind: die Rasterbreite bleibt bei vier, und ein Feld, dessen
   Inhalt mehr Platz braucht, nimmt zwei oder drei Zellen. Damit schliesst
   sich auch eine angebrochene Reihe -- der Prototyp nutzt das bei sechs
   Feldern in vier von sechs Faellen (2x sieben, 2x acht belegte Zellen bei
   cols-4). Am 2026-08-21 so entschieden; die Alternative waere
   gewesen, die Rasterbreite nach Feldanzahl zu wechseln, und dann bekaeme
   eine fuenfstellige PLZ ein Drittel der Kartenbreite.

   `--full` ist die vierte Stufe: ueber ALLE Spalten, unabhaengig von der
   Rasterbreite. Sie gab es hier zuerst und bleibt -- der Prototyp hat sie
   nicht als eigene Klasse, aber er braucht sie auch nicht: `.span2` in einem
   `cols-2` ist dasselbe.

   Gesetzt wird das wie `--full` als Klasse am Feld oder an einer Huelle
   darum; FieldShell fuehrt eine eingehende `class` mit `.qb-field`
   zusammen. Kein neuer Parameter -- derselbe Weg, den `--full` schon geht.

   Die Breitenklassen der schmalen Form (drei Spalten) `qb-field--short`,
   `--medium` und `--full` stehen in CardStack.razor.css und wirken nur unter
   `.qb-cardstack--narrow` ab 530 px Fensterhoehe. Im Rueckfall auf die breite
   Form gilt hier wieder das Raster mit Spannen; `--medium` ist dann eine
   Zelle. */
.qb-fieldgrid[b-mmkg8ue87q]  .qb-field--full {
    grid-column: 1 / -1;
}

.qb-fieldgrid[b-mmkg8ue87q]  .qb-field--span2 {
    grid-column: span 2;
}

.qb-fieldgrid[b-mmkg8ue87q]  .qb-field--span3 {
    grid-column: span 3;
}

@media (max-width: 1150px) {
    /* Unter 1150 px hat das Raster nur noch zwei Spalten -- eine Dreierspanne
       gaebe es dort nicht mehr. Der Prototyp zieht beide auf zwei. */
    .qb-fieldgrid[b-mmkg8ue87q]  .qb-field--span2,
    .qb-fieldgrid[b-mmkg8ue87q]  .qb-field--span3 {
        grid-column: span 2;
    }
}

/* ── `--fest`: die Spaltenzahl bleibt auch im schmalen Fenster ─────────────
   Fuer Gruppen, deren Dreierblock die Aussage traegt (Kalkulationstafel:
   Flaeche - Preis je m2 - Staerke); der Umbruch auf zwei Spalten zerrisse die
   Paarung. Nur fuer kurze Zahlen -- Text braucht die Umbruchregel. */
@media (max-width: 1150px) {
    .qb-fieldgrid--fest.qb-fieldgrid--3[b-mmkg8ue87q] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .qb-fieldgrid--fest.qb-fieldgrid--4[b-mmkg8ue87q] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .qb-fieldgrid--fest.qb-fieldgrid--5[b-mmkg8ue87q] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
    .qb-fieldgrid--fest.qb-fieldgrid--6[b-mmkg8ue87q] { grid-template-columns: repeat(6, minmax(0, 1fr)); }

    /* Eine Spanne innerhalb einer festen Gruppe bleibt ebenfalls, was sie ist. */
    .qb-fieldgrid--fest[b-mmkg8ue87q]  .qb-field--span3 { grid-column: span 3; }
}

/* ── `--abstand`: Luft nach oben ──────────────────────────────────────────
   Zwei aufeinanderfolgende Gruppen saehen sonst aus wie eine; eine Stufe der
   Abstandsleiter, nicht die Gruppenluecke. */
.qb-fieldgrid--abstand[b-mmkg8ue87q] {
    margin-top: var(--qb-space-md, 16px);
}
/* _content/D3.Web/Components/Shared/Components/FieldIcon.razor.rz.scp.css */
/* Größe, Farbe und Innenabstand wie der Kalender-Auslöser der DateBox
   (odysys-base.css, .rz-datepicker-trigger und .rz-datepicker:has(...) > .rz-inputtext),
   Randabstand wie das Symbol der SearchBox. */

/* Spalte wie der umgebende RadzenStack, damit das Feld die Breite behält, die es ohne
   Hülle hat. */
.qb-field-icon[b-ayv0pku2db] {
    position: relative;
    display: flex;
    flex-direction: column;
}

/* Den Rahmen trägt je nach Feld das input selbst (Textbox) oder seine Hülle (.rz-numeric,
   .rz-autocomplete); der Text sitzt in allen drei Fällen im input. */
.qb-field-icon[b-ayv0pku2db]  input {
    padding-inline-end: calc(var(--rz-datepicker-trigger-icon-size) + 2 * var(--qb-space-xs));
}

.qb-field-icon-symbol[b-ayv0pku2db] {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: var(--qb-space-xs);
    transform: translateY(-50%);
    width: var(--rz-datepicker-trigger-icon-size);
    height: var(--rz-datepicker-trigger-icon-size);
    font-size: var(--rz-datepicker-trigger-icon-size);
    color: var(--rz-datepicker-trigger-icon-color);
    pointer-events: none;
}
/* _content/D3.Web/Components/Shared/Components/FieldLabel.razor.rz.scp.css */
.qb-field-label[b-1e1jseuj07] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xxs);
    font-size: 0.75rem;
    line-height: var(--skai4-field-label-height);
    font-weight: 600;
    color: var(--qb-text-muted);
}

.qb-field-required[b-1e1jseuj07] {
    color: var(--qb-error);
    font-weight: 700;
    cursor: help;
}
/* _content/D3.Web/Components/Shared/Components/FieldShell.razor.rz.scp.css */
.qb-field[b-bjsdjdwjcq] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* Ein Feld OHNE Beschriftung in einer Reihe, deren übrige Felder eine haben --
   etwa die Zelle, die nur ein Kontrollkästchen trägt.

   Ohne diese Regel klebt der Inhalt an der Oberkante der Zelle und sitzt damit
   um die Höhe einer Beschriftungszeile höher als die Felder daneben.

   Der Prototyp löst das mit einer leeren Beschriftung (`<label>&nbsp;</label>`,
   Z. 2097). Bei uns geht das NICHT: FieldLabel prüft auf IsNullOrWhiteSpace, und
   U+00A0 gilt in .NET als Leerraum -- ein geschütztes Leerzeichen als Text
   erzeugt also gar keine Zeile. Deshalb über die Ausrichtung statt über ein
   Füllzeichen; das Raster macht die Zelle ohnehin so hoch wie die Reihe
   (`align-items: stretch` ist die Vorbelegung), und der Inhalt ist in beiden
   Fällen das letzte Kind. */
.qb-field--nolabel[b-bjsdjdwjcq] {
    justify-content: flex-end;
}

.qb-field-inline[b-bjsdjdwjcq] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
}

.qb-field-inline[b-bjsdjdwjcq] >  .rz-textbox {
    flex: 1 1 auto;
}
/* _content/D3.Web/Components/Shared/Components/Hint.razor.rz.scp.css */
.qb-hint[b-0triaxu1kn] {
    font-size: 0.75rem;    color: var(--qb-text-muted);
}
/* _content/D3.Web/Components/Shared/Components/IconButton.razor.rz.scp.css */
.qb-icon-button[b-z1oahvxlbw] {
    border: 0;
    background: none;
    border-radius: var(--qb-radius-control);
    cursor: pointer;
    display: grid;
    place-items: center;
    position: relative;
    text-decoration: none;
    transition: background-color var(--qb-transition-fast), color var(--qb-transition-fast);
}

.qb-icon-button:hover[b-z1oahvxlbw] {
        background: var(--qb-surface-hover);
    color: var(--qb-text);
}

.qb-icon-button-md[b-z1oahvxlbw] {
    width: 32px;
    height: 32px;
    color: var(--qb-text-muted);
}

.qb-icon-button-md .rzi[b-z1oahvxlbw] {
    font-size: var(--qb-icon-lg);
    width: var(--qb-icon-lg);
    height: var(--qb-icon-lg);
}

.qb-icon-button-sm[b-z1oahvxlbw] {
    width: 22px;
    height: 22px;
    color: var(--qb-text-subtle);
}

.qb-icon-button-sm[b-z1oahvxlbw]::before {
    content: "";
    position: absolute;
    inset: -4px;
}

.qb-icon-button-sm .rzi[b-z1oahvxlbw] {
    font-size: var(--qb-icon-sm);
    width: var(--qb-icon-sm);
    height: var(--qb-icon-sm);
}

/* Ein Schriftzeichen statt eines Symbols (Parameter `Glyph`).

   11 px ist der Wert des Prototyps fuer `.mm-toggle` (Z. 251) -- die einzige
   Stelle, die heute ein Zeichen fuehrt. Es steht absichtlich unter der
   Symbolgroesse (--qb-icon-sm, 14 px): ein gefuelltes Dreieck aus der
   Textschrift traegt bei gleicher Punktgroesse mehr Flaeche als ein Symbol.

   Fuer die Groesse Md gibt es bewusst keine Regel: dort fuehrt noch kein
   Aufrufer ein Zeichen, und einen Wert zu erfinden waere eine Behauptung. Der
   erste Aufrufer bekommt sie. */
.qb-icon-button-sm .qb-icon-button-glyph[b-z1oahvxlbw] {
    font-size: 11px;
    line-height: 1;
}

.qb-icon-button.qb-icon-button-skaila[b-z1oahvxlbw] {
    color: var(--qb-interactive-strong);
}
/* _content/D3.Web/Components/Shared/Components/MaskMenu.razor.rz.scp.css */
/* Maskenmenue -- Prototyp `.maskmenu` / `.mm-*` aus Kompakt-Konzept v3.

   ── Zwei bewusste Abweichungen, beide so entschieden ─────────────────────
   1. **Volle Seitenhoehe.** Der Prototyp haengt das Menue an `.mm-inner` mit
      `position:sticky; top:104px; max-height:calc(100vh - 104px)` -- es endet
      also an der Hoehe des Karteninhalts. Vorgabe vom 2026-08-20: "der soll
      einfach die komplette laenge der seite bekommen wie das rail". Deshalb
      hier kein sticky, sondern eine Flexspalte, die die Rumpfzeile der
      MaskShell voll ausfuellt.
   2. **Buendig links und oben.** Kein Aussenabstand, kein Radius: das Menue
      stoesst direkt an das Rail und beginnt unter der Kopfzeile. Es liegt
      dafuer ausserhalb des gepolsterten Rollbereichs (siehe MaskShell).

   ── Werte, alle aus dem Prototyp v3 abgelesen ────────────────────────────
     .workspace              grid-template-columns: 212px minmax(0,1fr)
     .workspace.mm-collapsed 36px
     .maskmenu               --surface, border-right 1px --border
     .mm-inner               padding 10px 8px 14px
     .mm-head                padding 0 4px 4px 8px
     .mm-title               10.5px / 700 / .8px, Versalien, --text-3
     .mm-toggle              22 x 22, 11px, --text-3, Zeichen ◀ / ▶
     .mm-search              padding 2px 2px 8px
     .mm-search input        h 26, padding 0 8px, 12px, --surface-2
     .mm-item                min-height 28, padding 0 9px, 13px, gap 7px
     .mm-item.active         --accent-soft / --accent-strong / 600,
                             inset 2px 0 0 --accent
     .mm-item .count         11px, padding 0 6px, line-height 16
     .mm-kbd                 10px, padding 0 4px, line-height 14
     .mm-grp                 min-height 24, padding 0 6px 0 9px, gap 5px
     .mm-sub .mm-item        padding-left 18px

   Die Zahlen stehen als Zahlen, nicht als --qb-space-*: 9, 10, 14, 18, 7, 6
   und 5 px liegen nicht auf unserer Abstandsleiter (4 / 8 / 12 / 16). Sie
   ueber die naechstliegende Stufe zu fuehren war genau der Fehler, den die Rückmeldung
   am Zellpolster der Slotliste gefunden hat -- 12 statt 8, weil
   --qb-space-sm nicht aufgeloest wurde.

   Ausnahmen, die bewusst NICHT der Prototypzahl folgen:
     * **Radius**: `--qb-radius-control` (6 px) statt der 2 px aus v3. Fuer
       Radien ist Kompakt-Konzept **v2** die Quelle (4 / 6 / 9 px), so steht
       es in der Leseliste.
     * **Farben**: die --qb-*-Rollen statt der Prototyp-Hexwerte, damit der
       Dunkelmodus mitgeht. Der Aenderungspunkt nimmt --qb-signal (#F7A600)
       statt #c9a227 -- dieselbe Rolle, unser Ton. */
.qb-maskmenu[b-ifh3nmwwfi] {
    flex: 0 0 212px;
    width: 212px;
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--qb-surface);
    border-inline-end: 1px solid var(--qb-surface-border);

    /* Beschneidet den Inhalt waehrend der Klappbewegung -- siehe unten. */
    overflow: hidden;
}

.qb-maskmenu--collapsed[b-ifh3nmwwfi] {
    flex-basis: 36px;
    width: 36px;
}

/* ── Einklappen laeuft weich ──────────────────────────────────────────────
   Am 2026-08-21 bestellt: „das einklappen des bereichs soll eine css
   animation bekommen." Der Prototyp animiert NICHT -- er schaltet
   `.mm-collapsed` hart um (Z. 222). Das ist also bewusst mehr als der
   Prototyp, kein Abgleichfehler.

   (Am 2026-09-01 war die Animation kurz draussen, weil das Zuklappen dem
   Konzept folgen sollte; am selben Tag wieder herein. Der Verlauf steht hier,
   damit sie nicht ein drittes Mal aus Versehen kippt.)

   Bewegt wird nur die Breite, Dauer --qb-transition-base (0.2s). Die schnelle
   Stufe (0.12s) traegt im Projekt Farb- und Randwechsel; 176 px brauchen mehr,
   sonst ruckelt es eher als dass es laeuft.

   ── Warum `overflow: hidden` oben dazugehoert ────────────────────────────
   Titel, Suche und Navigation entstehen eingeklappt gar nicht erst (`@if
   (!Collapsed)` im Markup) -- so bleibt eingeklappt nichts als der Knopf
   stehen, und das haengt nicht daran, dass eine CSS-Regel greift.

   Beim AUFklappen sind sie damit aber schon gezeichnet, waehrend die Spalte
   noch 36 px breit ist. Ohne Beschnitt stuenden sie fuer die Dauer der
   Bewegung sichtbar ueber den Inhaltsbereich hinaus (Gruppentitel und
   Menuetitel tragen keine Ellipse). `overflow: hidden` am <aside> macht daraus
   die richtige Bewegung: die wachsende Spalte gibt den Inhalt frei, statt dass
   er darueber liegt.

   Der Rollbereich bleibt davon unberuehrt -- er sitzt auf .qb-mm-inner und
   bringt seinen eigenen Beschnitt mit.

   prefers-reduced-motion schaltet die Bewegung ab: wer sie abbestellt hat,
   bekommt das harte Umschalten des Prototyps. */
.qb-maskmenu[b-ifh3nmwwfi] {
    transition: flex-basis var(--qb-transition-base), width var(--qb-transition-base);
}

@media (prefers-reduced-motion: reduce) {
    .qb-maskmenu[b-ifh3nmwwfi] {
        transition: none;
    }
}

.qb-mm-inner[b-ifh3nmwwfi] {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 10px 8px 14px;
}

.qb-mm-head[b-ifh3nmwwfi] {
    display: flex;
    align-items: center;
    padding: 0 4px 4px 8px;
}

.qb-mm-title[b-ifh3nmwwfi] {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    color: var(--qb-text-subtle);
}

/* Der Klapp-Knopf ist ein IconButton (Groesse Sm) mit dem Zeichen ◀ / ▶.

   Hier steht nur noch, was die Stellung im Kopf betrifft -- alles andere
   (22 x 22, randlos, Radius, Ruheton, Hover, vergroesserte Klickflaeche) traegt
   das Bauteil. Der Prototyp fuehrt fuer `.mm-toggle` (Z. 250-252) genau
   dieselben Masse; das ist der Grund, warum es kein eigener Knopf sein muss.

   Am 2026-09-01 stand hier einen Tag lang ein handgebauter `.qb-mm-toggle` mit
   diesen Werten als Kopie -- weil IconButton damals nur Symbolnamen kannte und
   das Dreieck des Konzepts ein Schriftzeichen ist. Die Kopie hatte die
   vergroesserte Klickflaeche verloren. Statt sie nachzutragen kann IconButton
   jetzt Zeichen (Parameter `Glyph`), und die Masse stehen wieder nur einmal. */
.qb-mm-head[b-ifh3nmwwfi]  .qb-icon-button {
    margin-inline-start: auto;
    flex-shrink: 0;
}

.qb-mm-search[b-ifh3nmwwfi] {
    padding: 2px 2px 8px;
}

.qb-mm-search .rz-textbox[b-ifh3nmwwfi] {
    width: 100%;
    box-sizing: border-box;
    height: 26px;
    padding: 0 8px;
    font-size: 12px;
    background: var(--qb-surface-raised);
}

.qb-mm-item[b-ifh3nmwwfi] {
    display: flex;
    align-items: center;
    gap: 7px;
    min-height: 28px;
    width: 100%;
    padding-inline: 9px;
    border: 0;
    border-radius: var(--qb-radius-control);
    background: none;
    color: var(--qb-text-muted);
    font-family: inherit;
    font-size: 0.8125rem;
    text-align: start;
    cursor: pointer;
}

.qb-mm-item:hover[b-ifh3nmwwfi] {
    background: var(--qb-surface-hover);
    color: var(--qb-text);
}

.qb-mm-item--active[b-ifh3nmwwfi] {
    background: var(--qb-interactive-background);
    color: var(--qb-interactive-strong);
    font-weight: 600;
    box-shadow: inset 2px 0 0 var(--qb-interactive);
}

.qb-mm-label[b-ifh3nmwwfi] {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.qb-mm-flag[b-ifh3nmwwfi],
.qb-mm-count[b-ifh3nmwwfi],
.qb-mm-kbd[b-ifh3nmwwfi] {
    margin-inline-start: auto;
    flex-shrink: 0;
}

.qb-mm-count + .qb-mm-kbd[b-ifh3nmwwfi],
.qb-mm-flag + .qb-mm-kbd[b-ifh3nmwwfi] {
    margin-inline-start: var(--qb-space-xxs);
}

.qb-mm-flag[b-ifh3nmwwfi] {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--qb-signal);
}

.qb-mm-count[b-ifh3nmwwfi] {
    padding-inline: 6px;
    border-radius: var(--qb-radius-control);
    background: var(--qb-surface-sunken);
    color: var(--qb-text-subtle);
    font-size: 0.6875rem;
    line-height: 16px;
}

.qb-mm-item--active .qb-mm-count[b-ifh3nmwwfi] {
    background: var(--qb-surface);
    color: var(--qb-interactive-strong);
}

.qb-mm-kbd[b-ifh3nmwwfi] {
    padding-inline: var(--qb-space-xxs);
    border: 1px solid var(--qb-surface-border);
    border-radius: var(--qb-radius-control);
    color: var(--qb-text-subtle);
    font-family: inherit;
    font-size: 0.625rem;
    line-height: 14px;
}

.qb-mm-item--active .qb-mm-kbd[b-ifh3nmwwfi] {
    border-color: var(--qb-interactive);
    color: var(--qb-interactive-strong);
}

.qb-mm-grp[b-ifh3nmwwfi] {
    display: flex;
    align-items: center;
    gap: 5px;
    min-height: 24px;
    width: 100%;
    margin-block-start: var(--qb-space-xs);
    padding-inline: 9px 6px;
    border: 0;
    border-radius: var(--qb-radius-control);
    background: none;
    color: var(--qb-text-subtle);
    font-family: inherit;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    text-align: start;
    cursor: pointer;
}

.qb-mm-grp:hover[b-ifh3nmwwfi] {
    color: var(--qb-text);
}

.qb-mm-grp[b-ifh3nmwwfi]  .qb-mm-chev {
    margin-inline-start: auto;
    font-size: var(--qb-icon-sm);
    transition: transform var(--qb-transition-fast);
}

.qb-mm-grp--closed[b-ifh3nmwwfi]  .qb-mm-chev {
    transform: rotate(-90deg);
}

.qb-maskmenu nav[b-ifh3nmwwfi],
.qb-mm-sub[b-ifh3nmwwfi] {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.qb-mm-sub .qb-mm-item[b-ifh3nmwwfi] {
    padding-inline-start: 18px;
}

.qb-mm-empty[b-ifh3nmwwfi] {
    margin: 0;
    padding: var(--qb-space-xxs) var(--qb-space-xs);
    color: var(--qb-text-subtle);
    font-size: 0.75rem;
}

.qb-maskmenu--collapsed .qb-mm-inner[b-ifh3nmwwfi] {
    padding: 10px 3px;
    overflow: hidden;
}

.qb-maskmenu--collapsed .qb-mm-head[b-ifh3nmwwfi] {
    padding: 0;
    justify-content: center;
}

@media (max-width: 900px) {
    .qb-maskmenu[b-ifh3nmwwfi] {
        /* Schmal wird aus der Spalte eine Leiste am unteren Rand -- Prototyp
           `@media` : `.workspace{grid-template-columns:1fr}`. Die feste Breite
           der Spalte muss dafuer zurueckgenommen werden. */
        flex: 0 0 auto;
        width: auto;
        position: fixed;
        inset-inline: 0;
        inset-block-end: 0;
        z-index: var(--qb-z-sheet);
        border-inline-end: 0;
        border-block-start: 1px solid var(--qb-surface-border);
    }

    .qb-maskmenu[b-ifh3nmwwfi]::before {
        content: "";
        display: block;
        width: 44px;
        height: 4px;
        margin: var(--qb-space-xxs) auto 0;
        border-radius: 2px;
        background: var(--qb-border-strong);
    }

    .qb-mm-inner[b-ifh3nmwwfi] {
        max-height: 40vh;
    }
}
/* _content/D3.Web/Components/Shared/Components/MaskShell.razor.rz.scp.css */
/* Die Hülle hebt das Polster von .rz-body auf, damit Kopf und Speicherleiste
   an die Kanten laufen. Der Inhalt bekommt es als eigenes Polster zurück --
   im Prototyp trägt .workspace es ebenso, die Leisten nicht. */
.qb-mask[b-6bezazpxur] {
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;

    margin: calc(-1 * var(--rz-layout-body-padding));

    /* Falle: height: 100% bezieht sich auf die Inhaltsbox von .rz-body. Die
       negativen Ränder verschieben die Hülle nach außen, vergrößern sie aber
       nicht -- die Fußleiste endete dadurch 48 px über dem unteren Rand
       (gemessen 841 statt 889). Also die aufgehobenen Polster wieder
       dazurechnen. */
    height: calc(100% + 2 * var(--rz-layout-body-padding));
}

/* Rumpfzeile zwischen Kopf und Fussleiste: links das Maskenmenue, rechts der
   rollende Inhalt. Prototyp `.workspace` ist dafuer ein Raster
   (`212px minmax(0,1fr)`); hier ist es eine Flexzeile, weil der Menue-Schlitz
   leer bleiben darf und ein Raster dann eine leere Spalte behielte.

   Das Menue liegt bewusst NICHT im gepolsterten Rollbereich: dort endete es an
   der Hoehe des Karteninhalts. Als Geschwister des Inhalts reicht es ueber die
   volle Hoehe und beginnt buendig unter der Kopfzeile. */
.qb-mask-body[b-6bezazpxur] {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
}

.qb-mask-content[b-6bezazpxur] {
    flex: 1 1 auto;

    /* In einer Flexzeile braucht die wachsende Spalte beides: min-width fuer
       Ellipsen und breite Tabellen, min-height fuer den eigenen Rollbereich. */
    min-width: 0;
    min-height: 0;
    overflow-y: auto;

    /* Prototyp: .workspace `padding: 0 20px 70px 0` und .content
       `padding: 14px 0 0 20px` -- also 20 px seitlich und 14 px oben.

       Hier stand vorher `var(--qb-space-md) var(--rz-layout-body-padding)`, das
       sind 16 oben und **24** seitlich: seitlich 4 px zu viel, oben 2 px. In
       der Rückmeldung am Bild gefunden ("der abstand zwischen den karten und dem rand ist
       nicht korrekt"). 20 und 14 liegen nicht auf unserer Abstandsleiter
       (4/8/12/16) und stehen deshalb als Zahl -- es sind Prototypmasse, keine
       Stufen der Leiter.

       Den Bodenfreiraum von 70 px braucht es nicht: die Speicherleiste liegt
       als letztes Flex-Kind unter dem Rollbereich statt darüber. */
    padding: 14px 20px;
}
/* _content/D3.Web/Components/Shared/Components/NumericBox.razor.rz.scp.css */
/* Zahlenfelder tragen Tabellenziffern, sind aber NICHT rechtsbuendig.

   Prototyp: die Eingabe bekommt `class="num"`, und `.num` ist ausschliesslich
   `font-variant-numeric: tabular-nums` (Zeile 73). Rechtsbuendig sind im
   Konzept nur Tabellenzellen -- `td.r` und `.cellinput.r`, nicht das
   Formularfeld.

   Vorher stand hier `TextAlign="TextAlign.Right"` am Bauteil und 119-mal
   direkt im Markup. Vorgabe vom 2026-08-21: "bei den inputs ist bei zahlen wie auf
   dem bild alles rechts, das macht sinn wenn man zahlen anzeigt beim eingeben
   ist dies jedoch sehr verwirrend."

   ::deep, weil die Eingabe von Radzen kommt und nicht in dieser Datei steht. */
[b-2wowm9kqgm] .rz-textbox,
[b-2wowm9kqgm] .rz-numeric input {
    font-variant-numeric: tabular-nums;
}
/* _content/D3.Web/Components/Shared/Components/OptionRow.razor.rz.scp.css */
/* `.inline-opts` des Kompakt-Konzepts v3, Zeile 322-325. Der entscheidende Wert ist
   `min-height: var(--fh)` -- die Feldhoehe; ohne ihn ist die Zeile nur so hoch wie das
   Kaestchen und sitzt ueber der Grundlinie des Nachbarfelds. Bei uns heisst sie
   --qb-density-field-height und folgt der Dichteumschaltung.

   Die Luecke ist 7 px, nicht die 16 der `.inline-opts` -- 16 trennt zwei Optionen
   voneinander, 7 das Kaestchen von seiner Beschriftung. */
.qb-optrow[b-8shjl0r1oq] {
    display: flex;
    align-items: center;
    gap: 7px;
    min-height: var(--qb-density-field-height);
    flex-wrap: wrap;
}

/* Die Kaestchengroesse steht bewusst nicht hier: sie kommt aus --rz-checkbox-width /
   -height des Themes. Eine eigene Groesse auf `.rz-chkbox-box` (position: absolute,
   inset: 0) reisst das Kaestchen aus seiner Verankerung, und zwei Quellen fuer einen Wert
   laufen auseinander (UI-INVENTAR, Fehler 18). */

/* Beschriftung: 12,5 px, dicht am Kaestchen, klickbar. */
.qb-optrow[b-8shjl0r1oq]  .rz-chkbox-label,
.qb-optrow[b-8shjl0r1oq]  .rz-radiobutton-label,
.qb-optrow[b-8shjl0r1oq]  label {
    font-size: 12.5px;
    line-height: 1.2;
    color: var(--qb-text);
    cursor: pointer;
    margin: 0;
}

/* Eine Rasterzelle mit beschriftetem Feld ist zweiteilig: Beschriftung, 2 px Abstand,
   Eingabefeld. Eine Kaestchenzeile hat diesen Kopf nicht und beginnt ganz oben in der
   Zelle -- ohne Rand oben sitzt das Kaestchen auf Hoehe der *Beschriftung* des Nachbarn
   statt auf Hoehe seines *Eingabefelds*.

   Die 2 px sind der `Gap="2px"` des RadzenStack, den jedes Feldbauteil zwischen
   Beschriftung und Eingabefeld setzt (Textbox, NumericBox, Textarea, FieldShell).

   Rand, nicht Innenabstand: `.qb-optrow` traegt `min-height`, und bei
   `box-sizing: border-box` ginge ein Padding darin auf, statt die Zeile zu verschieben. */
.qb-optrow--aligned[b-8shjl0r1oq] {
    margin-top: calc(var(--skai4-field-label-height) + 2px);
}
/* _content/D3.Web/Components/Shared/Components/OverviewCard.razor.rz.scp.css */
/* Gruppenkarte der Uebersicht. Werte aus dem Kompakt-Konzept2, `.dgroup` (Z. 446-457):

     .dgroup        --surface, 1px --border, radius 9px, padding 10px 12px 8px, min-width 0
     .dgroup.sp2    grid-column: span 2
     .dgroup.sp3    grid-column: span 3
     header         flex, align-items center, margin-bottom 6px
     h3             11px/700, letter-spacing .7px, Versalien, --text-2, margin 0
     .edit          margin-left auto, 11.5px/600, --accent-strong, radius 4px, padding 2px 4px
     .edit:hover    --accent-soft

   Radius 9px ist --qb-radius-card, der 4px-Radius des Knopfs laeuft auf
   --qb-radius-control (6px) -- zwei Radiusrollen, mehr gibt es nicht (§5.2).

   Das Polster 10px 12px 8px steht als Zahl: es ist ein Bauteilmass des Prototyps und
   liegt nicht auf der 4-px-Leiter. Die Ueberschrift ist die Rolle "overline" aus §4.1
   (0.625rem/600/1px), der Prototyp schreibt 11px/700/.7px -- gemessen gilt der
   Prototyp (§4.2 fuehrt genau diese Zeile als Gruppenueberschrift). */

.qb-dgroup[b-craaf33nw3] {
    min-width: 0;
    padding: 10px 12px 8px;

    background: var(--qb-surface);
    border: 1px solid var(--qb-surface-border);
    border-radius: var(--qb-radius-card);
}

.qb-dgroup--span2[b-craaf33nw3] {
    grid-column: span 2;
}

.qb-dgroup--span3[b-craaf33nw3] {
    grid-column: span 3;
}

/* Unter dem Bruchpunkt des Feldrasters werden aus drei Spalten zwei, und span3 muss
   mitgehen -- sonst ragt die Karte aus dem Raster heraus. --qb-breakpoint-form. */
@media (max-width: 1150px) {
    .qb-dgroup--span2[b-craaf33nw3],
    .qb-dgroup--span3[b-craaf33nw3] {
        grid-column: span 2;
    }
}

/* Einspaltig: jede Spanne faellt auf eine. --qb-breakpoint-mobile. */
@media (max-width: 480px) {
    .qb-dgroup--span2[b-craaf33nw3],
    .qb-dgroup--span3[b-craaf33nw3] {
        grid-column: auto;
    }
}

.qb-dgroup-head[b-craaf33nw3] {
    display: flex;
    align-items: center;
    margin-block-end: 6px;
}

.qb-dgroup-title[b-craaf33nw3] {
    margin: 0;

    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.7px;
    text-transform: uppercase;
    color: var(--qb-text-muted);
}

/* Der Zaehler hinter der Ueberschrift.

   Gedaempft und mit Tabellenziffern: er ist Beiwerk, kein Titel -- genau die
   Rolle, die §3.2 fuer „Zaehler" nennt (--qb-text-subtle). Ohne die eigene
   Farbe waere er von der Ueberschrift nicht zu unterscheiden und laese sich als
   Teil des Namens.

   Die Klammern stehen im CSS und nicht im Markup: sie sind Darstellung, kein
   Inhalt -- eine Vorlesehilfe soll „Positionen 5" hoeren und nicht
   „Positionen Klammer auf 5 Klammer zu". */
.qb-dgroup-count[b-craaf33nw3] {
    margin-inline-start: var(--qb-space-xxs);
    color: var(--qb-text-subtle);
    font-variant-numeric: tabular-nums;
}

.qb-dgroup-count[b-craaf33nw3]::before {
    content: "(";
}

.qb-dgroup-count[b-craaf33nw3]::after {
    content: ")";
}

.qb-dgroup-edit[b-craaf33nw3] {
    margin-inline-start: auto;
    padding: 2px 4px;

    background: none;
    border: 0;
    border-radius: var(--qb-radius-control);

    font-family: var(--qb-font-body);
    font-size: 0.71875rem;
    font-weight: 600;
    color: var(--qb-interactive-strong);
    cursor: pointer;
}

.qb-dgroup-edit:hover[b-craaf33nw3] {
    background: var(--qb-interactive-background);
}

.qb-dgroup-edit:focus-visible[b-craaf33nw3] {
    outline: var(--rz-outline-width) solid var(--qb-interactive);
    outline-offset: var(--rz-outline-offset);
}
/* _content/D3.Web/Components/Shared/Components/OverviewGrid.razor.rz.scp.css */
/* Werte aus dem Kompakt-Konzept2, `.dash` (Z. 442-450):

     .dash                      grid, repeat(3, minmax(0,1fr)), gap 16px
     @media (max-width:1150px)  repeat(2, ...), sp2/sp3 -> span 2
     @media (max-width:480px)   1fr, sp2/sp3 -> auto

   `minmax(0, 1fr)` und nicht `1fr`: sonst dehnt ein langer Wert die Spalte -- dieselbe
   Falle, die §9.2 fuer das Feldraster nennt.

   Die Bruchpunkte sind die Token --qb-breakpoint-form (1150) und -mobile (480). In einer
   Medienabfrage laesst sich eine CSS-Variable nicht benutzen, deshalb stehen sie hier als
   Zahl -- mit dem Tokennamen daneben, damit die Verbindung nachvollziehbar bleibt. */

.qb-dash[b-x82bp4mgcv] {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--qb-space-md);
}

/* --qb-breakpoint-form */
@media (max-width: 1150px) {
    .qb-dash[b-x82bp4mgcv] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* --qb-breakpoint-mobile */
@media (max-width: 480px) {
    .qb-dash[b-x82bp4mgcv] {
        grid-template-columns: 1fr;
    }
}
/* _content/D3.Web/Components/Shared/Components/OverviewRow.razor.rz.scp.css */
/* Wertzeile der Uebersicht. Werte aus dem Kompakt-Konzept2 (Z. 458-466):

     .kv              flex, align-items baseline, gap 12px, min-height 24px,
                      border-top 1px --surface-3
     .kv:first-of-type  border-top 0
     .kv dt           flex 0 0 44%, 12px, --text-2, margin 0
     .kv dd           flex 1, margin 0, text-align right, min-width 0
     .kv dd .lnk      --text, keine Unterstreichung, 600 (Prototyp: 500), Zeiger,
                      radius 3px, inline-block, max-width 100%, ellipsis, nowrap
     .kv dd .lnk:hover  --accent-strong + Unterstreichung
     .kv dd .muted    --text-3, 400

   Die Trennlinie ist `--surface-3` = --qb-surface-sunken, nicht --qb-surface-border:
   sie soll die Zeilen gliedern, nicht sie einrahmen. Der Prototyp trennt die beiden
   Rollen genauso.

   Gewicht 500 gibt es in der Anwendung nicht als Rolle; §4.2 fuehrt Werte mit 400 und
   Auszeichnungen mit 600. Genommen ist 500 wie im Prototyp -- die Zeile lebt davon,
   dass der Wert etwas kraeftiger steht als die Bezeichnung, ohne fett zu sein.

   44% fuer die Bezeichnung steht als Prozentwert des Prototyps. Keine Token-Rolle:
   es ist eine Aufteilung, kein Abstand. */

.qb-kv[b-b2jwzvrogs] {
    display: flex;
    align-items: baseline;
    gap: var(--qb-space-sm);

    min-height: 24px;
}

.qb-kv + .qb-kv[b-b2jwzvrogs] {
    border-block-start: 1px solid var(--qb-surface-sunken);
}

.qb-kv-label[b-b2jwzvrogs] {
    flex: 0 0 44%;
    margin: 0;

    font-size: 0.75rem;
    color: var(--qb-text-muted);
}

.qb-kv-value[b-b2jwzvrogs] {
    flex: 1;
    margin: 0;
    min-width: 0;
    text-align: right;
}

/* Knopf und Text teilen die Darstellung -- der Unterschied ist die Bedienbarkeit,
   nicht das Aussehen. Sonst saehe eine Zeile ohne Sprungziel wie ein Fehler aus. */
.qb-kv-link[b-b2jwzvrogs],
.qb-kv-text[b-b2jwzvrogs] {
    display: inline-block;
    max-width: 100%;

    font-family: var(--qb-font-body);
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--qb-text);

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

.qb-kv-link[b-b2jwzvrogs] {
    background: none;
    border: 0;
    padding: 0;
    border-radius: var(--qb-radius-control);
    text-decoration: none;
    cursor: pointer;
}

.qb-kv-link:hover[b-b2jwzvrogs] {
    color: var(--qb-interactive-strong);
    text-decoration: underline;
}

.qb-kv-link:focus-visible[b-b2jwzvrogs] {
    outline: var(--rz-outline-width) solid var(--qb-interactive);
    outline-offset: var(--rz-outline-offset);
}

/* Der leere Wert wird seit dem 2026-09-02 vom Bauteil `Wert` gezeichnet, und
   `.qb-kv-leer` ist entfallen. Die Regel stand hier wortgleich noch an zwei
   weiteren Stellen (PositionsStatusChip, PosTable) -- drei Definitionen
   derselben Rolle, was §1.2 auch bei gleichen Werten verbietet.

   Wichtig fuer diese Datei: `.qb-kv-link` setzt Gewicht 500, `Wert` setzt am
   Platzhalter ausdruecklich 400 dagegen. Das gehoert dorthin und nicht hierher
   -- sonst muesste jede Stelle, die `Wert` benutzt, ihr eigenes Gegengewicht
   mitbringen. */

/* "Ueberall, wo Ziffern untereinander stehen, gilt font-variant-numeric:
   tabular-nums" (§4.2). In einer Spalte rechtsbuendiger Betraege ist das der Fall.

   Der Klassenname ist bauteilbezogen (qb-kv-num) und NICHT die allgemeine qb-num:
   bereichsbezogenes CSS reicht nicht ueber die Komponentengrenze, ein gemeinsamer Name
   waere also eine Einladung, ihn woanders zu erwarten, wo er nicht wirkt. Dasselbe
   Muster wie qb-fact-num in Fact.razor.css. */
.qb-kv-num[b-b2jwzvrogs] {
    font-variant-numeric: tabular-nums;
}
/* _content/D3.Web/Components/Shared/Components/PageHead.razor.rz.scp.css */

.qb-pagehead[b-um7vl61nsc] {
    padding: var(--qb-space-xs) var(--rz-layout-body-padding);

    background: var(--qb-surface);
    border-bottom: 1px solid var(--qb-surface-border);
}

/* Randlos, nur wo der Kopf unmittelbar im Seitenkörper liegt (QbDataGrid).
   Die negativen Ränder heben das Body-Polster auf, damit der Kopf wie
   .pagehead des Prototyps von Kante zu Kante läuft und beim Rollen klebt.

   Falle: in einem Vorfahren mit overflow schneidet genau das den Kopf ab --
   siehe die Erklärung am Parameter Flush in PageHead.razor. */
.qb-pagehead--flush[b-um7vl61nsc] {
    margin-inline: calc(-1 * var(--rz-layout-body-padding));
    margin-block-start: calc(-1 * var(--rz-layout-body-padding));

    /* Nur hier: auf Listenseiten liegt der Kopf unmittelbar in .rz-body
       (display: block, kein Gap), der Rand ist dort der einzige Abstand zum
       Inhalt. In Detailmasken steckt er in einem Stapel mit gap: 16px -- dort
       zählte der Abstand doppelt, gemessen 32 px gegen 0 im Prototyp. */
    margin-block-end: var(--qb-space-md);

    position: sticky;
    top: calc(-1 * var(--rz-layout-body-padding));
    z-index: var(--qb-z-mask-header);
}

.qb-crumbs[b-um7vl61nsc] {
    margin-block-end: var(--qb-space-xxs);
    font-size: 0.71875rem;    color: var(--qb-text-muted);
}

.qb-titlerow[b-um7vl61nsc] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    flex-wrap: wrap;
    min-height: 1.875rem;}

.qb-page-title[b-um7vl61nsc] {
    margin: 0;
    font-size: 1.0625rem;    font-weight: 600;
    letter-spacing: 0.1px;
    color: var(--qb-text);
}

.qb-facts[b-um7vl61nsc] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xxs);
    min-width: 0;
    font-size: 0.75rem;
    color: var(--qb-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.qb-facts[b-um7vl61nsc]  > * + *::before {
    content: "·";
    margin-inline-end: var(--qb-space-xxs);
    color: var(--qb-border-strong);
}

.qb-facts[b-um7vl61nsc]  .qb-hint {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
}

.qb-titlerow-state[b-um7vl61nsc] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xxs);
    flex-shrink: 0;
}

.qb-titlerow-actions[b-um7vl61nsc] {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: var(--qb-space-xxs);
}

@media (max-width: 760px) {
    /* Nur der randlose Kopf klebt überhaupt, also hebt auch nur er es auf --
       wie .pagehead{position:static} des Prototyps am schmalen Schirm. */
    .qb-pagehead--flush[b-um7vl61nsc] {
        position: static;
    }

    .qb-titlerow-actions[b-um7vl61nsc] {
        margin-inline-start: 0;
        width: 100%;
        flex-wrap: wrap;
    }

    .qb-facts[b-um7vl61nsc]  .qb-hint {
        white-space: normal;
        overflow: visible;
    }
}

/* Änderungshinweis, Werte aus .dirty des Prototyps: 11,5 px in Signalfarbe
   mit einem 6-px-Punkt davor. Die Farbe kommt vom Rollentoken, nicht vom
   nackten Amber-Wert des Prototyps. */
.qb-dirty[b-um7vl61nsc] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xxs);

    font-size: 0.71875rem;
    color: var(--qb-warning);
    white-space: nowrap;
}

.qb-dirty[b-um7vl61nsc]::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}
/* _content/D3.Web/Components/Shared/Components/PositionsStatusChip.razor.rz.scp.css */
/* Der Gedankenstrich fuer eine Position ohne Status zeichnet seit dem
   2026-09-02 das Bauteil `Wert` -- dort steht die Rolle „leerer Wert" ein
   einziges Mal.

   Bis dahin stand hier `.qb-leer` mit denselben zwei Zeilen wie in
   OverviewRow.razor.css und PosTable.razor.css: drei Definitionen derselben
   Rolle, was §1.2 ausdruecklich verbietet („auch wenn beide Werte stimmen").

   Die Datei bleibt leer statt zu verschwinden: sie ist im Bauteil ueber
   Bereichs-CSS verdrahtet, und der naechste eigene Stil dieses Chips gehoert
   hierher. */
/* _content/D3.Web/Components/Shared/Components/PosTable.razor.rz.scp.css */
/* Die Tabelle innerhalb einer Maske -- `table.pos` des Kompakt-Konzepts v3.

   Nicht zu verwechseln mit `table.lst`, der Liste einer Listenseite (Muster
   9.11, bei uns QbDataGrid). `table.pos` ist die kleine Tabelle *in* einer
   Detailmaske: Positionen, Achsen, Slotmengen. Sie hat keine Suchleiste,
   keine Spaltenauswahl und keinen Pager.

   ── Warum die Zellregeln über ::deep laufen ──────────────────────────────
   Kopf- und Datenzellen kommen als RenderFragment von außen. Blazor setzt das
   Bereichsattribut nur auf Elemente, die in *dieser* Datei stehen -- ohne
   ::deep würde aus `.qb-pos td` ein `.qb-pos td[b-postable]`, und keine
   einzige übergebene Zelle träfe zu. Dasselbe Muster wie in LoginLayout.

   ── Werte ────────────────────────────────────────────────────────────────
   Prototyp `table.pos`, mit den qb-Token statt der Prototyp-Variablen:

     border-collapse: collapse; width: 100%; font-size: 14px
     thead th  11px/700, .5px gesperrt, Versalien, --text-2,
               links, padding 4px 8px, border-bottom 1px --border-strong
     tbody td  padding 2px 8px, height --rowh, border-bottom 1px --border
     tr:hover  --surface-2      tr.sel  --accent-soft
     td.r,th.r rechtsbündig

   Der Spaltenkopf steht als Verweis auf --rz-grid-header-*, nicht als zweiter
   Satz Werte: dieselbe Rolle trägt der Kopf der Datentabelle, und
   SperrvermerkAllgemeinTab hat sie 2026-08-18 bereits so aufgelöst. Wird der
   Listenkopf nachgezogen, folgt dieser hier mit. Für letter-spacing gibt es
   kein Token, die .5 px stehen deshalb als Zahl -- wie dort.

   Die Zeilenhöhe ist --qb-density-row-height, das Gegenstück zu --rowh: sie
   folgt der Dichteumschaltung, statt 33 px festzuschreiben.

   ── Warum das Zellpolster als Zahl dasteht ───────────────────────────────
   Hier stand zuerst `var(--qb-space-sm)`. Das ist 0.75rem = **12 px**, der
   Prototyp schreibt **8**. Vier Pixel je Seite, an jeder Zelle -- an der
   schmalen Nummernspalte sofort sichtbar, und in der Rückmeldung am Bild gefunden.
   Für 8 px gibt es keinen Abstandstoken: die Skala springt von 0.5rem (8)
   auf 0.75rem (12) -- 8 px wäre --qb-space-xs. Genommen ist trotzdem die
   Zahl, weil das hier ein **Zellpolster einer Tabelle** ist und kein Abstand
   der Layoutskala; dieselbe Begründung wie bei den Spaltenbreiten in
   SperrvermerkAllgemeinTab. Wer den Wert ändert, ändert ihn gegen den
   Prototypwert, nicht gegen die Skala. */
.qb-pos-wrap[b-vtkaqhvju3] {
    overflow-x: auto;
}

.qb-pos[b-vtkaqhvju3] {
    border-collapse: collapse;
    width: 100%;
    font-size: var(--qb-density-font-size);
}

.qb-pos[b-vtkaqhvju3]  thead th {
    font-size: var(--rz-grid-header-font-size);
    line-height: var(--rz-grid-header-line-height);
    font-weight: var(--rz-grid-header-font-weight);
    text-transform: var(--rz-grid-header-text-transform);
    color: var(--rz-grid-header-color);
    letter-spacing: 0.5px;
    text-align: left;
    padding: 4px 8px;
    border-block-end: 1px solid var(--qb-border-strong);
    white-space: nowrap;
}

.qb-pos[b-vtkaqhvju3]  tbody td {
    padding: 2px 8px;
    height: var(--qb-density-row-height);
    border-block-end: 1px solid var(--qb-surface-border);
    white-space: nowrap;
}

.qb-pos[b-vtkaqhvju3]  tbody tr:hover {
    background: var(--qb-surface-raised);
}

.qb-pos[b-vtkaqhvju3]  tbody tr.sel {
    background: var(--qb-interactive-background);
}

/* Eine Zeile, die als GANZE an eine Stelle fuehrt -- die Uebersichtskarte
   „Positionen" tut das (Konzept: `<tr data-sec="a-pos">`, Z. 3250).

   Nur der Zeiger, keine eigene Flaeche: den Hover traegt schon
   `tbody tr:hover`, und zwei Hervorhebungen fuer denselben Zustand waeren eine
   zu viel. Den Fokusring traegt `tbody tr:focus-visible`.

   NICHT dasselbe wie `.sel`: `.sel` ist die MARKIERTE Zeile der Positionssicht
   (eine von vielen, Werkzeuge wirken darauf), `.qb-pos-clickable` ist eine Zeile
   mit Sprungziel. Eine Tabelle hat entweder das eine oder das andere. */
.qb-pos[b-vtkaqhvju3]  tbody tr.qb-pos-clickable {
    cursor: pointer;
}

/* Die Zeile unter der Tastatur. Entsteht nur, wenn der Aufrufer sie mit
   `tabindex` anfassbar macht -- die Positionstabelle des Auftrags tut das,
   damit die Markierung nicht mausgebunden ist.

   `outline-offset` liegt INNEN (negativ) und nicht auf den globalen +1px: der
   Rollbereich der Tabelle beschneidet, ein aussen liegender Ring waere an der
   ersten und letzten Zeile halb weg. Dieselbe Ueberlegung wie beim Feldfokus,
   der aus demselben Grund `-1px` bekommt (Designsystem §9.2).

   Breite und Farbe kommen aus den Rollen: --rz-outline-width ist 2px, der Ring
   traegt --qb-interactive. */
.qb-pos[b-vtkaqhvju3]  tbody tr:focus-visible {
    outline: var(--rz-outline-width) solid var(--qb-interactive);
    outline-offset: calc(-1 * var(--rz-outline-width));
}

.qb-pos[b-vtkaqhvju3]  td.r,
.qb-pos[b-vtkaqhvju3]  th.r {
    text-align: right;
}

/* Tabellenziffern in den Zahlenspalten.

   „Überall, wo Ziffern untereinander stehen, gilt `font-variant-numeric:
   tabular-nums`" (Designsystem §4.2). Eine Positionstabelle ist der Fall, für
   den die Regel geschrieben ist: sechs rechtsbündige Zahlenspalten über bis zu
   fünfzig Zeilen. Ohne Tabellenziffern sind die Beträge unterschiedlich breit
   und die Kommas stehen nicht untereinander -- bei einer Spalte Geld ist das
   direkt ablesbar falsch.

   An `td.r` und nicht an der ganzen Tabelle: Tabellenziffern sind in Fließtext
   breiter und unruhiger als Proportionalziffern, und die Textspalte ist
   Fließtext. Dieselbe Aufteilung wie im QbDataGrid (`.qb-grid-num`) und bei
   `Fact`/`OverviewRow`, nur dass hier die Rechtsbündigkeit die Spalte schon
   auszeichnet und es keine zweite Klasse braucht.

   NICHT an `th.r`: die Kopfzelle trägt Text in Versalien, keine Ziffern. */
.qb-pos[b-vtkaqhvju3]  td.r {
    font-variant-numeric: tabular-nums;
}

/* Nummernspalte links und Aktionsspalte rechts schrumpfen auf ihren Inhalt.

   Der Prototyp schreibt dafuer nichts -- er braucht es auch nicht: sein
   Inhaltsbereich ist ~820 px breit (`.workspace` = `212px 1fr` bei 1280 px
   Fenster), und bei dieser Breite bleibt die Nummernspalte von allein eng.
   `table-layout: auto` mit `width: 100%` verteilt ueberschuessige Breite
   aber auf ALLE Spalten. Am Prototyp selbst gemessen:

     Tabelle  769 px  ->  Spalte "Nr." 35,9 px
     Tabelle 1400 px  ->  Spalte "Nr." 65,3 px   (dieselbe Tabelle!)

   Gesehen an unserer breiteren Maske (Rückmeldung): "bei der app hat die
   nummer noch viel platz nach links". Mit `width: 1%` bleibt sie bei beiden
   Breiten bei 34,9 px, die Aktionsspalte bei 64,4 -- also genau das Bild des
   Prototyps, unabhaengig vom Fenster.

   Angenommen ist dabei die Form, die der Prototyp fuer `table.pos`
   durchgehend zeigt: schmale Nummer links, Text in der Mitte, und rechts eine
   Spalte, die nicht mitwachsen soll.

   Was rechts steht, ist nicht immer der Aktionsverweis des Prototyps. In der
   Positionstabelle des Auftrags ist die letzte Spalte der Vorgangspreis, in der
   Uebersichtskarte der Gesamtbetrag -- beide `class="r"`. Fuer eine
   rechtsbuendige Zahlenspalte trifft die Regel dasselbe Ziel: sie soll so breit
   sein wie ihr Inhalt und den Rest dem Text lassen. Der Kommentar sagte bis zum
   2026-09-02 nur „Aktionsspalte" und las sich damit, als greife die Regel hier
   versehentlich.

   Bekommt eine kuenftige Tabelle rechts eine Spalte, die mitwachsen SOLL,
   gehoert das zu einem Parameter statt zu einer festen Regel. */
.qb-pos[b-vtkaqhvju3]  thead th:first-child,
.qb-pos[b-vtkaqhvju3]  tbody td:first-child,
.qb-pos[b-vtkaqhvju3]  thead th:last-child,
.qb-pos[b-vtkaqhvju3]  tbody td:last-child {
    width: 1%;
    white-space: nowrap;
}

/* Die erste Spalte ist die Nummer und steht halbfett -- Prototyp
   `table.pos tbody td:first-child{font-weight:600}`. */
.qb-pos[b-vtkaqhvju3]  tbody td:first-child {
    font-weight: 600;
}

/* ── Summenpositionen ─────────────────────────────────────────────────────
   Vorgabe des Kunden: fett wie die Summenzeile im tfoot. 700 statt 600, weil
   600 schon die Positionsnummer jeder Zeile traegt. Klasse aus
   AuftragPositionen.RowClass. */
.qb-pos[b-vtkaqhvju3]  tbody tr.qb-pos-summe td {
    font-weight: 700;
}

/* Nicht belegte ZEILEN und der Verweis darin. Prototyp `.empty` und
   `.rowlink`.

   NICHT dasselbe wie der leere WERT (Bauteil `Wert`, Klasse `qb-leer`), auch
   wenn die zwei Zeilen gleich aussehen -- und das ist der Grund, warum §1.2
   hier nicht greift:

     `.empty`   traegt einen SATZ ueber die Tabelle: „Keine Positionen
                vorhanden", „nicht belegt". Er steht in einer Zelle mit
                `colspan` ueber die ganze Breite und ersetzt die Zeile.
     `qb-leer`  traegt den Gedankenstrich in EINER Zelle, deren Nachbarn
                Werte haben.

   Das Konzept trennt die beiden ebenso (`.empty` gegen `.muted`). Fielen sie
   zusammen, muesste eine leere Liste denselben Gedankenstrich zeigen wie eine
   leere Zelle -- und „keine Positionen vorhanden" waere nicht mehr zu sagen. */
.qb-pos[b-vtkaqhvju3]  .empty {
    color: var(--qb-text-subtle);
    font-weight: 400;
}

.qb-pos[b-vtkaqhvju3]  .rowlink {
    color: var(--qb-interactive-strong);
    font-weight: 600;
    text-decoration: none;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    font-size: inherit;
    font-family: inherit;
}

.qb-pos[b-vtkaqhvju3]  .rowlink:hover {
    text-decoration: underline;
}

/* ── Summenzeile ──────────────────────────────────────────────────────────
   Prototyp `table.pos tfoot td` (Z. 556): padding 6px 8px, Gewicht 700,
   Oberkante 1px --border-strong. Gilt fuer jede Tabelle dieser Sorte, nicht
   nur fuer die Positionen -- deshalb hier und nicht am Aufrufer. */
.qb-pos[b-vtkaqhvju3]  tfoot td {
    padding: 6px 8px;
    font-weight: 700;
    border-block-start: 1px solid var(--qb-border-strong);
}

/* ── Klebende Kopf- und Summenzeile ───────────────────────────────────────
   Prototyp `#postable thead th` / `#postable tfoot td` (Z. 557–558):

     thead th  position:sticky; top:0;    background:var(--surface-2); z-index:2
     tfoot td  position:sticky; bottom:0; background:var(--surface)

   Die beiden Flaechen sind NICHT dieselbe: der Kopf steht auf der erhoehten
   Flaeche, die Summenzeile auf der Kartenflaeche. Ohne eigene Flaeche waeren
   beide durchsichtig und der rollende Inhalt liefe sichtbar durch sie hindurch.

   z-index 2 wie im Prototyp und NICHT aus der Ebenenordnung (§7): die dortigen
   Stufen beginnen bei 20 und regeln Overlays gegeneinander. Hier geht es um
   zwei Zellen gegen die Zeilen derselben Tabelle -- ein oertlicher Stapel im
   Rollbereich, kein Overlay. Die Summenzeile liegt eins darueber, damit sie den
   Kopf ueberdeckt, wenn die Tabelle kuerzer ist als ihr Rollbereich.

   Der Rollbereich braucht `overflow-y` UND eine Hoehe -- die kommt als
   MaxHeight vom Aufrufer. Ohne Hoehe rollt nichts und `sticky` tut nichts. */
.qb-pos-wrap--sticky[b-vtkaqhvju3] {
    overflow-y: auto;
}

.qb-pos--sticky[b-vtkaqhvju3]  thead th {
    position: sticky;
    top: 0;
    background: var(--qb-surface-raised);
    z-index: 2;
}

.qb-pos--sticky[b-vtkaqhvju3]  tfoot td {
    position: sticky;
    bottom: 0;
    background: var(--qb-surface);
    z-index: 3;
}

/* ── Die Textspalte ───────────────────────────────────────────────────────
   `.qb-pos-text` auf einer Kopf- und der zugehoerigen Datenzelle. Prototyp:
   `<th style="min-width:170px">Text</th>` (Z. 2164).

   Die Obergrenze und das Abschneiden hat der Prototyp NICHT -- er braucht es
   auch nicht, seine Texte sind kurz. Echte Positionsbeschreibungen sind es
   nicht, und `white-space: nowrap` von oben zieht die Tabelle dann beliebig
   breit: der Wagen rollt waagerecht, obwohl die Spalten hineinpassen wuerden.
   "Lange Werte werden abgeschnitten, nie umgebrochen" (MUSS).

   Warum die Regel HIER steht und nicht beim Aufrufer: die Textspalte kommt in
   jeder der acht Positions-Sichten und in der Uebersichtskarte vor. Am
   2026-08-31 stand sie in AuftragPositionTab.razor.css -- und fehlte in der
   Uebersichtskarte, weil eine bereichsbezogene Klasse nicht in die naechste
   Komponente reicht. Genau die zweite Definition, die §1.2 verbietet.

   Ueber ::deep, weil die Zellen als RenderFragment von aussen kommen -- dieselbe
   Begruendung wie bei den Zellregeln oben. */
.qb-pos[b-vtkaqhvju3]  .qb-pos-text {
    min-width: 170px;
    max-width: 340px;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* _content/D3.Web/Components/Shared/Components/RadioGroup.razor.rz.scp.css */
/* Senkrechte Huelle mit 2 px zwischen Beschriftung und Bedienelement -- dieselben 2 px wie in
   jedem Feldbauteil (FieldShell, OptionRow, Textarea). Als Regel und nicht als
   `RadzenStack Gap="2px"`, weil die Huelle ein HTML-Element dieser Datei sein muss
   (Begruendung im Kopf von RadioGroup.razor). */
.qb-radiogroup[b-0eebzrvay8] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* _content/D3.Web/Components/Shared/Components/SearchBox.razor.rz.scp.css */
/* Suchfeld mit Löschknopf.

   Werte aus dem Prototyp, `.listbar .search` (Kompakt-Konzept v3, Z. 477–484):

     .search        { position: relative; flex: 1; max-width: 460px }
     .search input  { height: 30px; width: 100%; padding: 0 30px 0 30px }
     .search svg    { position: absolute; left: 8px; top: 7px; 15 x 15;
                      stroke: var(--text-3) }
     .search .clear { position: absolute; right: 4px; top: 4px; 22 x 22 }

   Die Feldhöhe kommt bewusst NICHT von hier: sie folgt der Dichte über
   --rz-input-height; die 30 px des Prototyps sind die Stufe Kompakt.

   `flex: 1` statt einer festen Breite -- so wächst das Feld mit seiner Leiste,
   bis 460 px. In der Listenleiste stand vorher `width: 280px`, und damit lief
   `max-width` ins Leere; am 2026-08-21 bemängelt (UI-TODO §5h, Zeile
   `div.search`).

   Das Polster links entsteht nur mit Lupe. Rechts steht es immer: der
   Löschknopf erscheint und verschwindet mit dem Inhalt, und ohne festes
   Polster würde der Text beim Tippen unter ihn rutschen. */

.qb-searchbox[b-poxm918brf] {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 0;
    max-width: 460px;
}

.qb-searchbox-input[b-poxm918brf] {
    width: 100%;
    box-sizing: border-box;
    padding-inline-end: 1.875rem;   /* 30 px -- Platz für den Löschknopf */
}

.qb-searchbox-input--icon[b-poxm918brf] {
    padding-inline-start: 1.875rem; /* 30 px -- Platz für die Lupe */
}

.qb-searchbox-icon[b-poxm918brf] {
    position: absolute;
    inset-inline-start: var(--qb-space-xs);
    color: var(--qb-text-subtle);
    font-size: var(--qb-icon-sm);
    width: var(--qb-icon-sm);
    height: var(--qb-icon-sm);
    pointer-events: none;
}

.qb-searchbox-clear[b-poxm918brf] {
    position: absolute;
    inset-inline-end: 4px;
    display: flex;
}
/* _content/D3.Web/Components/Shared/Components/SectionHead.razor.rz.scp.css */
/* Werte aus dem Kompakt-Konzept2, `.sec-head` (Z. 286-289):

     .sec-head        display flex, align-items baseline, gap 10px,
                      margin 2px 0 10px, flex-wrap wrap
     .sec-head h2     font-size 14px, font-weight 700, margin 0
     .sec-head .hint  12px, --text-3          (traegt unser Hint-Bauteil)
     .sec-head .right margin-left auto, display flex, gap 6px

   `align-items: baseline` ist der Grund, warum Ueberschrift und Beisatz auf
   einer Linie sitzen statt mittig zueinander -- bei 14 px gegen 12 px waere
   mittig sichtbar schief.

   `flex-wrap: wrap` laesst den Beisatz umbrechen, bevor er die Ueberschrift
   zusammendrueckt.

   14 px, 10 px, 2 px und 6 px stehen als Zahlen: Bauteilmasse des Prototyps,
   die nicht auf der Schrift- bzw. Abstandsleiter (4/8/12/16) liegen. Sie auf
   die naechste Stufe zu ziehen ist der Fehler, den MaskMenu.razor.css am
   Zellpolster beschreibt.

   700 und nicht die 600 unserer uebrigen Ueberschriften ist der Prototypwert:
   die Bereichsueberschrift traegt den ganzen Bereich, nicht bloss eine Gruppe. */

.qb-sechead[b-53vs92xoex] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 10px;
    margin: 2px 0 10px;
}

.qb-sechead-title[b-53vs92xoex] {
    margin: 0;
    font-size: 14px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--qb-text);
}

.qb-sechead-actions[b-53vs92xoex] {
    margin-inline-start: auto;
    display: flex;
    gap: 6px;
}
/* _content/D3.Web/Components/Shared/Components/SectionLabel.razor.rz.scp.css */
/* Textrollen oberhalb der Feldebene.

   ── Warum ein Bauteil und nicht vier .razor.css-Dateien ──────────────────
   Dieselben drei Regeln standen nach der dritten Staffel byte-identisch in
   InvoicePreviewTab, RandbemerkungContainer, WorkflowStepContainer und
   RechnungsportalPage. Die Vervierfachung war eine Folge der Migration: vorher
   stand *eine* Definition im globalen <style>-Block von RechnungsportalPage
   und wirkte von dort in die Kindkomponenten hinein. Beim Verlegen musste
   jede Kindkomponente ihre eigene Kopie bekommen -- und RechnungsportalPage
   behielt eine, die sie im eigenen Markup gar nicht braucht.

   Wirksam war danach keine einzige der vier: die Klassen saßen auf
   RadzenText, und Blazor setzt das Bereichsattribut nur auf einfache
   HTML-Elemente. Am laufenden Server gemessen -- die Texte standen in
   Radzens body1 (1 rem / 400 / #1C2B36) statt in der gemeinten Rolle.

   Das Bauteil löst beides und erfüllt zusätzlich **Regel 2 der sechs
   Bibliotheksregeln** aus der Grundlage: „Keine Anwendung stylt eine
   Komponente von außen. Wer etwas nicht einstellen kann, bekommt ein Token
   oder einen Parameter -- nie einen Selektor." Vier Selektoren auf RadzenText
   werden zu einem Parameter an einem eigenen Bauteil. Vorbild ist FieldLabel,
   das für die Feldbeschriftung genau denselben Weg gegangen ist.

   Der Kommentar in InvoicePreviewTab hatte das Bauteil schon vorgeschlagen
   („Kandidat für ein eigenes Bauteil (SectionLabel), sobald mehr als diese
   vier Stellen es brauchen"). Die Bedingung ist eingetreten, aber aus einem
   anderen Grund als erwartet: nicht weil es mehr Stellen wurden, sondern weil
   keine der vier funktionierte.

   ── Werte ────────────────────────────────────────────────────────────────
   Aus den vier abgelösten Dateien übernommen. Ausnahme ist die Feldgruppe:
   ihre Farbe und ihre Trennlinie sind am 2026-08-19 nach dem Bildvergleich
   gegen .fgh des Prototyps korrigiert worden, Begründung an der Regel.
   Schriftfamilie, Zeilenhöhe und Laufweite kommen aus Radzens body1, damit
   die Umstellung von <p> auf <div> nichts verschiebt -- am Browser
   abgelesen: 1.6 und 0.

   Radzen nullt die Außenabstände seiner Textklassen im Stapel
   (`.rz-text-body1 { margin-block: 0 }`). Das <div> hat von sich aus keine,
   also ist `margin: 0` hier nur die ausgeschriebene Absicht.

   Offen, wie bei FieldLabel: das ist kein <h2>/<h3>. Eine
   Abschnittsüberschrift sollte in der Dokumentgliederung auftauchen. Das
   gehört in den Barrierefreiheits-Durchgang zusammen mit <label for> --
   verschlechtert hat sich nichts, vorher war es ein <p>. */
.qb-section-label[b-mmcdg7jetc] {
    font-family: var(--qb-font-body);
    line-height: 1.6;
    letter-spacing: 0;
    margin: 0;
}

.qb-section-label--header[b-mmcdg7jetc] {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--qb-text-muted);
}

.qb-section-label--title[b-mmcdg7jetc] {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--qb-text);
}

.qb-section-label--subtitle[b-mmcdg7jetc] {
    font-size: 0.875rem;
    font-weight: 400;
    color: var(--qb-text-muted);
}

.qb-section-label--fieldgroup[b-mmcdg7jetc] {
    /* Prototyp `.fgh` -- die Form, die das laufende Konzept WIRKLICH zeigt:

         .fgh { font-size: 11.5px; font-weight: 700; letter-spacing: .7px;
                text-transform: uppercase; color: var(--accent-strong);
                border-bottom: 1px solid var(--border);
                padding-bottom: 7px; margin: 0 0 12px }

       ── Warum nicht `.fg`, und warum das zweimal gekippt ist ─────────────
       Im Quellmarkup des Prototyps steht `.fg` (Linie NEBEN dem Text, grau,
       11 px). Diese Form wird aber **nie angezeigt**: ein Skript im Konzept
       ("Feldgruppen-Karten (V5-Muster): Karten automatisch je Gruppe
       splitten", Z. 3832 ff.) laeuft beim Laden ueber jede `.card`, zerlegt
       sie in **eine Karte je Gruppe** (`div.card.fgcard`) und macht aus
       jedem `.fg` ein `<h3 class="fgh">`. Nachgezaehlt: **alle 25** `.fg`
       werden gesplittet, keines liegt in einem `.sheet` (dem einzigen
       Ausnahmefall des Skripts).

       Damit ist die Kette der Fehlentscheidungen aufgeloest:
       * 2026-08-19 stellte eine Sitzung das Bauteil auf die `.fgh`-Form um.
         Das war **richtig**, nur nicht begruendet.
       * 2026-08-21 habe ich es auf `.fg` zurueckgedreht, mit der Begruendung
         `.fgh` sei "definiert und 0-mal benutzt". Das war **falsch**: die
         Klasse entsteht zur Laufzeit im Skript, nicht im Markup. Genau der
         Fehler, der zwei Stunden vorher schon `.mm-frs` und `.mm-mobilebar`
         betroffen hatte (UI-INVENTAR, Fehler 23) -- und den ich beim Zaehlen
         der Karten nicht wiedererkannt habe.
       * Rückfrage vom 2026-08-21: "hast du auf dem schirm das diese unter die
         ueberschrift sollen?" -- ja, jetzt.

       Auch seine Bemerkung von vorher ("die farbe bei den ueberschriften
       fand ich eigentlich ganz gut") war **keine** Abweichung, die wir uns
       genehmigen: `.fgh` traegt im Prototyp selbst `--accent-strong`.

       11,5 px steht als px und nicht als rem: der Wert liegt nicht auf
       unserer Schriftleiter, und ihn auf die naechste Stufe zu ziehen war
       genau der Fehler, den die Rückmeldung am Zellpolster der Slotliste gefunden hat.
       Dieselbe Schreibweise wie in MaskMenu.razor.css. */
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.7px;
    text-transform: uppercase;
    color: var(--qb-interactive-strong);

    border-block-end: 1px solid var(--qb-surface-border);
    padding-block-end: 7px;
    margin: 0 0 12px;
}

/* _content/D3.Web/Components/Shared/Components/SectionPlaceholder.razor.rz.scp.css */
/* Maße der Karte aus §9.5: Polster 0.75/1/1 rem, Radius --qb-radius-card,
   1-px-Kante, kein Schatten. Abweichend gestrichelt und auf der gedämpften Fläche
   -- das unterscheidet „hier kommt noch etwas" von einer fertigen Karte, ohne
   eine neue Farbe zu erfinden. */

.qb-platzhalter[b-dw4kns2rmm] {
    padding: var(--qb-space-sm) var(--qb-space-md) var(--qb-space-md);

    border: 1px dashed var(--qb-surface-border);
    border-radius: var(--qb-radius-card);
    background: var(--qb-surface-sunken);
}

/* Kein Abstand nach oben: der Text ist seit dem 2026-09-02 das erste Kind der
   Fläche -- die Überschrift steht darüber, außerhalb. Vorher trug der Abstand den
   Zwischenraum zur Überschrift INNERHALB der Fläche. */
.qb-platzhalter-text[b-dw4kns2rmm] {
    margin: 0 0 var(--qb-space-xs);

    font-size: 0.875rem;
    color: var(--qb-text);
}
/* _content/D3.Web/Components/Shared/Components/StatusChip.razor.rz.scp.css */
/* Zustandsmarke. Maße aus dem Kompakt-Konzept v3, `.chip` (Z. 167–173):
   11 px, Gewicht 600, Polster 1/8 px, Radius 99, Lücke 5 px, kein Umbruch.

   Die Farben sind Token, keine Hexwerte — sonst geht der Dunkelmodus nicht mit.
   Zuordnung Konzept → unsere Ebene, jeweils Fläche und Schrift:

     .chip.on    --accent-soft / --accent-strong   → --qb-interactive-background / --qb-interactive-strong
     .chip.off   --surface-3   / --text-3          → --qb-surface-sunken        / --qb-text-subtle
     .chip.warn  --amber-soft  / --amber           → --qb-signal-background     / --qb-warning
     .chip.navy  --surface-3   / --navy            → --qb-surface-sunken        / --qb-primary
     (danger)    --danger                          → --qb-error-background      / --qb-error

   Bei `warn` steht bewusst --qb-warning (#9A6A00) und nicht --qb-signal (#F7A600):
   das Signalgelb ist eine Fläche, kein Text — auf hellem Grund wäre es nicht
   lesbar. Alle fünf Paare sind im gebauten odysys-base.css nachgesehen.

   Der Punkt hat keine eigene Farbe: `currentColor` nimmt die Schrift der Tonlage,
   damit je Tonlage nur ein Farbwert zu pflegen ist. */

.qb-chip[b-5kdyp8gaeh] {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 1px 8px;
    border-radius: 99px;
    font-size: 0.6875rem;   /* 11 px */
    font-weight: 600;
    line-height: 1.45;
    white-space: nowrap;
}

.qb-chip-dot[b-5kdyp8gaeh] {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex-shrink: 0;
}

.qb-chip--muted[b-5kdyp8gaeh] {
    background: var(--qb-surface-sunken);
    color: var(--qb-text-subtle);
}

.qb-chip--accent[b-5kdyp8gaeh] {
    background: var(--qb-interactive-background);
    color: var(--qb-interactive-strong);
}

.qb-chip--warn[b-5kdyp8gaeh] {
    background: var(--qb-signal-background);
    color: var(--qb-warning);
}

.qb-chip--navy[b-5kdyp8gaeh] {
    background: var(--qb-surface-sunken);
    color: var(--qb-primary);
}

.qb-chip--danger[b-5kdyp8gaeh] {
    background: var(--qb-error-background);
    color: var(--qb-error);
}

/* Zwei Tonlagen kamen am 2026-08-26 dazu, um näher an D3 zu kommen: dort ist
   „umgewandelt" hellgrün und „Absage" blau. Beide Paare folgen der Form der vier
   darüber -- Fläche aus der -background-Variante, Schrift aus der Vollfarbe. */

.qb-chip--success[b-5kdyp8gaeh] {
    background: var(--qb-success-background);
    color: var(--qb-success);
}

.qb-chip--info[b-5kdyp8gaeh] {
    background: var(--qb-info-background);
    color: var(--qb-info);
}
/* _content/D3.Web/Components/Shared/Components/Textarea.razor.rz.scp.css */
/* Prototyp `.field textarea`, Zeile 316:

     height: auto; min-height: 70px; padding: 6px 8px; resize: vertical

   Die Breite ist die der Rasterzelle -- ueber die ganze Karte nur mit einer
   Spanne. 70 und 6/8 sind Prototypmasse und stehen deshalb als Zahl.

   ::deep, weil das Feld von Radzen kommt und nicht in dieser Datei steht. */
/* Senkrechte Huelle, 2 px Abstand wie in jedem Feldbauteil. */
.qb-textarea[b-sl2hnprdt9] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

[b-sl2hnprdt9] .rz-textarea {
    width: 100%;
    box-sizing: border-box;
    height: auto;
    min-height: 70px;
    padding: 6px 8px;
    resize: vertical;
}
/* _content/D3.Web/Components/Shared/Components/TranslatableTextbox.razor.rz.scp.css */
/* Uebersetzbares Feld -- Prototyp `.transwrap`, `.globebtn`, `.transpop`.

   Masse aus dem Prototyp: Globus 4 px vom rechten und unteren Rand, Kantenlaenge
   Feldhoehe minus 8 px, Symbol 15 px, Punkt 6 px oben rechts; Popover 4 px unter dem
   Feld, mindestens 300 px breit, Zeilen als Raster 110 px | Rest. Farben und Radien
   nur aus Tokens, kein Hex. */

.qb-translatable[b-mp8ws6e7en] {
    position: relative;
}

/* Das Feld fuellt die Zelle wie eine Textbox im RadzenStack (dort dehnt flex, hier
   muss die Breite gesetzt werden -- ohne sie stand das Feld schmal und der Globus am
   Zellenrand, gemessen 2026-09-08). Rechts 30 px Innenabstand, damit der Globus nicht
   auf dem Text sitzt (Grundlage, MUSS). RadzenTextBox ist eine Komponente, deshalb ::deep. */
.qb-translatable[b-mp8ws6e7en] >  .rz-textbox {
    display: block;
    width: 100%;
    padding-right: 30px;
}

.qb-translatable-globe[b-mp8ws6e7en] {
    position: absolute;
    right: 4px;
    bottom: 4px;
    width: calc(var(--qb-density-field-height) - 8px);
    height: calc(var(--qb-density-field-height) - 8px);
    border: 0;
    border-radius: var(--qb-radius-control);
    background: none;
    cursor: pointer;
    display: grid;
    place-items: center;
    color: var(--qb-text-muted);
}

.qb-translatable-globe:hover[b-mp8ws6e7en] {
    background: var(--qb-interactive-background);
    color: var(--qb-interactive-strong);
}

.qb-translatable-globe .rzi[b-mp8ws6e7en] {
    font-size: 15px;
}

.qb-translatable-dot[b-mp8ws6e7en] {
    position: absolute;
    top: 1px;
    right: 1px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--qb-interactive);
}

/* Unsichtbare Klickflaeche ueber der ganzen Seite: ein Klick ausserhalb schliesst das
   Popover. Dieselbe Mechanik wie `.qb-drawer-backdrop` im QbDataGrid, nur ohne
   Abdunkelung -- der Prototyp dunkelt nicht ab. */
.qb-translatable-backdrop[b-mp8ws6e7en] {
    position: fixed;
    inset: 0;
    z-index: calc(var(--qb-z-popover) - 1);
}

.qb-translatable-popup[b-mp8ws6e7en] {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: var(--qb-z-popover);
    min-width: 300px;
    padding: 10px 12px;
    border: 1px solid var(--qb-border-strong);
    border-radius: var(--qb-radius-card);
    background: var(--qb-surface);
    box-shadow: var(--qb-shadow-overlay);
}

.qb-translatable-title[b-mp8ws6e7en] {
    margin: 0 0 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .6px;
    text-transform: uppercase;
    color: var(--qb-text-subtle);
}

.qb-translatable-row[b-mp8ws6e7en] {
    display: grid;
    grid-template-columns: 110px 1fr;
    gap: 6px 10px;
    align-items: center;
    margin-bottom: 5px;
}

.qb-translatable-row label[b-mp8ws6e7en] {
    margin: 0;
    font-size: 12px;
    color: var(--qb-text-subtle);
}

.qb-translatable-row[b-mp8ws6e7en]  .rz-textbox {
    width: 100%;
}
/* _content/D3.Web/Components/Shared/Components/ViewTabs.razor.rz.scp.css */
/* Sichten-Reiter. Werte aus dem Kompakt-Konzept2, `.tabs` und `.tabs .tab`
   (Z. 379–387), mit den qb-Token statt der Prototyp-Variablen:

     .tabs      flex, align-items:flex-end, gap:2px, flex-wrap:wrap,
                border-bottom 1px --border, margin 0 0 12px
     .tab       padding 7px 12px 8px, margin-bottom:-1px, 12.5px/1,
                --text-2, border-bottom 2px transparent, radius 7px 7px 0 0
     :hover     --text auf --surface-3
     .active    --accent-strong, 600, border-bottom-color --accent
     :focus-vis 2px --accent, offset -2px

   Die 12,5 px und die 2 px Lücke stehen als Zahl: für beide gibt es keinen
   Token (die Schriftleiter springt von 0.75rem = 12 auf 0.8125rem = 13, die
   Abstandsleiter beginnt bei 4). Es sind Bauteilmaße aus dem Prototyp, keine
   Werte der Layoutskala -- dieselbe Begründung wie beim Zellpolster in
   PosTable.

   Der Radius 7px 7px 0 0 ist NICHT --qb-radius-card (9px): ein Reiter ist ein
   Steuerelement, nicht eine Karte. Genommen ist --qb-radius-control (6px) --
   die Rolle, die §5.2 für Knöpfe und Chips nennt. Ein Pixel Unterschied zum
   Prototyp, dafür eine Rolle statt einer Zahl.

   `margin-bottom: -1px` zieht die 2-px-Unterstreichung des aktiven Reiters
   ueber die 1-px-Linie der Leiste. Ohne das stehen zwei Linien untereinander,
   und der aktive Reiter sieht doppelt unterstrichen aus. */

.qb-viewtabs[b-y177r04exz] {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 2px;

    margin: 0 0 var(--qb-space-sm);
    border-block-end: 1px solid var(--qb-surface-border);
}

.qb-viewtab[b-y177r04exz] {
    appearance: none;
    border: 0;
    background: transparent;
    box-shadow: none;

    padding: 7px 12px 8px;
    margin-block-end: -1px;

    font-family: var(--qb-font-body);
    font-size: 12.5px;
    line-height: 1;
    color: var(--qb-text-muted);

    border-block-end: 2px solid transparent;
    border-start-start-radius: var(--qb-radius-control);
    border-start-end-radius: var(--qb-radius-control);

    white-space: nowrap;
    cursor: pointer;
    transition: color var(--qb-transition-fast), background var(--qb-transition-fast);
}

.qb-viewtab:hover[b-y177r04exz] {
    color: var(--qb-text);
    background: var(--qb-surface-hover);
}

/* „Der aktive Reiter ist an Unterstreichung, Farbe und Schriftstärke erkennbar"
   (MUSS) -- alle drei, damit die Aussage nicht allein in der Farbe steckt. */
.qb-viewtab--active[b-y177r04exz] {
    color: var(--qb-interactive-strong);
    font-weight: 600;
    border-block-end-color: var(--qb-interactive);
}

.qb-viewtab:focus-visible[b-y177r04exz] {
    outline: var(--rz-outline-width) solid var(--qb-interactive);
    outline-offset: -2px;
}

/* Unter der Schwelle des Feldrasters bleibt die Leiste vollständig und wird
   waagerecht rollbar -- „Kein Inhalt verschwindet auf kleinen Bildschirmen. Er
   wird verlagert, gestapelt oder scrollbar -- nicht entfernt" (MUSS). Acht
   Reiter umbrechen sonst auf drei Zeilen und schieben die Tabelle aus dem Bild. */
@media (max-width: 760px) {
    .qb-viewtabs[b-y177r04exz] {
        flex-wrap: nowrap;
        overflow-x: auto;
    }
}
/* _content/D3.Web/Components/Shared/Components/Wert.razor.rz.scp.css */
/* Der Platzhalter fuer einen leeren Wert.

   `--qb-text-subtle` und nicht `-muted`: der Strich ist Beiwerk, kein Text, den
   man liest -- genau die Rolle, die §3.2 dafuer nennt („Platzhalter, Zaehler,
   Symbol im Ruhezustand"). Designsystem §9.3 fuehrt fuer die Liste dieselbe
   Paarung: „Leerer Wert | --qb-text-subtle / 400".

   Das Gewicht steht ausdruecklich da, obwohl 400 die Vorbelegung ist: dieses
   Bauteil steht auch in Zellen und Zeilen, die ihren Inhalt auszeichnen -- die
   erste Spalte der Positionstabelle ist halbfett (`tbody td:first-child`), die
   Wertzeile der Uebersicht laeuft mit 500. Ohne die 400 waere der Platzhalter
   dort mit ausgezeichnet und saehe aus wie ein Wert. */
.qb-leer[b-h20t2zbq5x] {
    color: var(--qb-text-subtle);
    font-weight: 400;
}
/* _content/D3.Web/Components/Shared/Components/WorkflowTimeline.razor.rz.scp.css */
/* Workflow-Zeitleiste. Werte aus dem Kompakt-Konzept2, `.timeline` (Z. 201-217):

     .timeline           flex, align-items flex-start, overflow-x auto, padding 6px 2px 2px
     .tl-step            flex 1, min-width 86px, position relative, text-align center
     .tl-step::before    absolut, top 9px, links/rechts 0, hoehe 2px  (die Verbindung)
     :first-child        left 50%          -- vor der ersten Stufe keine Linie
     :last-child         right 50%         -- nach der letzten keine
     .tl-dot             20px rund, z-index 1, margin 0 auto 4px
     .tl-lbl             11px/600, --text-2, line-height 1.25
     .tl-step.current .tl-lbl  --accent-strong
     .tl-sub             10px, --text-3
     @media <=480px      .tl-step min-width 70px

   FARBE DER LEISTE: seit dem 2026-09-08 die Farbe des AKTUELLEN STANDES, nicht mehr
   die Akzentfarbe -- Festlegung des Kunden vom 2026-09-07. Sie kommt als Variable
   --qb-tl-color von aussen (siehe unten bei .qb-tl-step--done::before). Die
   Akzentfarbe ist nur noch der Rueckfallwert; sie deckt sich deckungsgleich mit dem
   Prototyp (`.tl-step.current .tl-dot{border-color:var(--accent)}`, Z. 213):
   --qb-interactive ist sein --accent (#1A86B0 hell, #45A9D6 dunkel).

   Bis zum 2026-09-01 stand hier --qb-signal (Odysys-Gelb) nach der Regelsammlung
   ("aktuell (Ring mit Punkt, Odysys-Gelb)"). Entscheidung am 2026-09-01: der gelbe
   Kreis ist falsch, im Konzept ist er blau wie die Linie, die zu ihm fuehrt. Damit
   gilt der Prototyp -- und die Regelsammlung war hier ohnehin schwer zu halten: Gelb
   ist die Farbe fuer "hier ist etwas zu tun", der aktuelle Workflow-Schritt ist aber
   ein Zustand und keine Aufforderung.

   Dass erledigt und aktuell denselben Farbton tragen, ist kein Verlust an
   Unterscheidbarkeit: erledigt ist GEFUELLT mit Haken, aktuell ist ein RING mit Punkt
   und Hof, und die Verbindung rechts der aktuellen Stufe ist noch grau. Der Fortschritt
   bleibt ohne Zaehlen erkennbar.

   Die 86px, 20px, 2px, 11px und 10px stehen als Zahlen: Bauteilmasse des Prototyps,
   die nicht auf der Abstands- oder Schriftleiter liegen. Die 4-px-Leiter regelt
   Abstaende, nicht Durchmesser (§5.1). */

.qb-timeline[b-agcyie1p6v] {
    display: flex;
    align-items: flex-start;
    overflow-x: auto;
    padding: 6px 2px 2px;
}

.qb-tl-step[b-agcyie1p6v] {
    flex: 1;
    min-width: 86px;
    position: relative;
    text-align: center;
}

/* Die Verbindung LINKS der Stufe. Sie liegt auf halber Hoehe des Punktes
   (20px / 2 - 2px / 2 = 9px) und laeuft unter ihm durch -- der Punkt hat z-index 1. */
.qb-tl-step[b-agcyie1p6v]::before {
    content: "";
    position: absolute;
    top: 9px;
    left: 0;
    right: 0;
    height: 2px;
    background: var(--qb-border-strong);
}

.qb-tl-step:first-child[b-agcyie1p6v]::before {
    left: 50%;
}

.qb-tl-step:last-child[b-agcyie1p6v]::before {
    right: 50%;
}

/* --qb-tl-color: die Farbe des AKTUELLEN Standes, gesetzt als Variable am
   Wurzelelement (WorkflowTimeline.Farbe). Sie faerbt den erledigten Teil der Leiste
   samt aktueller Stufe; alles dahinter bleibt --qb-border-strong.

   Festlegung des Kunden vom 2026-09-07: "wenn der Status gruen vorgibt, ist die ganze
   Leiste gruen gefaerbt bis zu diesem aktiven Status." Also EINE Farbe fuer die Leiste
   und nicht eine je Stufe -- eine erledigte Stufe "Eingeplant" ist in einem
   fakturierten Auftrag dunkelgruen, nicht gruen. Werte in wwwroot/css/statuscolors.css.

   Der Rueckfallwert --qb-interactive haelt das Verhalten von vor dem 2026-09-08: ohne
   Stand (Auftrag ohne Positionen) und auf den vier Abzweigungen faerbt nichts, dann
   ist die Leiste ohnehin durchgehend grau -- der Rueckfall greift nur, wenn jemand die
   Leiste ohne StatusCode benutzt. */
.qb-tl-step--done[b-agcyie1p6v]::before {
    background: var(--qb-tl-color, var(--qb-interactive));
}

/* "Die Verbindung zur aktuellen Stufe ist halb gefuellt" (MUSS): links vom Punkt
   gefuellt, rechts offen. */
.qb-tl-step--current[b-agcyie1p6v]::before {
    background: linear-gradient(
        90deg,
        var(--qb-tl-color, var(--qb-interactive)) 50%,
        var(--qb-border-strong) 50%
    );
}

.qb-tl-dot[b-agcyie1p6v] {
    position: relative;
    z-index: 1;

    display: flex;
    align-items: center;
    justify-content: center;

    width: 20px;
    height: 20px;
    margin: 0 auto 4px;

    border: 2px solid var(--qb-border-strong);
    border-radius: 50%;
    background: var(--qb-surface);

    font-size: 11px;
    line-height: 1;
    color: var(--qb-on-primary);
}

/* Erledigt: gefuellt mit Haken, in der Statusfarbe.

   Der Haken nimmt --qb-tl-color-on und nicht weiterhin --qb-on-primary: auf Gelb
   (Status 4) und Hellblau (Status 5) ist Weiss nicht lesbar, und im Dunkelmodus kippt
   "schwarz" (Status 7) auf fast weiss -- dort braucht der Haken eine dunkle Farbe.
   Deshalb fuehrt die Palette zu jeder Farbe ihren Gegenwert. */
.qb-tl-step--done .qb-tl-dot[b-agcyie1p6v] {
    background: var(--qb-tl-color, var(--qb-interactive));
    border-color: var(--qb-tl-color, var(--qb-interactive));
    color: var(--qb-tl-color-on, var(--qb-on-primary));
}

/* Aktuell: Ring mit Punkt, in der Statusfarbe. Der Hof macht die Stufe auf einen Blick
   auffindbar, ohne die Flaeche zu fuellen -- gefuellt heisst "erledigt".

   Der Hof ist die Statusfarbe auf 22 % verduennt und nicht mehr das feste
   --qb-interactive-background: ein blauer Hof um einen dunkelgruenen Ring waere zwei
   Farben fuer einen Zustand. color-mix wird im Haus schon benutzt
   (ErrorPage.razor.css); faellt es aus, entfaellt der Hof -- Ring und Punkt tragen die
   Farbe weiter, die Stufe bleibt also erkennbar. */
.qb-tl-step--current .qb-tl-dot[b-agcyie1p6v] {
    border-color: var(--qb-tl-color, var(--qb-interactive));
    box-shadow: 0 0 0 3px color-mix(
        in srgb,
        var(--qb-tl-color, var(--qb-interactive)) 22%,
        transparent
    );
}

.qb-tl-step--current .qb-tl-dot[b-agcyie1p6v]::after {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--qb-tl-color, var(--qb-interactive));
}

.qb-tl-label[b-agcyie1p6v] {
    font-size: 11px;
    font-weight: 600;
    line-height: 1.25;
    color: var(--qb-text-muted);
}

.qb-tl-step--current .qb-tl-label[b-agcyie1p6v] {
    color: var(--qb-text);
}

.qb-tl-sub[b-agcyie1p6v] {
    font-size: 10px;
    color: var(--qb-text-subtle);
}

.qb-tl-num[b-agcyie1p6v] {
    font-variant-numeric: tabular-nums;
}

/* --qb-breakpoint-mobile */
@media (max-width: 480px) {
    .qb-tl-step[b-agcyie1p6v] {
        min-width: 70px;
    }
}
/* _content/D3.Web/Components/Shared/ErrorPages/ErrorPage.razor.rz.scp.css */
/* Fehlerseite. Lag als globaler <style>-Block im Markup.

   ── Warum jede Regel hier über .error-page-scope ::deep läuft ────────────
   Blazor setzt das Bereichsattribut **nur auf einfache HTML-Elemente** des
   eigenen Markups, nie auf Komponenten. Alle fünf Klassen dieser Datei sitzen
   aber auf Radzen-Komponenten (`RadzenCard`, `RadzenStack`, `RadzenText`).
   Ein `.error-card { … }` wird zu `.error-card[b-x]`, und dieses Attribut
   trägt die Karte nie -- die Regel greift nicht.

   Am laufenden Server gemessen (`/Anrede/999999`), bevor dieser Anker
   eingezogen wurde: kein einziges Element der Seite trug `b-57is0gugth`. Die
   Severity-Kante fehlte (1 px `#D9E0E6` statt 5 px `#B3352C`), die Karte war
   847 px breit statt 600, die Symbolkachel 74x80 px statt 64x64 mit
   Kartenpolster statt Tint, die Augenbraue 10 px in `#51636F`. Der ganze
   Block war wirkungslos.

   Deshalb steht im Markup eine Hülle `<div class="error-page-scope">`. Sie ist ein
   einfaches Element, bekommt das Attribut, und `::deep` schiebt es auf den
   Vorfahren: `.error-page-scope[b-x] .error-card`. `display: contents` hält die
   Hülle aus dem Layout heraus -- die fünf Varianten zentrieren die Karte in
   einem eigenen Container, und ein zusätzlicher Block dazwischen hätte diese
   Zentrierung verschoben. Auf die Selektor-Zuordnung hat `display: contents`
   keinen Einfluss.

   Das ist dasselbe Muster, das `HistoryItem`, `FieldShell` und
   `NavigationSidebar` schon benutzen: Anker auf einem einfachen Element,
   dann `::deep`. Neu ist nur, dass hier kein einfaches Element vorhanden war
   und eines eingezogen werden musste.

   ── Die drei !important ──────────────────────────────────────────────────
   Entfallen. Die Symbolkachel kämpft gegen `.rz-card.rz-variant-flat`
   (0,2,0); `.error-page-scope[b-x] .error_icon_card.error_icon_card__error` liegt
   bei 0,4,0 und gewinnt unabhängig von der Ladereihenfolge.

   ── Was die rz-Werte wirklich waren, am Kompilat nachgesehen ─────────────
     --rz-danger         -> var(--qb-error)        wertgleich
     --rz-danger-lighter -> var(--qb-error-tint)   wertgleich
     --rz-danger-dark    -> color-mix(in srgb, black 16%, var(--qb-error-accent))

   Kante und Kachelfüllung ändern sich also nicht sichtbar; hier fiel nur
   eine Umleitung weg. Die Augenbraue **wird heller**: `-dark` war Radzens
   Schattenstufe, keine Rolle. Die Rolle für Text auf der Fläche ist der
   Akzent. Gemessen: vorher `#962D25` und 7.78:1, jetzt `#B3352C` und
   6.07:1; die anderen beiden Schweregrade durch Klassentausch nachgemessen,
   Info 5.12:1, Warnung 4.73:1. Alle drei über 4.5:1 -- die Augenbraue ist
   mit 12 px/700 kein Großtext. Die Warnung hat nur noch 0.23 Luft; wenn dort
   eine Stufe dazu soll, gehört sie in den Token, nicht in diese Datei. */

.error-page-scope[b-57is0gugth] {
    display: contents;
}

.error-page-scope[b-57is0gugth]  .error-card {
    width: 600px;
}

.error-page-scope[b-57is0gugth]  .error-card.error-card__error {
    border-inline-start: 5px solid var(--qb-error);
}

.error-page-scope[b-57is0gugth]  .error-card.error-card__warning {
    border-inline-start: 5px solid var(--qb-warning);
}

.error-page-scope[b-57is0gugth]  .error-card.error-card__info {
    border-inline-start: 5px solid var(--qb-info);
}

.error-page-scope[b-57is0gugth]  .error-page__content {
    flex: 1;
    min-width: 0;
}

.error-page-scope[b-57is0gugth]  .error-page__buttons {
    margin-block-start: var(--qb-space-xs);
}

.error-page-scope[b-57is0gugth]  .error-page__eyebrow {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.08em;
}

.error-page-scope[b-57is0gugth]  .error-page__eyebrow.error-page__eyebrow__error {
    color: var(--qb-error-accent);
}

.error-page-scope[b-57is0gugth]  .error-page__eyebrow.error-page__eyebrow__warning {
    color: var(--qb-warning-accent);
}

.error-page-scope[b-57is0gugth]  .error-page__eyebrow.error-page__eyebrow__info {
    color: var(--qb-info-accent);
}

.error-page-scope[b-57is0gugth]  .error_icon_card {
    height: 4rem;
    width: 4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.error-page-scope[b-57is0gugth]  .error_icon_card.error_icon_card__error {
    background-color: var(--qb-error-tint);
}

.error-page-scope[b-57is0gugth]  .error_icon_card.error_icon_card__warning {
    background-color: var(--qb-warning-tint);
}

.error-page-scope[b-57is0gugth]  .error_icon_card.error_icon_card__info {
    background-color: var(--qb-info-tint);
}
/* _content/D3.Web/Components/Shared/Grids/GridEmptyState.razor.rz.scp.css */
/* Leerzustand im Tabellenkörper. Werte aus dem Entwurf „Leerzustände Liste"
   (Runde 1, Varianten 1b/1c/1f).

   Der Entwurf schreibt seine Farben als --surface/--text/--accent; das ist 1:1 unsere
   --qb-*-Ebene, und nur die steht hier. Kein Hexwert -- sonst geht der Dunkelmodus
   nicht mit.

     Entwurf            hier
     --surface          --qb-surface
     --surface-3        --qb-surface-sunken
     --border           --qb-surface-border
     --text             --qb-text
     --text-2           --qb-text-muted
     --text-3           --qb-text-subtle
     --accent           --qb-interactive
     --accent-soft      --qb-interactive-background
     --accent-strong    --qb-interactive-strong
     --navy-btn         --qb-primary
     --navy-text        --qb-on-primary

   Die Höhe von 200 px kommt ebenfalls aus dem Entwurf: genug, dass der Zustand
   auffällt, wenig genug, dass Kopf- und Fussleiste beieinander bleiben. */

.qb-empty[b-3q879p985v] {
    min-height: 200px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 24px 20px;
    text-align: center;
}

/* Die Größen stehen hier und nicht in der Klasse .rzi: die trägt nur die
   Symbolschrift, ihre Größe kommt aus --rz-icon-size (1 rem). Zwei Klassen
   überstimmen sie, weil der Bereichsschlüssel der Datei dazukommt. */

.qb-empty-icon[b-3q879p985v] {
    font-size: 28px;
    line-height: 1;
    color: var(--qb-text-subtle);
}

.qb-empty-title[b-3q879p985v] {
    font-size: 0.875rem;    /* 14 px */
    font-weight: 600;
    color: var(--qb-text);
}

.qb-empty-text[b-3q879p985v] {
    max-width: 400px;
    margin: 0;
    font-size: 0.75rem;     /* 12 px */
    line-height: 1.5;
    color: var(--qb-text-muted);
    text-wrap: pretty;
}

.qb-empty-hint[b-3q879p985v] {
    max-width: 400px;
    font-size: 0.6875rem;   /* 11 px */
    line-height: 1.45;
    color: var(--qb-text-subtle);
}

/* ── Marken ──────────────────────────────────────────────────────────────────
   Eine lösbare Marke ist ein <button>, eine reine Angabe ein <span>. Beide sehen
   gleich aus; der Knopf bekommt zusätzlich Zeiger und Hover, damit man merkt, dass
   er etwas tut. */

.qb-empty-chips[b-3q879p985v] {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    justify-content: center;
    margin-top: 2px;
}

.qb-empty-chip[b-3q879p985v] {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    height: 22px;
    padding: 0 8px;
    border: 1px solid var(--qb-surface-border);
    border-radius: 2px;
    background: var(--qb-surface-sunken);
    color: var(--qb-text-muted);
    font-family: inherit;
    font-size: 0.71875rem;  /* 11,5 px */
    white-space: nowrap;
}

.qb-empty-chip b[b-3q879p985v] {
    font-weight: 600;
    color: var(--qb-text);
}

.qb-empty-chip--removable[b-3q879p985v] {
    padding-inline-end: 5px;
    cursor: pointer;
}

.qb-empty-chip--removable:hover[b-3q879p985v] {
    border-color: var(--qb-border-strong);
}

.qb-empty-chip-x[b-3q879p985v] {
    font-size: 14px;
    color: var(--qb-text-subtle);
}

.qb-empty-chip--removable:hover .qb-empty-chip-x[b-3q879p985v] {
    color: var(--qb-text-muted);
}

/* ── Knopf ───────────────────────────────────────────────────────────────────
   Maße wie die Knöpfe der Listenleiste: 24 px hoch, Polster 0/8, 11,5 px, 600.
   Radius 2 aus dem Entwurf. */

.qb-empty-btn[b-3q879p985v] {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 24px;
    margin-top: 2px;
    padding: 0 8px;
    border: 1px solid var(--qb-interactive);
    border-radius: 2px;
    background: var(--qb-interactive-background);
    color: var(--qb-interactive-strong);
    font-family: inherit;
    font-size: 0.71875rem;  /* 11,5 px */
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
}

.qb-empty-btn:hover[b-3q879p985v] {
    border-color: var(--qb-interactive-strong);
}

.qb-empty-btn--primary[b-3q879p985v] {
    border-color: var(--qb-primary);
    background: var(--qb-primary);
    color: var(--qb-on-primary);
}

.qb-empty-btn--primary:hover[b-3q879p985v] {
    background: var(--qb-primary-accent);
    border-color: var(--qb-primary-accent);
}

.qb-empty-btn-icon[b-3q879p985v] {
    font-size: 14px;
}
/* _content/D3.Web/Components/Shared/Grids/QbDataGrid.razor.rz.scp.css */

.qb-grid-toolbar[b-qa0s3tdgtf] {
    --rz-grid-border-radius: 0 0 var(--qb-radius-card) var(--qb-radius-card);
}

/* Zur Geometrie der Kopfzelle steht hier KEINE Regel: nicht zum Griff, nicht zur
   Filterzelle. Griff, Beschriftung und Filterfeld sitzen, wo Radzen sie
   hinsetzt.

   Am 2026-08-24 habe ich daran dreierlei versucht -- Griff nach rechts, dann eine
   Luecke hinter dem Griff, dann einen Vorlauf an der Filterzelle. Nichts davon
   war verlangt, jedes hat die Zeile anders verschoben, und ich habe es
   jedes Mal als fertig gemeldet. Die Ansage: "du zerschiesst mir hier alles
   durch deine random versuche". Deshalb: hier wird nichts mehr in Pixeln
   verschoben. Wer die drei Kanten wirklich zusammenholen will, macht das als
   eigenen Auftrag, mit Messung am laufenden Programm und vorher abgestimmt.

   Was von diesem Tag bleibt, sind zwei Dinge, die ausdruecklich gewollt waren: das
   Loeschkreuz in der Spaltensuche (weiter unten, das Feld selbst unangetastet)
   und die Ausrichtung nach dem, was angezeigt wird (RechtsBuendig in
   QbDataGrid.razor.cs). */

.qb-listbar[b-qa0s3tdgtf] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    padding: var(--qb-space-xs) var(--qb-space-sm);
    flex-wrap: wrap;

        background: var(--qb-surface);
    border: 1px solid var(--qb-surface-border);
    border-bottom: none;
    border-radius: var(--qb-radius-card) var(--qb-radius-card) 0 0;
}

.qb-listbar-grow[b-qa0s3tdgtf] {
    flex: 1;
}

.qb-listbar[b-qa0s3tdgtf]  .qb-hint {
    white-space: nowrap;
}

.qb-listbar-divider[b-qa0s3tdgtf] {
    width: 1px;
    height: 18px;
    background: var(--qb-surface-border);
    flex-shrink: 0;
}

.qb-listbar-btn[b-qa0s3tdgtf] {
    display: inline-flex;
    align-items: center;
    gap: var(--qb-space-xxs);
    min-height: var(--qb-density-field-height);
    padding-inline: var(--qb-space-xs);
    box-sizing: border-box;
    border: 1px solid var(--qb-border-strong);
    border-radius: var(--qb-radius-control);
    background: var(--qb-surface);
    color: var(--qb-text);
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: background-color var(--qb-transition-fast), border-color var(--qb-transition-fast);
}

.qb-listbar-btn:hover[b-qa0s3tdgtf] {
    background: var(--qb-surface-raised);
}

.qb-listbar-btn--active[b-qa0s3tdgtf] {
    background: var(--qb-interactive-background);
    border-color: var(--qb-interactive);
    color: var(--qb-interactive-strong);
}

.qb-grid-toolbar .grid-toolbar-search[b-qa0s3tdgtf] {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    flex-wrap: wrap;
}

/* Die Regeln fuer das Suchfeld der Listenleiste (.grid-search, -icon, -clear)
   sind entfallen: das Feld ist seit dem 2026-08-21 die Komponente SearchBox,
   die ihr Aussehen selbst mitbringt. Die Werte des Prototyps stehen dort im
   Kopf von SearchBox.razor.css, nicht mehr zweimal. */

/* Schleier und Schublade stehen fest am FENSTER -- das haengt an Patch 31 im
   Theme. Radzen setzt `transform: translateZ(0)` auf `.rz-body`; damit wird der
   Rumpf zum Bezugsrahmen fuer `position: fixed`, und weil er zugleich der
   Rollbereich ist, rollt ein fest positioniertes Kind mit dem Inhalt weg. Am
   2026-08-27 gemessen: 344 px gerollt stand die Schublade auf oben -298 statt 0,
   ihre Unterkante bei 545 -- zu sehen war ein kurzer Kasten, der beim Rollen
   abbricht. Patch 31 nimmt die Matrix zurueck (beide Waehler, `.rz-body` UND
   `.rz-layout .rz-body`).

   Wer die Matrix dort wieder einfuehrt oder die Schublade in einen Vorfahren mit
   `transform`/`filter`/`contain` verschiebt, bricht das hier -- ohne
   Compilerfehler und ohne dass diese Datei sich aendert. Das Konzept verlangt die
   volle Hoehe: `.drawer { position: fixed; top: 0; bottom: 0; width: 330px }`
   (SKAI4 Kompakt-Konzept2). */

.qb-drawer-backdrop[b-qa0s3tdgtf] {
    position: fixed;
    inset: 0;
    z-index: calc(var(--qb-z-drawer) - 1);
    background: rgba(16, 28, 38, 0.35);
}

.qb-drawer[b-qa0s3tdgtf] {
    position: fixed;
    inset-block: 0;
    inset-inline-end: 0;
    width: 330px;
    max-width: 100vw;
    z-index: var(--qb-z-drawer);
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    background: var(--qb-surface);
    border-inline-start: 1px solid var(--qb-surface-border);
    box-shadow: -8px 0 24px rgba(16, 32, 45, 0.15);
}

.qb-drawer-head[b-qa0s3tdgtf] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    padding: var(--qb-space-sm) var(--qb-space-sm);
    border-block-end: 1px solid var(--qb-surface-border);
}

.qb-drawer-title[b-qa0s3tdgtf] {
    margin: 0;
    font-size: 0.875rem;
    font-weight: 700;
}

.qb-drawer-head[b-qa0s3tdgtf]  .qb-icon-button {
    margin-inline-start: auto;
}

.qb-drawer-search[b-qa0s3tdgtf] {
    padding: var(--qb-space-xs) var(--qb-space-sm) var(--qb-space-xxs);
}

/* Das Suchfeld war 14 px gross und 30 px hoch, die Liste darunter 12 px -- das
   Feld war also grösser als das, was es filtert. Der Prototyp schreibt 12,5 px
   und 28 px (`.drawer .dsearch input`). Hier 12 px und 28 px: die halbe Stufe
   gibt es in unserer Schriftleiter nicht, und 12 px ist dieselbe Grösse wie die
   Einträge. */

.qb-drawer-search[b-qa0s3tdgtf]  .rz-textbox {
    height: 28px;
    font-size: 0.75rem;
}

.qb-drawer-list[b-qa0s3tdgtf] {
    flex: 1;
    overflow-y: auto;
    padding: var(--qb-space-xxs) var(--qb-space-xs) var(--qb-space-sm);
}

.qb-drawer-item[b-qa0s3tdgtf] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    padding: var(--qb-space-xxs) var(--qb-space-xs);
    border-radius: var(--qb-radius-control);
    font-size: 0.75rem;
    line-height: 1.2;
    cursor: pointer;
}

.qb-drawer-item:hover[b-qa0s3tdgtf] {
    background: var(--qb-surface-sunken);
}


.qb-drawer-item--locked[b-qa0s3tdgtf] {
    cursor: not-allowed;
    color: var(--qb-text-subtle);
}

/* Die Fusszeile stand auf 14 px (geerbt) in der Textfarbe. Der Prototyp:
   `.drawer footer{padding:10px 14px;font-size:12px;color:var(--text-3)}` -- also
   12 px und die zurückgenommene Farbe, denn dort steht eine Auskunft ("x von y
   Spalten sichtbar"), kein Inhalt. */

.qb-drawer-foot[b-qa0s3tdgtf] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    padding: var(--qb-space-xs) var(--qb-space-sm);
    border-block-start: 1px solid var(--qb-surface-border);
    font-size: 0.75rem;
    color: var(--qb-text-subtle);
}

.qb-drawer-reset[b-qa0s3tdgtf] {
    margin-inline-start: auto;
}

/* .grid-columns-error ist ersatzlos entfallen. Der Hinweis, wenn der
   Spaltenkatalog nicht geladen werden konnte, war ein RadzenText mit einem
   von Hand gebauten Warnkasten -- und damit ein Selektor auf einer Komponente,
   der nie gegriffen hat (Blazor setzt das Bereichsattribut nur auf einfache
   HTML-Elemente). Gemessen stand der Hinweis als nackter Fließtext da.

   Jetzt ein RadzenAlert mit AlertStyle.Warning: dieselbe Aussage über einen
   Parameter statt über einen Selektor, wie Regel 2 der sechs
   Bibliotheksregeln es verlangt. Die Farben kommen damit aus dem Theme, das
   --rz-warning-* auf --qb-warning-* legt -- eine Ebene weniger als der
   Handkasten. */

.qb-grid-toolbar[b-qa0s3tdgtf]  .qb-grid-num {
    font-variant-numeric: tabular-nums;
}

/* Zahlen stehen rechts, ihre ÜBERSCHRIFT links.
   Rückmeldung vom 2026-08-26: "mir gefällt nicht das die tabellenüberschrift auch
   rechtsbündig ist bei zahlen, so wird oft der name abgeschnitten obwohl platz
   dafür ist [...] in den spalten selbst ist die rechtsbündigkeit okay."

   ── Warum hier und nicht über TextAlign ─────────────────────────────────────
   `RadzenDataGridColumn.TextAlign` gilt für Kopf UND Werte zugleich; ein
   `HeaderTextAlign` gibt es in 11.2.3 nicht (Paket-Doku). Und Radzen schreibt
   daraus einen **Inline-Stil** auf die Zelle
   (`style="width:223px;text-align:right;…"`, am 2026-08-26 im Browser gelesen) --
   dagegen hilft kein Wähler, nur `!important`.

   Deshalb setzt das Grid TextAlign nicht mehr, und die Ausrichtung der Werte
   steht hier. Damit entsteht die Inline-Angabe nie, und zwei Radzen-Regeln, die
   an ihr hängen, entfallen von selbst:

     thead th.rz-text-align-right .rz-column-title   justify-content: right
     … .rz-sortable-column .rz-column-title          padding-inline-start:
                                                     var(--rz-grid-sort-icon-width)

   Die zweite war die Ursache des abgeschnittenen Namens: ein rechtsbündiger,
   sortierbarer Kopf verlor links **1 rem** Polster für den Sortierpfeil -- auch
   wenn gar nicht nach der Spalte sortiert wurde. Bei „Von-Datum" ist das der
   Unterschied zwischen ganzem Wort und „Von-D…".

   `td` trifft nur Wertzellen; `qb-grid-num` sitzt auf Kopf und Wert. */

.qb-grid-toolbar[b-qa0s3tdgtf]  td.qb-grid-num {
    text-align: right;
}

/* EINE linke Kante für Überschrift, Spaltenfilter und Wert.
   Rückmeldung vom 2026-08-26: "der linksbündige spalteninhalt [ist] nicht inline mit dem
   kopf ... diese sollten so gespaced sein das sie inline mit der überschrift links
   sind (also inline mit der linken seite von spaltekopf und suchleiste der
   spalte)".

   Gemessen an der Spalte „Einsatzort" (Zellkante 360,2 px), vorher drei Kanten:

     Wert in der Zeile      370,2    Zellpolster 10 px
     Griff `⋮`              370,2    beginnt am Zellpolster
     Spaltenfilter          375,1    auf der Tinte der Punkte (Stand 2026-08-24)
     Überschrift            382,2    Zellpolster + Griffbreite

   Die Überschrift ist die Kante, die zählt -- sie ist das, was der Anwender liest.
   Ihr Einzug ist kein Zufallswert, sondern genau die Breite des Griffs: Radzen
   rendert `th > div > [Griff][Titel]` als Flex-Zeile, der Griff schiebt den Titel
   um seine eigene Breite nach rechts.

   Deshalb `0.625rem` (das waagerechte Zellpolster, --rz-grid-cell-padding und
   --rz-grid-header-cell-padding tragen beide diesen Wert) plus `--qb-icon-xs`
   (die Griffbreite, Theme-Token, gesetzt in themes/qb/_scales.scss und gelesen von
   Patch 28). Keine Zahl doppelt: ändert sich der Griff, wandert der Einzug mit.

   ── Was hier vorher stand ───────────────────────────────────────────────────
   Der Spaltenfilter lag auf der TINTE der drei Punkte (10 px + 0,35em),
   am 2026-08-24 so entschieden ("optisch auf die punkte"). Diese Entscheidung ist
   überholt, weil ihre Voraussetzung entfallen ist: der Griff ist seit dem
   2026-08-26 im Ruhezustand fast unsichtbar (--qb-surface-border). Auf die Tinte
   von Punkten auszurichten, die man nicht sieht, richtet auf nichts aus. Die
   ursprüngliche Anforderung vom 2026-08-24 war ohnehin diese: "diese waren bündig
   mit dem anfang der überschrift und nicht mit dem greifer".

   Rechtsbündige Zahlenspalten bleiben unberührt -- ihre Werte hängen an der
   rechten Kante, und die bleibt, wie sie war ("stoesst sauber an der rechten seite
   mit dem ende der spalte an"). Ihr Filterfeld wandert mit, damit die Filterzeile
   eine Linie behält. */

/* ── Nachtrag 2026-08-27: die Spaltensuche geht zurueck auf die Punkte ───────
   Rückmeldung: "die ausrichtung vom spalteninhalt gefaellt mir nur finde ich es doch
   schoener wenn die spaltensuche links so breit ist das es inline mit den 3
   punkten ist." Die Werte der Zeile bleiben also, wo sie sind (Ueberschriftkante,
   22 px) -- nur das Filterfeld wandert nach links.

   Wohin genau, gemessen am 2026-08-27: die Griffbox beginnt bei 10 px ab
   Zellkante, die TINTE der Punkte erst bei 14. Der Griff ist ein Pseudoelement
   (`.rz-column-drag::after`, Ligatur `more_vert`, Material Symbols 12 px, kein
   Textinhalt), die Tinte laeuft im Vorschub von 4 bis 8 -- gemessen mit
   `measureText` und `actualBoundingBox*` bei geladener Schrift. 4 von 12 ist ein
   Drittel der Symbolstufe, deshalb `var(--qb-icon-xs) / 3` und keine Zahl: waechst
   das Symbol, wandert die Kante mit.

   Am 2026-08-24 stand hier fuer dieselbe Absicht `0.35em` (gemessen 14,9 px). Der
   Wert war richtig gemeint und um 1 px daneben, weil `em` an der Zellschrift hing
   und nicht an der Symbolstufe.

   Die Begruendung, mit der es am 2026-08-26 auf die Ueberschriftkante wanderte
   ("auf unsichtbare Punkte auszurichten richtet auf nichts aus"), ist damit
   ueberstimmt -- durch eine Entscheidung, und sie verliert ohnehin an Gewicht, sobald der Kopf
   ueberfahren wird: dann sind Punkte UND Teilerlinie sichtbar (Patch 28, Patch 32).
   ─────────────────────────────────────────────────────────────────────────── */

.qb-grid-toolbar[b-qa0s3tdgtf]  .rz-cell-filter {
    padding-inline-start: calc(0.625rem + var(--qb-icon-xs) / 3);
}

.qb-grid-toolbar[b-qa0s3tdgtf]  td:not(.qb-grid-num) {
    padding-inline-start: calc(0.625rem + var(--qb-icon-xs));
}

/* Das Aussehen der FILTERZEILE -- Flaeche, Hoehe und die schwache Trennlinie --
   steht vollstaendig im Theme, in einer Regel:
   `themes/qb/_patches-late.scss`, Waehler `tr:has(> th > .rz-cell-filter) > th`.
   Dort stehen auch die Konzeptwerte und die Begruendung.

   Hier bitte KEINE zweite Regel dafuer anlegen. Bis zum 2026-08-27 stand die
   Trennlinie hier und die Flaeche im Theme; das waren zwei Stellen fuer eine Sache,
   und davor drei Schreibweisen. Vorgabe: "ich will nicht in 3 verschiedenen seite
   verschiedene wege sehen um eine sache zu bearbeiten". */

/* Die Mitte des Auswahlfelds steht nicht hier, sondern als Patch 30 im Theme: der
   Fehler betrifft JEDES Auswahlfeld der Anwendung, nicht nur den Spaltenfilter --
   in der Fussleiste sass die Seitengroesse genauso 2,4 px zu hoch. Hier stand
   zuerst eine Regel nur fuer Felder mit Chip; die war zu eng gefasst. */

/* Loeschkreuz in der Spaltensuche.

   Am Feld selbst aendert sich NICHTS: es bleibt derselbe RadzenTextBox mit
   denselben Werten. Der erste Versuch am 2026-08-24 hatte das Feld gegen die
   SearchBox getauscht -- und damit war es groesser und anders gestaltet als das
   Auswahlfeld daneben. Vorgabe: "füge das x ein aber ändere nichts am styling der
   spaltensuche". Also nur eine Huelle mit `position: relative` und der Knopf
   darueber; kein Polster, keine Breite, keine Hoehe am Eingabefeld.

   `.rz-cell-filter-content` ist eine Flexzeile (`display: flex; flex: auto`),
   deshalb traegt die Huelle `flex: 1` und `min-width: 0` -- sonst schrumpft sie
   in schmalen Spalten unter die Breite des Feldes.

   Falle, dieselbe wie bei SearchBox: die Klasse traegt ein <span> und nicht der
   IconButton. Blazor setzt das Bereichsattribut nur auf einfache HTML-Elemente;
   auf der Komponente bekaeme die Regel keines und wuerde nie greifen. */
.qb-filter-cell[b-qa0s3tdgtf] {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1;
    min-width: 0;
}

.qb-filter-cell-clear[b-qa0s3tdgtf] {
    position: absolute;
    inset-inline-end: 4px;
    display: flex;
}

/* Fußleiste weg, wenn sie nichts zu tun hat -- bei einem Treffer ist sie hoeher als
   die Zeile darueber. Wann das gilt, entscheidet FusszeileUeberfluessig; hier wird es
   nur unsichtbar gemacht, die Blaetterung selbst bleibt an.

   Der Waehler zielt auf <nav class="rz-pager"> -- das ist die Wurzel von
   RadzenPager (RadzenPager.razor Z. 4, Klasse aus GetComponentCssClass Z. 43), und
   `.rz-pager` steht auch im gebauten odysys-base.css. Ein einfaches HTML-Element in
   einer Fremdkomponente, deshalb ::deep. */

.qb-grid-toolbar--nopager[b-qa0s3tdgtf]  .rz-pager {
    display: none;
}
/* _content/D3.Web/Components/Shared/Grids/WorkTiles.razor.rz.scp.css */
/* Arbeitsvorrat-Kacheln. Werte aus dem Kompakt-Konzept 3, `.wtiles`/`.wtile`
   (Z. 336–353, enge Bildschirme Z. 863 und 896–897).

   Der Entwurf schreibt seine Farben als --surface/--border/--accent; das ist 1:1
   unsere --qb-*-Ebene, und nur die steht hier. Kein Hexwert -- sonst geht der
   Dunkelmodus nicht mit.

     Entwurf            hier
     --surface          --qb-surface
     --border           --qb-surface-border
     --border-strong    --qb-border-strong
     --accent           --qb-interactive
     --text             --qb-text
     --text-3           --qb-text-subtle
     --shadow (= none)  --qb-shadow-flat
     --amber            --qb-signal
     --navy             --qb-primary
     --danger           --qb-error

   Bei --amber steht hier --qb-signal (#F7A600) und NICHT --qb-warning wie beim Chip:
   dort ist die Tonlage die Schriftfarbe und das Signalgelb auf hellem Grund nicht
   lesbar, hier ist sie eine 4 px breite Fläche. Gleiche Tonlage, andere Rolle.

   Die Tonlagen tragen dieselben Namen wie beim Wert-Chip, damit ein Schritt in der
   Kachel und in der Zeile gleich aussieht -- siehe StatusChip.razor.css.

   ── Radien: Konzept 2, nicht Konzept 3 ──────────────────────────────────────
   Die beiden Konzepte widersprechen sich: Konzept 3 schreibt 3 px fuer die Kachel
   und 2 px fuer die Leiste, Konzept 2 schreibt 9 px und 4 px. Fuer Radien gilt im
   Projekt Konzept 2 (Commit 9b285257, "Radien kommen aus Konzept 2"), und die Kachel
   ist eine Flaeche wie das Panel darunter: `.qb-listbar` und `.rz-datatable` messen
   im Browser 9 px. Deshalb --qb-radius-card (0.5625rem = 9 px) und 4 px, und nicht
   die Zahl aus Konzept 3. Am 2026-08-26 im Browser gegen beide Vorlagen gemessen. */

.qb-wtiles[b-ffr0ork1mk] {
    display: grid;
    grid-template-columns: repeat(var(--qb-wtiles-n, 5), minmax(0, 1fr));
    gap: 12px;
}

/* Kein margin-bottom, obwohl der Entwurf 14 px schreibt: dort steht der Kachelblock
   in einem Fluss ohne Zwischenabstand, hier in einem RadzenStack mit Gap 16. Beides
   ergaebe 30 px nach unten und 16 px nach oben -- am 2026-08-26 im Browser gemessen,
   So auch in der Rückmeldung. Der Abstand kommt aus dem Stapel, damit Kopf, Kacheln und
   Liste denselben Rhythmus haben. */

/* Der Entwurf schreibt fünf Spalten fest, weil er fünf Kacheln hatte. Hier kommt die
   Zahl aus der Definition (--qb-wtiles-n, gesetzt im Markup): bei fünf Kacheln ist es
   derselbe Satz, beim Rechnungsportal mit sechs Schritten bleibt die Reihe eine
   Reihe statt eine einzelne Kachel umzubrechen. */

@media (max-width: 1100px) {
    .qb-wtiles[b-ffr0ork1mk] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Sehr schmal: Wischleiste statt Raster, wie im Entwurf. */
@media (max-width: 480px) {
    .qb-wtiles[b-ffr0ork1mk] {
        display: flex;
        overflow-x: auto;
        gap: 10px;
        padding-bottom: 4px;
    }

    .qb-wtile[b-ffr0ork1mk] {
        flex: 0 0 46%;
        min-width: 150px;
    }
}

.qb-wtile[b-ffr0ork1mk] {
    position: relative;
    min-width: 0;
    padding: 10px 12px 10px 18px;
    border: 1px solid var(--qb-surface-border);
    border-radius: var(--qb-radius-card);
    background: var(--qb-surface);
    box-shadow: var(--qb-shadow-flat);
    color: var(--qb-text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

/* Die Leiste links: 4 px breit, oben und unten 9 px eingerückt. Sie trägt die
   Tonlage des Schritts -- ohne Angabe bleibt sie neutral. */
.qb-wtile[b-ffr0ork1mk]::before {
    content: "";
    position: absolute;
    left: 0;
    top: 9px;
    bottom: 9px;
    width: 4px;
    border-radius: 4px;
    background: var(--qb-border-strong);
}

.qb-wtile--warn[b-ffr0ork1mk]::before {
    background: var(--qb-signal);
}

.qb-wtile--accent[b-ffr0ork1mk]::before {
    background: var(--qb-interactive);
}

.qb-wtile--navy[b-ffr0ork1mk]::before {
    background: var(--qb-primary);
}

.qb-wtile--danger[b-ffr0ork1mk]::before {
    background: var(--qb-error);
}

/* Dieselben zwei Tonlagen wie beim Chip (success, info). Hier die Vollfarbe, weil
   die Leiste eine Flaeche ist -- beim Chip ist die Tonlage die Schriftfarbe. */

.qb-wtile--success[b-ffr0ork1mk]::before {
    background: var(--qb-success);
}

.qb-wtile--info[b-ffr0ork1mk]::before {
    background: var(--qb-info);
}

.qb-wtile:hover[b-ffr0ork1mk] {
    border-color: var(--qb-interactive);
}

/* Gewählt: Rahmen in der Interaktionsfarbe, verstärkt durch einen inneren Strich.
   Zwei Kennzeichen statt einem, damit die Wahl auch bei schwachem Kontrast auffällt
   -- so steht es im Entwurf. */
.qb-wtile--on[b-ffr0ork1mk] {
    border-color: var(--qb-interactive);
    box-shadow: inset 0 0 0 2px var(--qb-interactive);
}

.qb-wtile-n[b-ffr0ork1mk] {
    display: block;
    font-size: 1.5rem;      /* 24 px */
    font-weight: 700;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

.qb-wtile-l[b-ffr0ork1mk] {
    display: block;
    margin-top: 1px;
    font-size: 0.75rem;     /* 12 px */
    font-weight: 600;
}

.qb-wtile-h[b-ffr0ork1mk] {
    display: block;
    margin-top: 1px;
    font-size: 0.6875rem;   /* 11 px */
    color: var(--qb-text-subtle);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* _content/D3.Web/Components/Shared/NavigationSidebar.razor.rz.scp.css */

.skai4-nav-rail[b-wa7t9ngjo9] {
    --rz-icon-size: var(--qb-icon-md);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--qb-space-xxs);
    padding: 8px 6px;
    width: var(--skai4-rail-width);
    box-sizing: border-box;
}

.skai4-nav-rail-item[b-wa7t9ngjo9] {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 30px;
    border-radius: var(--qb-radius-control);
    color: var(--qb-text-muted);
    cursor: pointer;
    text-decoration: none;
    transition: background-color var(--qb-transition-fast), color var(--qb-transition-fast);
}

.skai4-nav-rail-item:hover[b-wa7t9ngjo9] {
    background-color: var(--qb-surface-sunken);
    color: var(--qb-text);
    text-decoration: none;
}

.skai4-nav-rail-item-active[b-wa7t9ngjo9] {
    background-color: var(--qb-interactive-background);
    color: var(--qb-interactive-strong);
    font-weight: 600;
}

.skai4-nav-rail-item-active:hover[b-wa7t9ngjo9] {
    background-color: var(--qb-interactive-background);
    color: var(--qb-interactive-strong);
}

.skai4-nav-rail-item-active[b-wa7t9ngjo9]:before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    border-radius: var(--qb-radius-control) 0 0 var(--qb-radius-control);
    background-color: var(--qb-interactive-strong);
}

.skai4-nav-flyout-overlay[b-wa7t9ngjo9] {
    position: fixed;
    top: var(--qb-header-height);
    left: var(--skai4-rail-width);
    right: 0;
    bottom: 0;
    z-index: calc(var(--qb-z-drawer) - 1);
    background: transparent;
}

.skai4-nav-flyout[b-wa7t9ngjo9] {
    --rz-panel-menu-item-padding-block: var(--qb-space-xxs);
    --rz-panel-menu-item-padding-inline: var(--qb-space-xs);
    position: fixed;
    top: var(--qb-header-height);
    left: var(--skai4-rail-width);
    bottom: 0;
    width: 260px;
    z-index: var(--qb-z-drawer);
    background-color: var(--qb-surface);
    box-shadow: 2px 0 8px rgba(0, 0, 0, 0.12);
    overflow-y: auto;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
}

.skai4-nav-flyout-header[b-wa7t9ngjo9] {
    font-weight: 600;
    font-size: 0.9rem;
    padding: var(--qb-space-sm) var(--qb-space-md);
    color: var(--qb-text);
    border-bottom: 1px solid var(--qb-surface-border);
}

.skai4-nav-search[b-wa7t9ngjo9] {
    display: flex;
    align-items: center;
    gap: var(--qb-space-xs);
    padding-block: var(--qb-space-xxs);
    padding-inline: var(--qb-space-sm);
    border-radius: var(--qb-radius-control);
}

.skai4-nav-search:focus-within[b-wa7t9ngjo9] {
    background-color: var(--qb-surface-hover);
}

.skai4-nav-search[b-wa7t9ngjo9]  .rzi {
    height: 16px;
    width: 16px;
    font-size: 16px;
    color: var(--qb-text-muted);
    flex-shrink: 0;
}

/* `padding: 0` stand hier, solange die Lupe ein Flex-Geschwister des Feldes war
   und der Abstand aus dem `gap` der Huelle kam. Seit dem 2026-08-21 bringt
   `SearchBox` die Lupe selbst mit -- sie liegt absolut im Feld, und den Platz
   dafuer macht das Feld ueber sein eigenes `padding-inline-start`. Mit `padding: 0`
   hier stand die Lupe deshalb IM Text. In der Rückmeldung gefunden: "in der suche im rail
   und burgermenue ist das lupen icon jetzt im text."

   Rand, Hintergrund und Schatten bleiben aus: das Feld sitzt in einer eigenen
   Huelle, die den Rahmen und den Fokuszustand traegt. */
.skai4-nav-search[b-wa7t9ngjo9]  .rz-textbox {
    flex: auto;
    appearance: none;
    -webkit-appearance: none;
    border: none;
    background: transparent;
    box-shadow: none;
    font-size: inherit;
    color: inherit;
}

.skai4-nav-search[b-wa7t9ngjo9]  .rz-textbox::-webkit-search-cancel-button,
.skai4-nav-search[b-wa7t9ngjo9]  .rz-textbox::-webkit-search-decoration {
    -webkit-appearance: none;
}
