/* =========================================================================
   Dataflor Theme-Tokens (CSS-first Theming)

   Dark ist Default (entspricht ThemeState.IsDarkMode = true). DfBlazorSetup
   setzt die Klasse df-theme-dark bzw. df-theme-light am <html>-Element
   (browserInterop.js applyTheme). Alle theme-abhängigen Styles hängen an
   diesen Variablen – ein Theme-Wechsel greift dadurch sofort im ganzen DOM,
   ohne dass Komponenten neu rendern müssen (analog zu MudBlazors
   --mud-palette-* Variablen).
   ========================================================================= */
:root {
    --df-paper-primary-bg: #1B1915;
    --df-paper-secondary-bg: #14120E;
    --df-paper-shadow: rgba(0, 0, 0, 0.4) 0px 1px 3px 0px, rgba(0, 0, 0, 0.5) 0px 1px 2px -1px, rgba(255, 255, 255, 0.15) 0px 0px 0px 1px;
    --df-page-background: #14120E;
    --df-page-color: #ffffff;
    /* Map-/Selektionsgruen (df-ui-theme primary[500]): Dark #DFFA33, Light #AFCA05 */
    --df-accent-green: #DFFA33;
    /* Schrift und Symbole auf einer Akzentflaeche. In beiden Themes derselbe Wert, weil
       das Gruen in beiden hell ist. Identisch zu DfMudTheme.OnAccent (dort als
       PrimaryContrastText gesetzt); bei Aenderungen synchron halten. */
    --df-on-accent: #14120E;
    /* Uebersichten (DfOverview*): Tabellenkopf, Trennlinien, Hover und gedaempfter Text.
       Werte an der MyDATAflor-Projektuebersicht ausgerichtet. */
    --df-table-head-bg: #211E19;
    --df-border-subtle: rgba(255, 255, 255, 0.08);
    --df-row-hover-bg: rgba(255, 255, 255, 0.05);
    --df-text-muted: rgba(255, 255, 255, 0.55);
}

html.df-theme-light {
    --df-paper-primary-bg: rgb(255, 255, 255);
    --df-paper-secondary-bg: rgb(255, 255, 255);
    --df-page-background: #EFEEEE;
    --df-page-color: #000000;
    --df-accent-green: #AFCA05;
    --df-table-head-bg: #F4F4F5;
    --df-border-subtle: rgba(0, 0, 0, 0.10);
    --df-row-hover-bg: rgba(0, 0, 0, 0.04);
    --df-text-muted: rgba(0, 0, 0, 0.55);
}

/* Theme-agnostische Klassen – von DfMudTheme.GetPaperTheme()/PageBackground() geliefert. */
.paper-primary,
.paper-secondary {
    box-shadow: var(--df-paper-shadow);
    padding: 10px;
    border-radius: 10px;
}

.paper-primary {
    background-color: var(--df-paper-primary-bg);
}

.paper-secondary {
    background-color: var(--df-paper-secondary-bg);
}

.page-background {
    background-color: var(--df-page-background);
    color: var(--df-page-color);
}

/* Aufmass-/LV-Baum:
   - Selektion/Auswahl = Map-Grün (--df-accent-green)
   - Dark Mode: Textfarbe DATAflor-Weiss (#FBFBFB = text.primary Dark);
     html:not(.df-theme-light) deckt auch den Initialzustand ab, bevor
     DfBlazorSetup die Themeklasse gesetzt hat (Default = Dark). */
.df-tree-paper {
    --mud-palette-primary: var(--df-accent-green);
}

html:not(.df-theme-light) .df-tree-paper,
html:not(.df-theme-light) .df-tree-layout-popover {
    --mud-palette-text-primary: #FBFBFB;
    --mud-palette-text-secondary: #FBFBFB;
    color: #FBFBFB;
}

/* Aufklapp-Pfeil in LV- und Messungsbaum: eigene Spalte links vom Knotensymbol. Feste
   Breite, damit die Symbole von Knoten mit und ohne Kinder in derselben Spalte stehen. */
.df-tree-expand {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: var(--df-tree-line, 20px);
    cursor: pointer;
    margin-right: 5px;
}

/* Knotensymbol (20px) in Messungs- und LV-Baum, auf die Mitte der ersten Textzeile gesetzt. Die
   Abstaende der Zeile stehen hier statt als MudStack-Spacing, weil das in 4px-Schritten rechnet
   und die gewuenschten Werte (5px zum Pfeil, 9px zum Text) nicht trifft. */
.df-tree-icon {
    margin-right: 9px;
    margin-top: calc((var(--df-tree-line, 20px) - 20px) / 2);
}

.df-tree-expand .mud-icon-root {
    color: var(--mud-palette-text-secondary);
}

/* Zeile in Messungs- und LV-Baum: eigener Flex-Container statt display:contents, damit sie als
   Drag-Quelle und Drop-Ziel ein eigenes Element ist und die Mehrfachauswahl per :has() auf dem
   MudBlazor-Inhaltselement eingefaerbt werden kann (gleiche Flaeche wie dessen Einzelselektion).
   Pfeil und Symbol haengen an der ersten Textzeile, nicht an der Zeilenmitte. */
.df-tree-row {
    display: flex;
    align-items: flex-start;
    flex: 1 1 auto;
    min-width: 0;
    /* Hoehe einer Textzeile (body1): Pfeil, Symbol und Aktionen richten sich darauf aus. */
    --df-tree-line: calc(var(--mud-typography-body1-size, 14px) * var(--mud-typography-body1-lineheight, 1.5));
    /* Jede Zeile ist Container fuer die Schmal-Regel unten (Nummer als Kopfzeile). */
    container-type: inline-size;
}

/* Option "Zeilen mit Luft": etwas Padding und runde Ecken fuer Hover und Selektion. Drei Klassen, damit
   die Regel MudBlazors .mud-treeview-dense .mud-treeview-item-content (1px 4px) sicher ueberstimmt. */
.df-tree-paper.df-tree-rounded .mud-treeview .mud-treeview-item-content {
    padding: 2px 6px;
    border-radius: 6px;
}

/* Beschriftung einer Zeile in Messungs- und LV-Baum: Text links (waechst), Wert rechts auf der
   Panelkante. Reicht die Breite nicht fuer beide, rueckt der Wert als Ganzes in die naechste Zeile
   (weiter rechtsbuendig) und der Text bekommt die volle Breite. */
.df-tree-label {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0 8px;
    flex: 1 1 auto;
    min-width: 0;
}

/* Textteil: Nummer (feste Spalte) und Name (waechst, bricht mit haengendem Einzug um). Lange Namen
   ohne Leerzeichen brechen, statt die Zeile zu verbreitern. */
.df-tree-label-text {
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex: 1 1 auto;
    min-width: 0;
}

.df-tree-number {
    flex: 0 0 auto;
    opacity: .62;
    font-variant-numeric: tabular-nums;
}

.df-tree-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Option "Hierarchien fett": Ordner im Messungsbaum und Hierarchien im LV halbfett als Gliederung. */
.df-tree-bold .df-tree-row-hierarchy .df-tree-name {
    font-weight: 600;
}

