/* MudBlazor Component Workarounds */
/* Common fixes for known MudBlazor issues that can be reused project-wide */

/* Kurzueberblick-Tour: Das Profil-Menue wird im Konto-Schritt programmatisch aufgeklappt.
   Damit es trotz des Tour-Spotlights (.tutorial-hole/.tutorial-fullshade liegen bei z-index
   2001) sichtbar bleibt, wird sein Popover knapp darueber gehoben. Die Sprechblase selbst
   liegt bei 2002 und im DOM nach dem Popover, bleibt also dank gleichem z-index obenauf.
   Diese Klasse wird nur waehrend des Tour-Schritts gesetzt (PopoverClass), beeinflusst die
   normale Menue-Nutzung also nicht. */
.tour-account-menu-popover {
    z-index: 2002 !important;
}

/* Fix: MudTextField double-click focus issue in nested containers (MudItem, MudPaper) */
/* Problem: Input elements inside nested MudBlazor containers require double-click to focus */
/* Solution: Ensure input elements immediately receive pointer events */
.mud-input-control .mud-input-slot textarea,
.mud-input-control .mud-input-slot input {
    pointer-events: auto !important;
}

/* Isolate input controls from parent container click handlers to prevent interference */
.mud-paper .mud-input-control,
.mud-grid-item .mud-input-control {
    isolation: isolate;
}

/* Speed up MudNavGroup expand/collapse animation (default 300ms is too slow) */
.mud-collapse-container {
    transition: grid-template-rows 75ms ease-out !important;
}

/* Stimmen-Beschreibung nur im offenen Dropdown anzeigen, nicht im geschlossenen Input-Feld */
.mud-input-slot .voice-description {
    display: none;
}

/* Modell-Auswahl Dropdown: maximale Breite begrenzen, damit lange Beschreibungen umbrechen */
.model-selector-popover,
.model-selector-list {
    max-width: 500px;
}

/* Höhe auf den Viewport begrenzen und scrollen, sobald mehr Modelle freigeschaltet sind als in
   die Fensterhöhe passen — sonst läuft die Liste unten aus dem Bild heraus und die letzten
   Provider-Gruppen (Anthropic, xAI) sind unerreichbar. Die Gruppen-Überschriften scrollen mit,
   weil die Begrenzung auf der Liste sitzt und nicht auf einzelnen Einträgen.
   Wichtig: `.mud-menu-list` mit in den Selektor und `!important` — sonst gewinnen MudBlazors
   eigene Höhen-/Overflow-Regeln auf der Liste und die Begrenzung greift gar nicht (gleiches
   Muster wie beim AppBar-Projekt-Menü weiter unten). */
.mud-menu-list.model-selector-list {
    max-height: min(70dvh, 620px) !important;
    overflow-y: auto !important;
    overscroll-behavior: contain;
}

/* Das Popover darf die Liste nicht auf ihre Vollhöhe aufziehen, sonst scrollt nichts. */
.model-selector-popover {
    max-height: min(70dvh, 620px) !important;
    overflow: hidden !important;
}

.model-selector-list .mud-list-item {
    white-space: normal;
    word-break: break-word;
}

/* MudTextField in vertikalem Flex-Container vertikal ausdehnen (z.B. CalcAssist Vorlagen).
   Workaround statt CSS-Isolation (::deep): MudBlazor reicht das b-Scope-Attribut nicht
   zuverlaessig an seine internen DOM-Elemente weiter, daher global.
   Greift nur, wenn explizit Class="stretch-textfield" am MudTextField gesetzt ist. */
.stretch-textfield {
    flex: 1 1 0 !important;
    min-height: 0 !important;
    margin-top: 4px !important;
}

.stretch-textfield .mud-input-control-input-container {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: 100% !important;
}

.stretch-textfield .mud-input,
.stretch-textfield .mud-input.mud-input-outlined {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    height: 100% !important;
    align-items: stretch !important;
}

.stretch-textfield textarea.mud-input-slot,
.stretch-textfield textarea.mud-input-slot.mud-input-root-multiline {
    height: auto !important;
    min-height: 0 !important;
    resize: none !important;
    overflow-y: auto !important;
}