/* Rechter Teil der Beschriftung: der Wert (TreeValue), rechtsbuendig auf der Kante. */
.df-tree-label-end {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 0 4px;
    flex: 0 1 auto;
    min-width: 0;
    margin-left: auto;
}

/* Werkzeugspalte am Zeilenende: der Menue-Button (drei Punkte) an der selektierten Zeile und im
   Ebenen-Modus das Chevron zum Oeffnen. Feste Plaetze von 20px, auch leer, damit der Wert in allen
   Zeilen auf derselben Kante steht und nicht springt, wenn ein Button erscheint. */
.df-tree-tools {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    height: var(--df-tree-line);
    margin-left: 4px;
}

.df-tree-tool {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
}

.df-tree-tool .mud-icon-button,
.df-tree-back .mud-icon-button {
    padding: 0;
}

/* MudTooltip legt um jeden Button einen Inline-Wrapper mit eigener Zeilenbox, der den Button um
   knapp 1px nach unten schiebt; als Flex-Container ist er genau so hoch wie der Button. */
.df-tree-tool .mud-tooltip-root,
.df-tree-back .mud-tooltip-root {
    display: flex;
}

/* Wert = Zahl + Einheit (TreeValue). Die Einheit steht in einer eigenen schmalen Spalte, dadurch
   stehen die Zahlen untereinander und die Einheiten der Positionen in derselben Spalte wie die
   ihrer Messungen. Der Wert bricht nie in sich um. */
.df-tree-value {
    display: flex;
    align-items: baseline;
    flex: 0 0 auto;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.df-tree-unit {
    flex: 0 0 auto;
    margin-left: .3em;
    opacity: .62;
}

/* Option "Einheit in eigener Spalte": feste schmale Spalte, in der die Einheit rechtsbuendig steht.
   Dadurch enden alle Einheiten auf der Kante, die Zahlen davor stehen untereinander, und die
   Einheiten der Positionen stehen in derselben Spalte wie die ihrer Messungen. 2.2em reicht in
   Mulish noch fuer "psch" und "Stck". */
.df-tree-unitcol .df-tree-unit {
    min-width: 2.2em;
    margin-left: .4em;
    text-align: right;
}

/* Option "Schmal: Nummer als Kopfzeile" (unter 260px, je Zeile per Container-Query, tiefere Ebenen
   also frueher): Eine Position zeigt Nummer und Wert als Kopfzeile und den Namen darunter in voller
   Breite, statt den Namen in eine schmale Spalte neben der Nummer zu quetschen. Hierarchien (kurz,
   ohne Wert) und Messungen (ohne Nummer) sind nicht betroffen. */
@container (max-width: 259px) {
    .df-tree-narrow-header .df-tree-row-position .df-tree-label-text {
        display: contents;
    }

    .df-tree-narrow-header .df-tree-row-position .df-tree-number {
        order: 1;
    }

    .df-tree-narrow-header .df-tree-row-position .df-tree-label-end {
        order: 2;
    }

    .df-tree-narrow-header .df-tree-row-position .df-tree-name {
        order: 3;
        flex: 1 1 100%;
    }
}

/* ---- Anwender-Optionen zur Trennung der Zeilen (TreeLayoutSettings.Separator) ---- */

/* Trennlinien: punktierte Linie unter jeder Zeile; sie beginnt an der Einzugskante der Ebene und wird
   mit jeder Ebene kuerzer. Ohne runde Ecken, sonst laege die Linie unter einer gerundeten Flaeche. */
.df-tree-sep-lines .mud-treeview .mud-treeview-item-content {
    border-bottom: 1px dotted var(--mud-palette-divider);
    border-radius: 0;
}

/* Leitlinien: gestrichelte Senkrechte unter dem Pfeil des Elternknotens, entlang seiner Kinder. */
.df-tree-sep-guides .mud-treeview-group {
    position: relative;
    overflow: visible;
}

.df-tree-sep-guides .mud-treeview-group::before {
    content: "";
    position: absolute;
    left: 0;
    top: 3px;
    bottom: 3px;
    border-left: 1px dashed var(--mud-palette-divider);
    pointer-events: none;
}

/* Karten: jede Zeile umrandet. Hierarchien und Ordner durchgezogen mit Kopfzeilen-Tint, Elemente
   gestrichelt, die selektierte Zeile gestrichelt in Akzentgruen wie die aktive Kachel der Zeitleiste. */
.df-tree-sep-cards .mud-treeview .mud-treeview-item-content {
    border: 1px dashed var(--mud-palette-divider);
    border-radius: 6px;
    margin: 2px 0;
    padding: 2px 6px;
}

.df-tree-sep-cards .mud-treeview-item-content:has(.df-tree-row-hierarchy) {
    border-style: solid;
    background-color: var(--df-table-head-bg);
}

.df-tree-sep-cards .mud-treeview-item-content.mud-treeview-item-selected,
.df-tree-sep-cards .mud-treeview-item-content:has(.df-tree-row-selected) {
    border-style: dashed;
    border-color: var(--df-accent-green);
}

/* Gruppen: die Kinder eines Knotens stehen gemeinsam in einem gestrichelten Rahmen. */
.df-tree-sep-groups .mud-treeview-group {
    border: 1px dashed var(--mud-palette-divider);
    border-radius: 8px;
    padding: 2px;
    margin: 2px 0 4px 17px;
}

.df-tree-sep-groups .mud-treeview-item-content:has(.df-tree-row-hierarchy) {
    background-color: var(--df-table-head-bg);
}

/* Option "Auswahl gestrichelt": Akzentrahmen wie die aktive Kachel der Zeitleiste. */
.df-tree-sel-dashed .mud-treeview-item-content.mud-treeview-item-selected,
.df-tree-sel-dashed .mud-treeview-item-content:has(.df-tree-row-selected) {
    outline: 1px dashed var(--df-accent-green);
    outline-offset: -1px;
}

/* ---- Ebenen-Modus (TreeNavigationMode.Levels) ---- */

/* Kopfzeile ueber der Liste: Zurueck-Pfeil, Symbol und der Knoten der aktuellen Ebene. */
.df-tree-level-header {
    display: flex;
    align-items: flex-start;
    flex: 0 0 auto;
    padding: 2px 6px 4px;
    margin-bottom: 2px;
    border-bottom: 1px solid var(--mud-palette-divider);
    cursor: pointer;
    --df-tree-line: calc(var(--mud-typography-body1-size, 14px) * var(--mud-typography-body1-lineheight, 1.5));
}

.df-tree-back {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    height: var(--df-tree-line);
    margin-right: 5px;
}

/* Hinweis unter der Kopfzeile, wenn die geoeffnete Ebene keine Eintraege hat. */
.df-tree-empty {
    padding: 6px 10px;
    opacity: .62;
}

/* Kopfzeile als Auswahl: der geoeffnete Knoten ist selektiert, gleiche Optik wie eine selektierte Zeile
   (Option "Auswahl gestrichelt" gilt auch hier). */
.df-tree-level-header.df-tree-level-selected {
    color: var(--mud-palette-primary);
    background-color: var(--mud-palette-primary-hover);
}

.df-tree-sel-dashed .df-tree-level-header.df-tree-level-selected {
    outline: 1px dashed var(--df-accent-green);
    outline-offset: -1px;
}

/* Kopfzeile als Drop-Ziel (Messungsbaum: Verschieben in die aktuelle Ebene); waehrend des Ziehens vor
   der Auswahl-Optik. */
.df-tree-paper.df-tree-dragging .df-tree-level-header.df-tree-row-drop-target {
    outline: 1px dashed var(--mud-palette-primary);
    outline-offset: -1px;
    background-color: var(--mud-palette-primary-hover);
}

/* Wie bei den Zeilen: waehrend des Ziehens empfaengt nur die Kopfzeile selbst dragenter/dragleave. */
.df-tree-paper.df-tree-dragging .df-tree-level-header > * {
    pointer-events: none;
}

/* ---- Layout-Menue (TreeLayoutMenu) ---- */

/* Das Popover liegt im MudPopoverProvider, also ausserhalb von .df-tree-paper, und kaeme sonst in MudBlazors
   neutralem Surface-Grau mit 4px-Rundung. Hier bekommt es die Optik der DATAflor-Papers: gleiche Farbe,
   10px-Rundung und Schatten wie .paper-primary. Selektionsgruen wie beim Select-Popover. */
.mud-popover.df-tree-layout-popover {
    --mud-palette-primary: var(--df-accent-green);
    background-color: var(--df-paper-primary-bg);
    border-radius: 10px;
    box-shadow: var(--df-paper-shadow);
    overflow: hidden;
}

.df-tree-layout-popover .df-tree-layout-list {
    padding: 0;
    background-color: transparent;
}

.df-tree-layout-panel {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 6px 16px 12px;
    min-width: 280px;
}

/* Kopf: Titel links, Schliessen-Knopf rechts an der Kante, Trennlinie darunter. */
.df-tree-layout-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 4px 0 6px;
    margin-bottom: 2px;
    border-bottom: 1px solid var(--df-border-subtle);
}

.df-tree-layout-head .mud-icon-button {
    margin-right: -6px;
}

.df-tree-layout-caption {
    margin-top: 10px;
    opacity: .7;
}

/* Fusszeile mit "Auf Standard zuruecksetzen", durch eine Trennlinie von den Optionen abgesetzt. */
.df-tree-layout-foot {
    display: flex;
    justify-content: flex-end;
    margin-top: 10px;
    padding-top: 6px;
    border-top: 1px solid var(--df-border-subtle);
}

.df-tree-layout-panel .mud-radio-group {
    display: flex;
    flex-direction: column;
}

/* Scrollbereich um den Messungsbaum; seine Leerflaeche unter dem letzten Knoten nimmt Drops auf
   die Wurzelebene an. */
.df-tree-scroll {
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
}

/* Mehrfachauswahl: gleiche Optik wie MudBlazors mud-treeview-item-selected, das nur den
   Ankerknoten kennt. */
.df-tree-paper .mud-treeview-item-content:has(.df-tree-row-selected) {
    color: var(--mud-palette-primary);
    background-color: var(--mud-palette-primary-hover);
}

/* Drop-Ziel waehrend einer Drag-Operation (Ordner: hinein, Messung: daneben). Mit .df-tree-dragging,
   damit die Markierung die Option "Auswahl gestrichelt" (ebenfalls eine outline) ueberstimmt. */
.df-tree-paper.df-tree-dragging .mud-treeview-item-content:has(.df-tree-row-drop-target) {
    outline: 1px dashed var(--mud-palette-primary);
    outline-offset: -1px;
    background-color: var(--mud-palette-primary-hover);
}

/* Waehrend des Ziehens empfaengt nur die Zeile selbst dragenter/dragleave. Sonst feuern Pfeil,
   Symbol und Text beim Ueberfahren staendig leave/enter, und die Zielmarkierung flackert. */
.df-tree-paper.df-tree-dragging .df-tree-row > * {
    pointer-events: none;
}

/* MudSelect-Dropdown (Aufmass/LV) rendert im Popover ausserhalb .df-tree-paper.
   Selektionsgruen daher am Popover separat setzen (erbt --df-accent-green vom html). */
.df-tree-select-popover {
    --mud-palette-primary: var(--df-accent-green);
}

/* =========================================================================
   Deprecated: alte theme-suffigierte Klassen. Nur noch für Alt-Markup, das
   die Klassennamen hart codiert hat – neue/aktualisierte Apps bekommen von
   GetPaperTheme()/PageBackground() die theme-agnostischen Klassen oben.
   ========================================================================= */
.paper-primary-dark {
    background-color: #1B1915;
    box-shadow: rgba(0, 0, 0, 0.4) 0px 1px 3px 0px, rgba(0, 0, 0, 0.5) 0px 1px 2px -1px, rgba(255, 255, 255, 0.15) 0px 0px 0px 1px;
    padding: 10px;
    border-radius: 10px;
}

.paper-secondary-dark {
    background-color: #14120E;
    box-shadow: rgba(0, 0, 0, 0.4) 0px 1px 3px 0px, rgba(0, 0, 0, 0.5) 0px 1px 2px -1px, rgba(255, 255, 255, 0.15) 0px 0px 0px 1px;
    padding: 10px;
    border-radius: 10px;
}

.paper-primary-light {
    background-color: rgb(255, 255, 255);
    box-shadow: rgba(0, 0, 0, 0.4) 0px 1px 3px 0px, rgba(0, 0, 0, 0.5) 0px 1px 2px -1px, rgba(255, 255, 255, 0.15) 0px 0px 0px 1px;
    padding: 10px;
    border-radius: 10px;
}

.paper-secondary-light {
    background-color: rgb(255, 255, 255);
    box-shadow: rgba(0, 0, 0, 0.4) 0px 1px 3px 0px, rgba(0, 0, 0, 0.5) 0px 1px 2px -1px, rgba(255, 255, 255, 0.15) 0px 0px 0px 1px;
    padding: 10px;
    border-radius: 10px;
}

.df-tree-paper.paper-secondary-dark {
    --mud-palette-text-primary: #FBFBFB;
    --mud-palette-text-secondary: #FBFBFB;
    --mud-palette-primary: #DFFA33;
    color: #FBFBFB;
}

.df-tree-paper.paper-secondary-light {
    --mud-palette-primary: #AFCA05;
}

.df-tree-select-popover-dark {
    --mud-palette-primary: #DFFA33;
}

.df-tree-select-popover-light {
    --mud-palette-primary: #AFCA05;
}

.page-background-dark {
    background-color: #14120E;
    color: #ffffff;
}

.page-background-light {
    background-color: #EFEEEE;
    color: #000000;
}

/* DfLoadingIndicator: dataflor-Logo + hüpfende Punkte */
.df-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
}