/* HelperText (z.B. bei Auswahlhinweis) soll nicht mitschrumpfen */
.stretch-textfield .mud-input-helper-text {
    flex-shrink: 0;
}

/* Calcassist-Tabellen (Preisspiegel Phase 4, Angebotserstellung Phase 5):
   kompakte Zell-Paddings. Global statt scoped, weil das Scope-Attribut auf
   demselben Element wie die Tabellen-Klasse sitzt und ein Vorfahren-Selektor
   (::deep .x th) deshalb nicht greift. MudBlazors Default fuer dense
   MudSimpleTable ist 6px 16px; wir reduzieren auf 2px vertikal / 10px horizontal. */
.preisspiegel-table th,
.preisspiegel-table td,
.angebotserstellung-table th,
.angebotserstellung-table td {
    padding: 2px 10px !important;
}

/* Bauteil-Trennzeile (Komponente BauteilTrennzeile): die Zelle spannt ueber alle Spalten und
   bringt kein eigenes Padding mit — Flaeche, Rahmen und Innenabstand liefert die Komponente,
   damit die Trennung in allen Phasen gleich aussieht. Ohne !important gewaenne die Regel oben. */
.preisspiegel-table td.bauteil-trenner-zelle,
.angebotserstellung-table td.bauteil-trenner-zelle {
    padding: 0 !important;
}

/* Schmale graue Trennspalte (10px Breite) ohne Padding lassen.
   Die Inline-Styles setzen padding:0 — hier mit !important nachziehen,
   damit unsere obige !important-Regel nicht ueberschreibt. */
.preisspiegel-table th[style*="padding:0"],
.preisspiegel-table td[style*="padding:0"],
.angebotserstellung-table th[style*="padding:0"],
.angebotserstellung-table td[style*="padding:0"] {
    padding: 0 !important;
}

/* Phase-4-Preisspiegel: Seit die ganze Phase scrollt (PreisspiegelPhase.razor.css), wandern die
   Zeilen unter der Kopfzeile durch. Ohne eigenen Hintergrund ist eine Kopfzelle durchsichtig und
   die Zeilen schienen durch — das fiel vorher nicht auf, weil der .mud-table-container scrollte
   und die Zeilen erst gar nicht hinter den Kopf liefen. Nur die erste Kopfzeile: die zweite
   (EP/GP) ist bewusst nicht sticky und scrollt mit dem Inhalt weg.
   Bewusst OHNE !important, damit die inline gesetzten Sonderhintergruende (Durchschnitts-Block in
   Grau, Zuschlag-Spalte in Blau) weiter gewinnen. */
.preisspiegel-table thead tr:first-child > th {
    background: var(--mud-palette-surface);
    position: sticky;
    top: 0;
}

/* Feste Spaltenbreiten statt table-layout: auto. Die Zeilenvirtualisierung tauscht beim Scrollen
   Zeilen gegen Platzhalter aus — mit auto misst der Browser die Spalten immer nur am gerade
   gerenderten Ausschnitt, und die Breiten sprangen bei jedem Nachladen hin und her. Die Breiten
   selbst stehen in der <colgroup> der Tabelle (PreisspiegelPhase.razor), weil sie von der Anzahl
   der Bieter- und Preisspalten abhaengen. width: max-content laesst die Tabelle ueber den
   Scroll-Container hinauswachsen, sodass sie waagerecht scrollt — Voraussetzung dafuer, dass die
   eingefrorene Pos.-Spalte per position: sticky links kleben kann. */
.preisspiegel-table table {
    table-layout: fixed;
    width: max-content;
}

/* Bei fester Spaltenbreite liefe eine ungewoehnlich lange Ordnungszahl sonst lautlos unter die
   daneben liegende Kurztext-Zelle (die deckt, weil sie selbst positioniert ist). Mit Ellipse ist
   das Abschneiden wenigstens sichtbar. */