.df-loading-logo {
    height: auto;
}

/* Ohne erzwungenes Theme (Dark-Parameter) rendert der Indikator beide Logos;
   das jeweils unpassende wird per Themeklasse ausgeblendet. */
html.df-theme-light .df-loading-logo-dark {
    display: none;
}

html:not(.df-theme-light) .df-loading-logo-light {
    display: none;
}

/* Dasselbe fuer beliebige Stellen, die das DATAflor-Logo (Icons/df-logo-dark.ico bzw. -light.ico) zeigen:
   beide Varianten rendern, die unpassende verschwindet per Themeklasse. !important, weil die Bilder
   ihr display oft als Inline-Style mitbringen (z.B. display:block fuer die Groesse) und der sonst
   gewinnen wuerde - dann waeren beide Logos sichtbar. */
html.df-theme-light .df-theme-logo-dark,
html:not(.df-theme-light) .df-theme-logo-light {
    display: none !important;
}

.df-loading-dots {
    display: flex;
    gap: 12px;
}

.df-loading-dots span {
    width: var(--df-loading-dot-size, 13px);
    height: var(--df-loading-dot-size, 13px);
    border-radius: 50%;
    background-color: var(--df-loading-dot-color, var(--df-accent-green, #AFCA05));
    animation: df-loading-bounce 1.4s infinite ease-in-out both;
}

.df-loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.df-loading-dots span:nth-child(2) { animation-delay: -0.16s; }

.df-loading-text {
    font-size: 14px;
}

@keyframes df-loading-bounce {
    0%, 80%, 100% { transform: translateY(0); opacity: 0.45; }
    40% { transform: translateY(-18px); opacity: 1; }
}

/* ── Referenzsystem-Picker (Dialogs/ReferenceSystemPickerDialog) ────────────
   Gruppen-Header als kompakte Bänder: schmaler Streifen mit eigenem
   Hintergrund und enger Versal-Typo, sticky beim Scrollen. Farben je Theme
   explizit — die Paper-Tokens geben im Light-Theme (beide weiß) keinen
   Kontrast her; html:not(.df-theme-light) deckt wie bei .df-tree-paper auch
   den Initialzustand vor dem Setzen der Themeklasse ab (Default = Dark). */
.df-refsys-list {
    padding-top: 0;
    padding-bottom: 0;
}

.df-refsys-list .mud-list-subheader {
    position: sticky;
    top: 0;
    z-index: 1;
    min-height: 0;
    margin: 0;
    padding: 5px 16px;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
    background-color: #ECEAE5;
}

html:not(.df-theme-light) .df-refsys-list .mud-list-subheader {
    background-color: #26231D;
}

/* =========================================================================
   Uebersichtsseiten (DfPageHeader, DfOverview*, DfChip, DfCtaIconButton)

   Nachbau der MyDATAflor-Projektuebersicht (cloud-web: ProjectsBoqsDashboard,
   ProjectsContent, ProjectTable, ProjectCard, df-ui/ChipItem). Alle Farben
   haengen an den Tokens oben, damit ein Themewechsel ohne Re-Render greift.
   ========================================================================= */

/* --- Seitenkopf -------------------------------------------------------- */
.df-page-header {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.df-page-header-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
}

.df-page-header-titles {
    min-width: 0;
}

.df-page-header-title {
    font-weight: 600;
}

.df-page-header-description {
    color: var(--df-text-muted);
}

.df-page-header-actions {
    flex: 0 0 auto;
}

.df-page-header-tabs {
    border-bottom: 1px solid var(--df-border-subtle);
}

/* Der gruene Plus-Knopf oben rechts. !important, weil MudIconButton seine
   Farben selbst als Klasse setzt; Color.Inherit allein reicht fuer den
   Hintergrund nicht. */
.df-cta-icon-button {
    background-color: var(--df-accent-green) !important;
    color: var(--df-on-accent) !important;
    border-radius: 10px !important;
    width: 44px;
    height: 44px;
}

.df-cta-icon-button:hover {
    filter: brightness(1.08);
}

/* --- Chips (Status und Tags) ------------------------------------------- */
.df-chip {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    max-width: 100%;
    padding: 2px 10px;
    border: 1.5px solid var(--df-chip-border-dark);
    border-radius: 999px;
    background-color: var(--df-chip-bg-dark);
    font-size: 0.8125rem;
    line-height: 1.25rem;
    transition: all 150ms ease-out;
}

html.df-theme-light .df-chip {
    border-color: var(--df-chip-border-light);
    background-color: var(--df-chip-bg-light);
}

.df-chip-tag {
    color: #000000;
}

.df-chip-status {
    color: #FFFFFF;
}

.df-chip-small {
    padding: 1px 8px;
    font-size: 0.75rem;
    line-height: 1.125rem;
}

.df-chip-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.df-chip-interactive {
    cursor: pointer;
}

.df-chip-interactive:hover {
    box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.35);
}

/* Entsaettigt den Chip, ohne die Farbe zu wechseln - fuer den Fall
   "ein Tag von mehreren" beim Ueberfahren der Zelle. */
.df-chip-muted {
    filter: saturate(0%) brightness(1.1);
}

.df-chip-delete {
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    opacity: 0.7;
}

.df-chip-delete:hover {
    opacity: 1;
}

/* --- Rahmen der Uebersicht -------------------------------------------- */
.df-overview {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

.df-overview-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

.df-overview-footer {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 8px 4px 4px;
}

.df-overview-count {
    margin-left: auto;
    font-size: 0.75rem;
    color: var(--df-text-muted);
}

/* --- Werkzeugzeile ---------------------------------------------------- */
.df-overview-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
    gap: 16px;
    margin-block: 16px;
}

.df-overview-toolbar-item {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

.df-overview-toolbar-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 16px;
}

.df-overview-search {
    max-width: 320px;
}

.df-overview-appearance {
    flex: 0 0 auto;
}

/* Der gewaehlte Eintrag steht auf dem Akzentgruen - ein helles Symbol darauf ist kaum
   zu erkennen, deshalb dunkel wie beim Plus-Knopf. MudBlazors SVG-Symbole sind
   fill: currentColor, die Textfarbe genuegt also. Die Klasse kommt von SelectedClass
   am MudToggleGroup und nicht aus MudBlazors internen Klassennamen. */
.df-overview-appearance-selected,
.df-overview-appearance-selected .mud-icon-root {
    color: var(--df-on-accent);
}

/* Abschnittsueberschrift im Filtermenue - dasselbe schmale Versal-Band wie
   die Gruppenkoepfe im Referenzsystem-Picker. */
.df-overview-menu-caption {
    padding: 6px 16px 2px;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--df-text-muted);
}

/* --- Tabelle ---------------------------------------------------------- */
.df-overview-table {
    display: flex;
    flex-direction: column;
    height: 100%;
    background-color: transparent;
}

/* Der scrollende Bereich holt seine Hoehe aus dem Flex-Layout statt aus einem
   height-Wert - nur so bleibt der mitlaufende Kopf oben, ohne dass die Seite
   eine Pixelhoehe kennen muss. */