.preisspiegel-table .preisspiegel-col-pos {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Phase-5-Angebotstabelle: NUR Pos.- und Kurztext-Spalte bleiben beim horizontalen Scrollen
   links fixiert; alle uebrigen Spalten (inkl. Menge/Einh.) scrollen normal mit.
   table-layout: fixed + width: max-content geben den Spalten feste, vom Inhalt unabhaengige
   Breiten — dadurch sitzt Kurztext exakt auf 220px hinter der 90px-Pos.-Spalte (verlaesslicher
   left-Offset, keine Ueberlappung/"Margin") und die Tabelle ist breiter als ihr Scroll-Container
   (.mud-table-container), sodass dieser horizontal scrollt. Dieser Container-Scroll ist
   Voraussetzung dafuer, dass position: sticky greift — deshalb darf am MudTable-Root KEIN
   min-width gesetzt sein, das den Container so breit wie die Tabelle macht. */
.angebotserstellung-table table {
    table-layout: fixed;
    width: max-content;
}

.angebotserstellung-table .col-frozen {
    position: sticky;
    background: var(--mud-palette-surface);
    z-index: 2; /* Body-Zellen der eingefrorenen Spalten ueber den horizontal scrollenden Zellen */
}

/* WICHTIG: MudBlazor setzt fuer den FixedHeader auf JEDE thead-th per
   `.mud-simple-table.mud-table-sticky-header * table thead * th` ein `position: sticky; top: 0;
   z-index: 1`. Die frozen-th kleben dadurch zwar korrekt bei left:0/90px, werden aber von den
   im DOM spaeter stehenden, scrollenden Header-Zellen (gleicher z-index 1) UEBERDECKT — es sah
   aus, als wuerde der Header nicht mitfixiert. Loesung: z-index der Header-Zellen ueber MudBlazors
   Wert heben. Da MudBlazors Selektor gleich/hoeher spezifisch ist, ist hier `!important` noetig. */
.angebotserstellung-table thead th {
    z-index: 3 !important; /* gesamte Header-Zeile ueber den Body-Zellen (auch beim vertikalen Scrollen) */
    /* Ohne eigenen Hintergrund ist die Kopfzelle durchsichtig: bisher fiel das nicht auf, weil der
       .mud-table-container scrollte und die Zeilen erst gar nicht hinter den Kopf liefen. Seit die
       ganze Phase scrollt, wandern die Zeilen unter der Kopfzeile durch und schienen im oberen,
       textfreien Teil der Zelle (vertical-align: bottom) durch. `background` deckt die gesamte
       Zellflaeche ab, nicht nur die Textzeile. */
    background: var(--mud-palette-surface) !important;
    /* Der Kopf klebt am oberen Rand der scrollenden Phase. MudBlazor setzt das fuer FixedHeader
       ohnehin; hier verankert, damit die Kopfzeile nicht an einem MudBlazor-Selektor haengt. */
    position: sticky;
    top: 0;
}

/* Kreuzungszellen: Header-th der eingefrorenen Spalten muessen ueber ALLEM liegen — ueber den
   horizontal scrollenden Header-Zellen UND ueber den vertikal scrollenden frozen-Body-Zellen. */
.angebotserstellung-table thead .col-frozen {
    z-index: 4 !important;
}

/* Breite der Pos.-Spalte bewusst hier (nicht inline am th): der left-Offset der Kurztext-Spalte
   MUSS demselben Wert folgen, sonst ueberlappen die beiden eingefrorenen Spalten. 125px fasst die
   laengste real vorkommende GAEB-Ordnungszahl ("02.00.00.00.01", 14 Zeichen) samt der 2x10px
   Zell-Paddings; mit den vorherigen 90px wurden schon 12-stellige Nummern ("02.01.3.0004")
   abgeschnitten — table-layout: fixed laesst die Nummer ueberlaufen und die darueberliegende
   sticky Kurztext-Zelle verdeckte den Rest ohne jeden Hinweis.
   ellipsis + title-Attribut am td: laufen Nummern doch einmal ueber, ist das sichtbar ("…")
   und der volle Wert per Tooltip lesbar, statt lautlos zu verschwinden. */
.angebotserstellung-table .col-pos {
    left: 0;
    width: 125px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.angebotserstellung-table .col-kurztext { left: 125px; }

/* Benachrichtigungs-Dropdown (Glocke): bei vielen/langen Eintraegen scrollbar machen, statt
   unten aus dem Viewport zu laufen und abgeschnitten zu werden. Die PopoverClass
   `notification-menu-popover` war referenziert, aber nie definiert — ohne max-height/overflow
   gibt es keinen Scroll-Container. Global statt scoped, weil das Popover in einem Portal am
   Wurzelknoten (MudPopoverProvider) ausserhalb der Komponente gerendert wird. */
.notification-menu-popover {
    overflow: hidden !important;
}

/* Panel als Flex-Spalte mit Viewport-Hoehe als Deckel: Hinweis + Kopfleiste bleiben fixiert,
   nur die Liste (.notification-scroll) scrollt. */
.notification-panel {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 96px);
}

.notification-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
}