.df-overview-table .mud-table-container {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
}

/* Festes Tabellenlayout: die Spaltenbreiten kommen aus dem Kopf (HeaderStyle), nicht aus
   dem Inhalt. Im automatischen Layout dehnt eine nowrap-Zelle die Spalte bis zur Textlaenge,
   die Tabelle wird breiter als ihr Rahmen und bekommt einen waagerechten Scroller - und
   text-overflow: ellipsis kann nie greifen, weil die Zelle nie zu schmal wird. Mit fixed
   bleibt die Tabelle 100% breit, Spalten ohne Breite teilen sich den Rest, lange Texte
   werden in den Zellen abgeschnitten wie in den Kacheln. */
.df-overview-table .mud-table-root {
    table-layout: fixed;
    width: 100%;
}

.df-overview-table .mud-table-head .mud-table-cell {
    background-color: var(--df-table-head-bg);
    font-size: 0.75rem;
    font-weight: 550;
    color: var(--df-text-muted);
    white-space: nowrap;
}

.df-overview-table .mud-table-body .mud-table-cell {
    height: 2.5rem;
    padding-block: 0;
    border-bottom: 1px solid var(--df-border-subtle);
}

.df-overview-table-compact .mud-table-body .mud-table-cell {
    height: 1.75rem;
}

.df-overview-table .mud-table-body .mud-table-row:hover {
    background-color: var(--df-row-hover-bg);
}

/* Gepinnte Spalten brauchen einen eigenen Hintergrund, sonst scrollt der
   Inhalt der Nachbarspalten sichtbar darunter durch. */
.df-overview-table .mud-table-cell.sticky-left,
.df-overview-table .mud-table-cell.sticky-right {
    background-color: var(--df-paper-primary-bg);
}

.df-overview-table .mud-table-head .mud-table-cell.sticky-left,
.df-overview-table .mud-table-head .mud-table-cell.sticky-right {
    background-color: var(--df-table-head-bg);
}

/* --- Zellinhalte ------------------------------------------------------ */
.df-cell-text {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.875rem;
}

.df-cell-placeholder {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.875rem;
    color: var(--df-text-muted);
}

.df-cell-interactive {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Leeranzeige nach einem Ladefehler: Hinweis plus Knopf zum Wiederholen, untereinander. */
.df-overview-loadfailed {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

.df-cell-tags {
    display: flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
}

.df-cell-tags-more {
    letter-spacing: 1.5px;
    line-height: 1rem;
    color: var(--df-text-muted);
}

/* Aufklapp-Pfeil einer Zeile ohne Unterzeilen: bloss angedeutet statt als Knopf. Ein
   deaktivierter Knopf saehe genauso aus, gaebe aber keine Mausereignisse mehr - und damit
   auch keinen Tooltip, der erklaert, warum nichts passiert. */
.df-hierarchy-empty {
    opacity: 0.3;
}

/* --- Unterzeilen einer aufgeklappten Tabellenzeile --------------------- */
/* Im Projekt-Tab die LVs des Projekts. Bewusst schlicht - die Zeilen liegen innerhalb
   der aufgeklappten Zeile des DataGrids, ein zweiter Tabellen-Look waere zu viel. */
.df-subrows {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 8px 8px 56px;
}

.df-subrow {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-size: 0.875rem;
}

.df-subrow-number {
    flex: 0 0 auto;
    min-width: 70px;
    color: var(--df-text-muted);
}

.df-subrows-empty {
    padding: 8px 8px 8px 56px;
    font-size: 0.875rem;
    color: var(--df-text-muted);
}

/* --- Kachelansicht ---------------------------------------------------- */
.df-overview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    align-content: start;
    gap: 16px;
    height: 100%;
    padding: 4px;
    overflow-y: auto;
}

.df-overview-grid-loading,
.df-overview-grid-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
}

/* Kein overflow: hidden an der Karte. Ein Grid-Element mit overflow ungleich visible hat
   die automatische Mindesthoehe 0 und darf dadurch kleiner werden als sein Inhalt - genau
   so verschwand der Text unter der Kante. Ohne die Angabe gilt min-height: auto, die
   Zeile kann also nie niedriger werden als Bild plus Rumpf plus Fusszeile. Das Bild
   beschneidet sich in .df-overview-card-media selbst. */
.df-overview-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--df-border-subtle);
    border-radius: 10px;
    background-color: var(--df-paper-secondary-bg);
    cursor: pointer;
    transition: box-shadow 150ms ease-out;
}

.df-overview-card:hover,
.df-overview-card:focus-visible {
    box-shadow: var(--df-paper-shadow);
}

/* Feste Hoehe statt aspect-ratio - und zwar bewusst:
   Mit aspect-ratio haengt die Hoehe an der Kachelbreite, die im Grid aus einer
   1fr-Spalte kommt. Beim Ausmessen der Zeilenhoehe steht diese Breite noch nicht fest,
   also geht der Medienbereich mit annaehernd 0 in die Rechnung ein. Die Zeile wird dann
   nur nach Rumpf und Fusszeile bemessen, das Bild malt seine volle Hoehe hinein und
   drueckt den Text unter die Kante, wo overflow ihn abschneidet.
   Eine feste Hoehe nimmt an der Zeilenberechnung teil und macht alle Kacheln exakt
   gleich hoch - unabhaengig von Kachelbreite und Bildformat. Ueber
   --df-overview-card-media-height laesst sie sich je Anwendung verstellen.
   Das img bleibt absolut positioniert, damit nicht seine Eigenhoehe durchschlaegt: ein
   echtes Foto ergaebe sonst eine andere Kachelhoehe als das Ersatzbild. */
.df-overview-card-media {
    position: relative;
    flex: 0 0 auto;
    height: var(--df-overview-card-media-height, 160px);
    overflow: hidden;
    border-radius: 9px 9px 0 0;
    background-color: var(--df-table-head-bg);
}

.df-overview-card-media img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Ersatzbild ohne eigenes Vorschaubild: beide Fassungen stehen im Markup, die
   Themeklasse am <html>-Element blendet die unpassende aus - dasselbe Vorgehen wie
   bei den beiden Logos im DfLoadingIndicator. */
html.df-theme-light .df-overview-card-fallback-dark {
    display: none;
}

html:not(.df-theme-light) .df-overview-card-fallback-light {
    display: none;
}

.df-overview-card-favorite {
    position: absolute;
    top: 4px;
    right: 4px;
}

/* flex: 0 0 auto an allen drei Bereichen: sonst duerfen sie schrumpfen, und sobald die
   Kachel etwas niedriger ist als ihr Inhalt, wird der Text weggedrueckt und von
   overflow: hidden abgeschnitten - genau das liess in der Projektuebersicht nur noch das
   Bild uebrig. */
.df-overview-card-body {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    gap: 4px;
    padding: 10px 12px 4px;
    min-width: 0;
}

.df-overview-card-titles {
    display: flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
}