/* Dezente Trennlinie zwischen den einzelnen Benachrichtigungskarten — die letzte Karte
   braucht keine, damit unten kein doppelter Strich zum Panel-Rand entsteht. */
.notification-scroll .notification-item {
    border-bottom: 1px solid var(--mud-palette-divider);
}

.notification-scroll .notification-item:last-child {
    border-bottom: none;
}

/* Zuschlags-ExpansionPanel (Calcassist Phase 5): Header ohne Padding und auf
   Hoehe der Medium-Buttons (36px) gestreckt, damit er buendig mit den
   Aktions-Buttons rechts daneben in einer Zeile sitzt. Global statt scoped,
   weil das b-Scope-Attribut auf demselben Element wie .zuschlagspanel sitzt
   und ::deep deshalb nicht greift (analog zur .preisspiegel-table Loesung
   weiter oben). */
.zuschlagspanel .mud-expand-panel-header {
    padding: 0 !important;
    min-height: 36px !important;
}

/* Toolbar-Hoehe ab Tablet/Desktop (>=600px) auf 48px reduzieren. MudBlazor 8.7 setzt in seinem
   eigenen Bundle dieselbe Regel mit 64px (gleiche Spezifitaet) — daher !important auf der
   Custom-Property, damit unser Wert unabhaengig von der Ladereihenfolge gewinnt. */
:where([data-aura-view="desktop"]) .mud-toolbar {
    --mud-internal-toolbar-height: 48px !important;
}

/* Projekt-Auswahl (MudSelect im Nav-Drawer, Variant.Outlined): MudSelect ankert das Popover
   an einem Platzhalter INNERHALB des Input-Paddings, nicht an der aeusseren Feldkante. Dadurch
   sitzt das Popover 16px zu weit rechts (gemessen: Feld left=8px, Popover left=24px, delta=16px)
   — obwohl RelativeWidth die Breite bereits korrekt an die Feldbreite koppelt. Wir schieben die
   Position per negativem margin-left um genau diese 16px zurueck, sodass das Popover buendig unter
   dem Feld sitzt. margin-left greift bei position:absolute auf die per Inline-Style gesetzte
   left-Position und laesst die Animations-transform unberuehrt. Global statt scoped, weil das
   Popover im Portal am Wurzelknoten (MudPopoverProvider) ausserhalb der Komponente gerendert wird. */
.project-selector-popover {
    margin-left: -16px;
}

/* Projekt-Auswahl (MudMenu in der AppBar, Zwei-Spalten-Layout): MudMenu setzt — anders als
   MudSelect (dort MaxHeight-Default 300px) — KEINE Hoehenbegrenzung auf das Popover. Die Liste
   erbt per MudBlazor-Default `.mud-list{max-height:inherit;overflow-y:auto}` die Popover-Hoehe;
   fehlt sie, loest `inherit` zu „unbegrenzt" auf und die Liste laeuft unten aus dem Viewport,
   ohne scrollbar zu sein. Wir setzen eine feste (responsive) Hoehe direkt auf die Liste.
   WICHTIG: Selektor MUSS `.mud-menu-list` mit einschliessen — sonst hat unsere Regel dieselbe
   Spezifitaet wie MudBlazors `.mud-list{max-height:inherit}`, und da `MudBlazor.min.css` NACH
   dieser Datei geladen wird, gewaenne dort `inherit`. Global statt scoped, weil das Popover im
   Portal am Wurzelknoten (MudPopoverProvider) ausserhalb der Komponente gerendert wird. */
.mud-menu-list.appbar-project-menu-list {
    width: min(360px, calc(100vw - 24px)) !important;
    max-height: 70vh !important;
    overflow-y: auto !important;
}

/* Projekt-Auswahl (MudMenu in der AppBar): Ohne Breitenbegrenzung waechst das Popover auf die
   Breite des laengsten Projektnamens (z.B. „73223_Grossenrich_2025-11-21_114643") und ragt auf
   Mobile ueber den rechten Viewport-Rand hinaus — die rechts sitzenden Favoriten-Sterne werden
   abgeschnitten. Wir kappen die Breite (Desktop max. 360px, Mobile Viewport minus Rand). Zusammen
   mit `min-width:0` am Namens-Span (im Markup) greift dann `text-truncate`, sodass lange Namen
   kuerzen statt die Zeile aufzublaehen, und der Stern bleibt sichtbar. Global, weil das Popover im
   Portal am Wurzelknoten ausserhalb der Komponente gerendert wird. */
.appbar-project-menu-popover {
    max-width: min(360px, calc(100vw - 24px)) !important;
}

/* MudFileUpload mit sichtbarem Activator (Import-Buttons „JSON Import"/„XML Import" in der
   Lieferantenverwaltung): Der Datei-Input liegt per InputClass absolut und transparent UEBER dem
   Activator-Button (`absolute mud-width-full mud-height-full z-10`) und ist damit das Hover-Ziel.
   Browser rendern fuer `input[type=file]` den normalen Pfeil — MudBlazors `cursor:pointer` an
   `.mud-button-root` darunter kommt deshalb nie zum Tragen. Der Parameter `InputStyle` reicht dafuer
   nicht aus: er landet in MudBlazor 8.x nicht auf dem Input-Element selbst (sonst haette der
   Inline-Style jede Stylesheet-Regel geschlagen).
   !important ist Pflicht — diese Datei wird in App.razor VOR `MudBlazor.min.css` eingebunden, bei
   gleicher Spezifitaet gewaenne sonst MudBlazor. Regel bewusst auf Wrapper, Label, Button UND Input,
   damit sie unabhaengig davon greift, welches Element am Ende oben liegt. */
.aura-file-upload,
.aura-file-upload label,
.aura-file-upload .mud-button-root,
.aura-file-upload input[type="file"] {
    cursor: pointer !important;
}

/* Laeuft ein Import, ist das MudFileUpload deaktiviert (Input traegt `disabled`) — dann der normale
   Pfeil statt der Hand, damit die Optik zum gesperrten Zustand passt. */
.aura-file-upload input[type="file"]:disabled,
.aura-file-upload:has(input[type="file"]:disabled),
.aura-file-upload:has(input[type="file"]:disabled) label,
.aura-file-upload:has(input[type="file"]:disabled) .mud-button-root {
    cursor: default !important;
}

/* Info-Tooltips der Stammdaten-Dialoge (AURA-145): maximal 200px breit.
   MudTooltip hat keinen MaxWidth-Parameter; `Class` landet in MudBlazor 8.x auf dem Tooltip selbst
   (fuer den Wrapper gibt es RootClass), die Regel greift also direkt auf `.mud-tooltip`.
   Beide Selektoren bewusst: der zweite ist die Rueckfallebene, falls die Klasse in einer kuenftigen
   MudBlazor-Version wieder am Wrapper landet.
   `text-align: left` ueberschreibt das zentrierte Standard-Layout — bei begrenzter Breite bricht der
   Text in mehrere Zeilen, zentriert waeren die Zeilenanfaenge versetzt und der Text schlecht lesbar.
   !important ist Pflicht: diese Datei wird VOR `MudBlazor.min.css` eingebunden (siehe oben). */
.aura-tooltip-narrow,
.aura-tooltip-narrow .mud-tooltip {
    max-width: 200px !important;
    text-align: left !important;
}

/* Upload-Zeile im Anhang-Menue des Chats. MudBlazor haengt den Menue-Inhalt in den
   Popover-Container am Ende des Body um; komponentenskopierte CSS (::deep) erreicht ihn dort
   nicht, deshalb stehen die Regeln global. Die Zeile ist ein MudFileUpload-Label (Safari braucht
   die Label-Aktivierung) und soll aussehen wie ein MudMenuItem.
   !important ist Pflicht: diese Datei wird VOR MudBlazor.min.css eingebunden. */