.df-overview-card-number {
    flex: 0 0 auto;
    font-size: 0.75rem;
    color: var(--df-text-muted);
}

.df-overview-card-name {
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.df-overview-card-description,
.df-overview-card-client {
    font-size: 0.8125rem;
    color: var(--df-text-muted);
    overflow: hidden;
}

/* In der Kachel ist Platz nach unten, aber nicht in die Breite - die Beschreibung
   laeuft deshalb ueber zwei Zeilen statt einzeilig abgeschnitten zu werden. In der
   Tabellenzeile bleibt sie einzeilig (df-cell-text). */
.df-overview-card-description {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    min-height: 2.4em;
}

.df-overview-card-client {
    text-overflow: ellipsis;
    white-space: nowrap;
}

.df-overview-card-footer {
    margin-top: auto;
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 8px 8px 12px;
    min-height: 40px;
}

.df-overview-card-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    min-width: 0;
}

/* --- Tab-Leiste im Seitenkopf (DfPageTabs) ----------------------------- */
.df-page-tabs {
    display: flex;
    gap: 24px;
}

/* Chip hinter der Beschriftung: zeigt, worauf der Tab gerade eingeschraenkt ist. Der Chip
   erbt die Farbe des Tabs, ist also am aktiven Tab gruen und sonst gedaempft. */
.df-page-tab-filter {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    max-width: 180px;
    margin-left: 8px;
    padding: 1px 4px 1px 8px;
    border: 1px solid currentColor;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 500;
}

.df-page-tab-filter-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.df-page-tab-filter-clear {
    flex: 0 0 auto;
    padding: 0 2px;
    font-size: 0.9375rem;
    line-height: 1;
    opacity: 0.7;
}

.df-page-tab-filter-clear:hover {
    opacity: 1;
}

.df-page-tab {
    appearance: none;
    display: inline-flex;
    align-items: center;
    margin: 0;
    padding: 8px 2px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    font: inherit;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--df-text-muted);
    cursor: pointer;
    transition: color 150ms ease-out, border-color 150ms ease-out;
}

.df-page-tab:hover:not(:disabled) {
    color: var(--df-page-color);
}

.df-page-tab-active {
    color: var(--df-accent-green);
    border-bottom-color: var(--df-accent-green);
}

.df-page-tab:disabled {
    opacity: 0.5;
    cursor: default;
}

/* --- Anklickbare Zeilen und ihr Tooltip ------------------------------- */
/* Die Klasse setzt DfOverviewTable nur, wenn OnItemClick belegt ist - eine Tabelle
   ohne Klickziel soll keinen Zeigefinger zeigen. */
.df-overview-table-clickable .mud-table-body .mud-table-row {
    cursor: pointer;
}

.df-overview-table-clickable .mud-table-body .mud-table-row:hover .df-cell-name {
    color: var(--df-accent-green);
}

/* Der Tooltip-Rahmen von MudBlazor schrumpft um seinen Inhalt herum; als Block mit
   min-width 0 bleibt die Zelle massgeblich und der Name kann weiter mit
   Auslassungspunkten abgeschnitten werden. */
.df-cell-tooltip-root {
    display: block;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
}

.df-cell-tooltip {
    display: flex;
    flex-direction: column;
    gap: 3px;
    max-width: 340px;
    text-align: left;
}

.df-cell-tooltip-title {
    font-weight: 600;
}

/* Beschreibung im Tooltip: hier darf sie ueber mehrere Zeilen laufen, in der Zelle
   selbst passt nur eine. Nach vier Zeilen ist Schluss. */
.df-cell-tooltip-line {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    opacity: 0.85;
}

.df-cell-tooltip-hint {
    margin-top: 2px;
    padding-top: 4px;
    border-top: 1px solid rgba(255, 255, 255, 0.2);
    font-size: 0.75rem;
    color: var(--df-accent-green);
}

/* --- Seitenrahmen und Inhaltsbreite ------------------------------------ */
/* Nachbau der Abstaende aus MyDATAflor (df-ui: PagePaperScrollElement und
   PageContentContainer). Dort liegt das Panel in einer Box mit px 2 / pb 2 -
   also 16px seitlich und unten, oben buendig unter der AppBar. Hier weicht das
   ab: oben 4px, weil der 1px-Ring des Panels (--df-paper-shadow) ausserhalb der
   Box liegt und der Rahmen darum (overflow: hidden in MEASUREweb Index.razor und
   WebCad MainLayout) ihn bei 0 einfach abschneidet - das Panel sah oben
   abgeschnitten aus. Unten ebenfalls 4px statt 16px, weil der 20px hohe Footer
   seinen eigenen Luftraum mitbringt - mit ihm zusammen liegt das Panel dann etwa
   so weit vom unteren Fensterrand wie seitlich (16px). */
.df-page-outer {
    height: 100%;
    padding: 4px 16px;
    box-sizing: border-box;
}

/* Der Inhalt auf dem Panel steckt dort in einem MUI-Container: mittig, gedeckelt
   auf maxWidth lg = 1200px, mit grosszuegigem Innenabstand. Ueber
   --df-page-content-max laesst sich der Deckel je Anwendung verschieben oder mit
   none ganz aufheben. */
.df-page-content {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: var(--df-page-content-max, 1200px);
    height: 100%;
    min-height: 0;
    margin-inline: auto;
    padding: 24px;
    box-sizing: border-box;
}

/* =========================================================================
   Dock-Layout (DockHost / DockPanel)

   Die Geometrie (Position, Groesse, Sichtbarkeit der Trenner) setzt wwwroot/dockLayout.js als
   Inline-Styles und data-df-*-Attribute; hier stehen Optik und alles, was vom Zustand abhaengt
   (data-df-mode, data-df-side, data-df-inner-splitter). Blazor rendert auf diesen Elementen
   weder style noch data-df-*, damit sich beide Seiten nicht ueberschreiben.
   ========================================================================= */
.df-dock-host {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    box-sizing: border-box;
}

/* Vor dem ersten Layout aus dem JS staenden die Panels unpositioniert uebereinander. */
.df-dock-host:not([data-df-ready]) > .df-dock-panel,
.df-dock-host:not([data-df-ready]) > .df-dock-splitter,
.df-dock-host:not([data-df-ready]) > .df-dock-indicator {
    visibility: hidden;
}

.df-dock-center {
    position: absolute;
    overflow: hidden;
    box-sizing: border-box;
}

/* Waehrend einer Zieh- oder Groessenoperation: iframes (Karte, CAD-Editor) wuerden sonst die
   Pointer-Events schlucken; der Cursor gilt fuer den ganzen Host, weil der Zeiger auch ueber
   fremden Elementen steht. */
.df-dock-host[data-df-dragging] {
    user-select: none;
}

.df-dock-host[data-df-dragging] iframe {
    pointer-events: none;
}

.df-dock-host[data-df-cursor="grabbing"],
.df-dock-host[data-df-cursor="grabbing"] * { cursor: grabbing !important; }
.df-dock-host[data-df-cursor="col-resize"],
.df-dock-host[data-df-cursor="col-resize"] * { cursor: col-resize !important; }
.df-dock-host[data-df-cursor="row-resize"],
.df-dock-host[data-df-cursor="row-resize"] * { cursor: row-resize !important; }
.df-dock-host[data-df-cursor="ew-resize"],
.df-dock-host[data-df-cursor="ew-resize"] * { cursor: ew-resize !important; }
.df-dock-host[data-df-cursor="ns-resize"],
.df-dock-host[data-df-cursor="ns-resize"] * { cursor: ns-resize !important; }
.df-dock-host[data-df-cursor="nwse-resize"],
.df-dock-host[data-df-cursor="nwse-resize"] * { cursor: nwse-resize !important; }

/* Panel-Huelle: nur Lage; die Optik traegt der Rahmen darin. overflow bleibt sichtbar, weil der
   Trenner zum Nachbarn und die Griffe ausserhalb der Huelle liegen. */
.df-dock-panel {
    position: absolute;
    box-sizing: border-box;
    z-index: 1;
    transform-origin: 0 0;
    --df-dock-gap: 8px;
}

.df-dock-panel-frame {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    /* Kein Clipping am Rahmen: die Kopfzeile darf aufgeklappt ueber den Rand hinausragen. Den Inhalt
       beschneidet der Body, die Kopfzeile sich selbst. */
    overflow: visible;
    border-radius: 10px;
    background-color: var(--df-paper-secondary-bg);
    box-shadow: var(--df-paper-shadow);
    box-sizing: border-box;
}

.df-dock-panel[data-df-mode="floating"] > .df-dock-panel-frame,
.df-dock-panel[data-df-mode="mini"] > .df-dock-panel-frame,
.df-dock-panel[data-df-mode="pill"] > .df-dock-panel-frame {
    box-shadow: var(--df-paper-shadow), 0 12px 32px rgba(0, 0, 0, 0.45);
}

/* Kopfzeile = Griff zum Ziehen. touch-action none, damit ein Finger zieht statt zu scrollen. */
.df-dock-panel-header {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: 0 0 auto;
    height: 34px;
    position: relative;
    min-width: 0;
    overflow: hidden;
    border-radius: 10px 10px 0 0;
    padding: 0 6px 0 4px;
    background-color: var(--df-table-head-bg);
    border-bottom: 1px solid var(--df-border-subtle);
    cursor: grab;
    user-select: none;
    touch-action: none;
    box-sizing: border-box;
}

.df-dock-grip {
    flex: 0 0 auto;
    color: var(--df-text-muted);
}

.df-dock-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding-left: 2px;
    font-size: 0.875rem;
    font-weight: 600;
}

.df-dock-pill-text {
    display: none;
    white-space: nowrap;
    padding: 0 6px 0 4px;
    font-size: 0.8125rem;
    color: var(--df-text-muted);
}

/* Zu schmal fuer Titel und alle Knoepfe: die Kopfzeile schneidet rechts ab, ein Verlauf und ein Punkt
   zeigen es an (nicht in der Miniatur). Aufgeklappt (data-df-flyout, setzt das JS: Maus nach kurzer
   Zeit, Stift/Finger per Tipp) bekommt sie ihre volle Breite und ragt ueber den Panelrand hinaus -
   nach rechts, oder nach links, wenn rechts der Platz fehlt. Sie bleibt dabei im Fluss, der Inhalt
   darunter springt nicht. */
.df-dock-panel[data-df-clipped]:not([data-df-flyout]):not([data-df-mode="mini"]) .df-dock-panel-header::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 28px;
    pointer-events: none;
    background: linear-gradient(to right, transparent, var(--df-table-head-bg) 60%);
}

.df-dock-panel[data-df-clipped]:not([data-df-flyout]):not([data-df-mode="mini"]) .df-dock-panel-header::before {
    content: "";
    position: absolute;
    top: 50%;
    right: 8px;
    width: 8px;
    height: 8px;
    margin-top: -4px;
    border-radius: 50%;
    background-color: var(--df-accent-green);
    z-index: 1;
    pointer-events: none;
}

.df-dock-panel[data-df-flyout] .df-dock-panel-header {
    align-self: flex-start;
    width: max-content;
    min-width: 100%;
    overflow: visible;
    z-index: 4;
    border-radius: 10px;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.45);
}

.df-dock-panel[data-df-flyout="left"] .df-dock-panel-header {
    align-self: flex-end;
}

.df-dock-actions {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
}

.df-dock-actions .mud-button-root {
    width: 26px;
    height: 26px;
    padding: 3px;
}

.df-dock-actions .mud-icon-root {
    font-size: 1.15rem;
}

/* Aktionen je Zustand: alles aus, dann gezielt an. Auf der angedockten Seite fehlt der Knopf zu
   ebendieser Seite. */
.df-dock-act {
    display: none;
}

.df-dock-panel[data-df-mode="docked"] :is(.df-dock-act-mini, .df-dock-act-pill, .df-dock-act-float, .df-dock-act-left, .df-dock-act-right, .df-dock-act-top, .df-dock-act-bottom),
.df-dock-panel[data-df-mode="floating"] :is(.df-dock-act-mini, .df-dock-act-pill, .df-dock-act-left, .df-dock-act-right, .df-dock-act-top, .df-dock-act-bottom),
.df-dock-panel[data-df-mode="pill"] .df-dock-act-restore {
    display: inline-flex;
}

.df-dock-panel[data-df-mode="docked"][data-df-side="left"] .df-dock-act-left,
.df-dock-panel[data-df-mode="docked"][data-df-side="right"] .df-dock-act-right,
.df-dock-panel[data-df-mode="docked"][data-df-side="top"] .df-dock-act-top,
.df-dock-panel[data-df-mode="docked"][data-df-side="bottom"] .df-dock-act-bottom {
    display: none;
}

.df-dock-panel-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
}

.df-dock-panel-body {
    border-radius: 0 0 10px 10px;
}

.df-dock-panel-body > * {
    flex: 1 1 auto;
    min-height: 0;
}

/* Die Baeume bringen ihr eigenes Paper mit; im Panel gibt der Rahmen schon Hintergrund und Schatten. */
.df-dock-panel-body > .paper-primary,
.df-dock-panel-body > .paper-secondary {
    box-shadow: none;
    border-radius: 0;
}

/* Miniatur: dasselbe DOM, per Transform verkleinert. Bedienbar ist nur die Huelle (ziehen; ein
   Tipp oeffnet), der Inhalt nimmt keine Eingaben an. */
.df-dock-panel[data-df-mode="mini"] {
    cursor: grab;
}

.df-dock-panel[data-df-mode="mini"] > .df-dock-panel-frame {
    pointer-events: none;
}

/* Eigene Miniatur (DockPanel.MiniContent): statt des skalierten Panels nur dieser Inhalt in
   natuerlicher Groesse, ohne Kopfzeile; das JS setzt dafuer keinen Transform und misst die Groesse
   wie bei der Pille. */
.df-dock-mini {
    display: none;
}