.attach-menu-upload-wrapper {
    display: block !important;
    width: 100% !important;
}

.attach-menu-upload-wrapper .mud-input-control {
    margin: 0 !important;
    padding: 0 !important;
}

.attach-menu-upload-wrapper label {
    display: block !important;
    width: 100% !important;
    margin: 0 !important;
}

/* Aktionen-Menü der Benutzerverwaltung: Einträge vertikal untereinander.
   Ursache: Jeder MudMenuItem dort steckt in einem MudTooltip (Hinweistext bei gesperrten
   Aktionen). MudBlazor rendert dessen Wrapper als `.mud-tooltip-root.mud-tooltip-inline`
   mit `display: inline-block` — die umhüllten Einträge flossen dadurch nebeneinander
   statt zu stapeln. MudBlazor selbst kennt den Fall (`:has(> .mud-width-full)` schaltet auf
   block), das hätte aber eine Zusatzklasse an jedem einzelnen Eintrag gebraucht.
   Die Regel greift über die PopoverClass nur in diesem Menü. */
.user-actions-menu .mud-tooltip-root.mud-tooltip-inline {
    display: block;
    width: 100%;
/* Projektsuche im Projekt-Dropdown (AppBar-Menue und MudSelect): Das Suchfeld soll wie eine normale
   Dropdown-Zeile aussehen und mit „Neues Projekt erstellen" fluchten. MudBlazor setzt die
   Schriftgroesse auf `.mud-input-root` (1rem), die Dropdown-Zeilen nutzen Typo.body2 (0.875rem) —
   ein font-size am Wrapper wuerde davon geschlagen, die Regel muss also direkt auf den Input-Root.
   Zusaetzlich den Dense-Margin des Feldes entfernen, sonst sitzt der Text tiefer als die Lupe daneben.
   Global statt scoped, weil beide Dropdowns im Portal am Wurzelknoten (MudPopoverProvider)
   ausserhalb der Komponente gerendert werden. */
.aura-project-search.mud-input-control {
    margin-top: 0 !important;
}

.aura-project-search .mud-input-root {
    font-size: 0.875rem;
}

/* Ausgewaehlte Tabellenzeile (Referenzkalkulationen): MudBlazors `.mud-selected-item` faerbt nur
   Listeneintraege (`.mud-list-item-clickable`), auf einer Tabellenzeile bleibt die Klasse wirkungslos.
   Ohne eigene Regel gibt ein Zeilenklick daher keinerlei sichtbare Rueckmeldung — das Detail-Panel
   steht unterhalb der Tabelle und liegt bei voller Liste ausserhalb des Sichtbereichs.
   !important, weil MudBlazors Zebra- und Hover-Regeln fuer `.mud-table-row` sonst gewinnen. */
.mud-table-row.aura-zeile-gewaehlt > td {
    background-color: var(--mud-palette-action-default-hover) !important;

/* Dialoge ueber der Bildschirmtastatur halten.
   MudBlazor zentriert den Dialog in einem `position: fixed`-Container mit voller Fensterhöhe.
   Auf iOS bleibt diese Höhe beim Aufklappen der Tastatur unverändert — der Dialog blieb also
   in der Mitte des GANZEN Bildschirms stehen und seine Eingabefelder lagen hinter der Tastatur.
   Mit --aura-viewport-height (js/auraKeyboard.js) endet der Container an der Tastaturkante, der
   Dialog zentriert sich im verbleibenden Bereich und wächst nicht darunter.
   Ohne offene Tastatur ist der Wert 100dvh, das Verhalten also unverändert. */
.mud-dialog-container {
    height: var(--aura-viewport-height) !important;
    max-height: var(--aura-viewport-height) !important;
}

/* Vollbild-Dialoge (MudBlazor FullScreen) dürfen ebenfalls nicht unter die Tastatur laufen,
   sonst sitzt ihre Fußzeile mit den Schaltflächen im Verborgenen. */
.mud-dialog-container .mud-dialog-fullscreen {
    height: var(--aura-viewport-height) !important;
    max-height: var(--aura-viewport-height) !important;
}