.df-dock-panel--custom-mini[data-df-mode="mini"] {
    width: auto;
    height: auto;
}

.df-dock-panel--custom-mini[data-df-mode="mini"] > .df-dock-panel-frame {
    height: auto;
}

.df-dock-panel--custom-mini[data-df-mode="mini"] .df-dock-panel-header,
.df-dock-panel--custom-mini[data-df-mode="mini"] .df-dock-panel-body {
    display: none;
}

.df-dock-panel--custom-mini[data-df-mode="mini"] .df-dock-mini {
    border-radius: 10px;
    overflow: hidden;
    display: block;
}

/* Pille: nur die Kopfzeile mit Titel und Kontexttext, Breite nach Inhalt. */
.df-dock-panel[data-df-mode="pill"] {
    width: auto;
    height: auto;
}

.df-dock-panel[data-df-mode="pill"] > .df-dock-panel-frame {
    height: auto;
    border-radius: 17px;
}

.df-dock-panel[data-df-mode="pill"] .df-dock-panel-header {
    border-radius: 17px;
    border-bottom: 0;
    background-color: var(--df-paper-secondary-bg);
    padding-right: 4px;
}

.df-dock-panel[data-df-mode="pill"] .df-dock-title {
    flex: 0 0 auto;
    overflow: visible;
}

.df-dock-panel[data-df-mode="pill"] .df-dock-pill-text {
    display: inline;
}

.df-dock-panel[data-df-mode="pill"] .df-dock-panel-body,
.df-dock-panel[data-df-mode="pill"] .df-dock-resize,
.df-dock-panel[data-df-mode="pill"] .df-dock-inner-splitter {
    display: none;
}

/* Groessenaenderung schwebender Panels: rechte und untere Kante sowie die Ecke. */
.df-dock-resize {
    position: absolute;
    display: none;
    z-index: 2;
    touch-action: none;
}

.df-dock-panel[data-df-mode="floating"] > .df-dock-resize {
    display: block;
}

.df-dock-resize[data-df-resize="e"] {
    top: 0;
    right: -4px;
    width: 8px;
    height: 100%;
    cursor: ew-resize;
}

.df-dock-resize[data-df-resize="s"] {
    left: 0;
    bottom: -4px;
    width: 100%;
    height: 8px;
    cursor: ns-resize;
}

.df-dock-resize[data-df-resize="se"] {
    right: -4px;
    bottom: -4px;
    width: 16px;
    height: 16px;
    cursor: nwse-resize;
}

/* Trenner zwischen zwei angedockten Panels derselben Seite: liegt im Spalt hinter dem Panel und
   traegt den Knopf zum Wechsel unter-/nebeneinander. Die Richtung setzt das JS. */
.df-dock-inner-splitter {
    position: absolute;
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 3;
    touch-action: none;
}

.df-dock-inner-splitter::before {
    content: "";
    position: absolute;
    border-radius: 2px;
    background-color: transparent;
    transition: background-color 0.15s;
}

.df-dock-panel[data-df-inner-splitter="vertical"] > .df-dock-inner-splitter {
    display: flex;
    left: 0;
    right: 0;
    top: 100%;
    height: var(--df-dock-gap);
    cursor: row-resize;
}

.df-dock-panel[data-df-inner-splitter="vertical"] > .df-dock-inner-splitter::before {
    left: 12px;
    right: 12px;
    top: calc(50% - 1px);
    height: 2px;
}

.df-dock-panel[data-df-inner-splitter="horizontal"] > .df-dock-inner-splitter {
    display: flex;
    top: 0;
    bottom: 0;
    left: 100%;
    width: var(--df-dock-gap);
    cursor: col-resize;
}

.df-dock-panel[data-df-inner-splitter="horizontal"] > .df-dock-inner-splitter::before {
    top: 12px;
    bottom: 12px;
    left: calc(50% - 1px);
    width: 2px;
}

.df-dock-inner-splitter:hover::before {
    background-color: var(--df-accent-green);
}

.df-dock-inner-splitter .mud-button-root {
    width: 20px;
    height: 20px;
    padding: 1px;
    border-radius: 4px;
    background-color: var(--df-paper-secondary-bg);
    box-shadow: var(--df-paper-shadow);
}

.df-dock-inner-splitter .mud-icon-root {
    font-size: 0.95rem;
}

/* Trenner zwischen Seitenband und Mitte (Breite bzw. Hoehe des Bands). */
.df-dock-splitter {
    position: absolute;
    display: none;
    z-index: 3;
    touch-action: none;
}

.df-dock-splitter[data-df-orientation="vertical"] {
    cursor: col-resize;
}

.df-dock-splitter[data-df-orientation="horizontal"] {
    cursor: row-resize;
}

.df-dock-splitter::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    border-radius: 2px;
    background-color: transparent;
    transition: background-color 0.15s;
}

.df-dock-splitter[data-df-orientation="vertical"]::after {
    width: 2px;
}

.df-dock-splitter[data-df-orientation="horizontal"]::after {
    height: 2px;
}

.df-dock-splitter:hover::after {
    background-color: var(--df-accent-green);
}

/* Klappknopf in der Mitte jedes Bandtrenners: klappt das ganze Band zu einem Streifen ein und wieder
   auf. Welches der beiden Symbole zu sehen ist, entscheidet data-df-collapsed am Trenner (setzt das JS). */
.df-dock-splitter > .mud-tooltip-root {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 1; /* ueber der Linie (::after kommt im DOM nach dem Knopf und laege sonst obenauf) */
}

.df-dock-splitter .df-dock-band-toggle {
    width: 20px;
    height: 20px;
    padding: 1px;
    border-radius: 4px;
    background-color: var(--df-paper-secondary-bg);
    box-shadow: var(--df-paper-shadow);
    color: var(--df-text-muted);
}

.df-dock-splitter .df-dock-band-toggle .mud-icon-root {
    font-size: 1rem;
}

.df-dock-band-icon-expand,
.df-dock-splitter[data-df-collapsed] .df-dock-band-icon-collapse {
    display: none;
}

.df-dock-splitter[data-df-collapsed] .df-dock-band-icon-expand {
    display: inline-block;
}

/* Eingeklapptes Band: der Trenner ist der Streifen am Rand, ohne Linie, nicht ziehbar. */
.df-dock-splitter[data-df-collapsed] {
    cursor: default;
    border-radius: 6px;
    background-color: var(--df-table-head-bg);
}

.df-dock-splitter[data-df-collapsed]::after {
    display: none;
}

.df-dock-panel[data-df-collapsed] {
    display: none;
}

/* Ablagehinweis beim Ziehen: Randzone einer leeren Seite oder die Haelfte eines angedockten Panels. */
.df-dock-indicator {
    position: absolute;
    display: none;
    z-index: 50;
    pointer-events: none;
    box-sizing: border-box;
    border: 2px dashed var(--df-accent-green);
    border-radius: 10px;
    background-color: color-mix(in srgb, var(--df-accent-green) 18%, transparent);
}

.df-dock-indicator[data-df-visible] {
    display: block;
}

