/* General application-wide styles */

/* Zentrale Stellschraube für die Bildbreite im Chat-Verlauf. Generierte Bilder, Markdown-Bilder
   und die darunter liegenden Fußzeilen (Herkunft, Aktions-Buttons) richten sich alle danach —
   ohne gemeinsamen Wert laufen Bild und Fußzeile bei einer Änderung auseinander. */
:root {
    --aura-chat-image-max-width: 420px;

    /* Sichtbare Höhe der App und Höhe der Bildschirmtastatur. Beide Werte setzt
       js/auraKeyboard.js bei offener Tastatur als Pixelwert am <html>-Element; hier stehen
       die Ruhewerte. Alles, was die volle Höhe einnimmt, MUSS --aura-viewport-height statt
       100dvh/100vh benutzen — nur so schrumpft die Seite beim Aufklappen der Tastatur nach
       oben weg (Kopfbereich bleibt stehen, Eingabezeile sitzt auf der Tastatur), statt
       hinter die Tastatur zu rutschen oder verschoben zu werden. */
    --aura-viewport-height: 100dvh;
    --aura-keyboard-inset: 0px;
}

/* Force the entire document to be constrained to viewport */
html, body {
    height: 100% !important;
    overflow: hidden !important;
    margin: 0 !important;
    padding: 0 !important;
    /* Kein Überziehen/Gummiband am Rand: auf iOS konnte die Seite dadurch beim Tippen
       mitgezogen werden und der Kopfbereich verschwand nach oben. */
    overscroll-behavior: none;
}

#app {
    height: 100% !important;
    overflow: hidden !important;
}

/* Ensure MudBlazor components respect height constraints */
.mud-layout {
    height: var(--aura-viewport-height) !important;
    overflow: hidden !important;
}

/* iOS zoomt beim Fokussieren automatisch in ein Eingabefeld hinein, sobald dessen
   Schriftgröße unter 16px liegt — sichtbar als "die Seite zoomt/quetscht sich beim Tippen".
   max(16px, 1em) hebt nur die zu kleinen Felder an und lässt bewusst größere Schrift
   (z.B. Überschriften-Eingaben) unangetastet. Checkbox/Radio/Range tragen keinen Text und
   würden durch eine Schriftgröße nur in ihrer Größe verzerrt.
   Die contenteditable-Zeilen sind kein Beiwerk: die Chat-Eingabe ist KEIN <textarea>, sondern
   ein contenteditable-<div> (.custom-chat-input, 0.875rem) — genau das Feld, an dem der Zoom
   aufgefallen ist. */
:where([data-aura-view="mobile"]) input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
:where([data-aura-view="mobile"]) textarea,
:where([data-aura-view="mobile"]) select,
:where([data-aura-view="mobile"]) [contenteditable="true"],
:where([data-aura-view="mobile"]) [contenteditable=""] {
    font-size: max(16px, 1em) !important;
}

.mud-drawer-container {
    height: 100% !important;
    overflow: hidden !important;
}

/* MudMainContent should NOT have overflow hidden - it needs to contain scrollable content */
.mud-main-content {
    height: 100% !important;
    display: flex !important;
    flex-direction: column !important;
}

/* Drag-and-Drop Zone Styles */
.drag-drop-wrapper {
    width: 100%;
}

.drag-drop-zone {
    position: relative;
    transition: all 0.3s ease-in-out;
}

.drag-drop-zone.drag-over {
    border: 3px dashed var(--mud-palette-primary);
    background-color: rgba(var(--mud-palette-primary-rgb), 0.05);
    transform: scale(1.01);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
}

.drag-drop-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(var(--mud-palette-primary-rgb), 0.15);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    pointer-events: none;
    border-radius: 4px;
}

.drag-drop-overlay * {
    pointer-events: none;
}

.drag-drop-overlay .mud-icon-root {
    color: var(--mud-palette-primary);
    font-size: 3rem;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

.drag-drop-overlay .mud-typography {
    color: var(--mud-palette-primary);
    text-align: center;
    font-weight: 600;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

.mud-menu-list {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

/* Force dark-mode text color in HTML editor, overriding inline styles from email templates */
.html-editor-content,
.html-editor-content * {
    color: var(--mud-palette-text-primary) !important;
}

/* PhotoCaptureDialog: Desktop-Standardwerte */
.photo-capture-video-container {
    max-height: 400px;
    overflow: hidden;
    background: #000;
}

.photo-capture-video {
    max-width: 100%;
    max-height: 400px;
    object-fit: contain;
}

.photo-capture-preview-container {
    max-height: 300px;
    overflow: hidden;
}

.photo-capture-preview-img {
    max-width: 100%;
    max-height: 300px;
    object-fit: contain;
}

/* PhotoCaptureDialog: Fullscreen auf Mobile (via MudBlazor FullScreen=true + Feintuning) */
.photo-capture-dialog.mud-dialog-fullscreen {
    display: flex !important;
    flex-direction: column !important;
}

.photo-capture-dialog.mud-dialog-fullscreen .mud-dialog-title {
    flex-shrink: 0;
    padding-top: calc(8px + env(safe-area-inset-top, 0px)) !important;
    padding-left: calc(16px + env(safe-area-inset-left, 0px)) !important;
    padding-right: calc(16px + env(safe-area-inset-right, 0px)) !important;
}

.photo-capture-dialog.mud-dialog-fullscreen .mud-dialog-content {
    flex: 1 !important;
    display: flex !important;
    flex-direction: column !important;
    overflow-y: auto !important;
    padding-left: calc(16px + env(safe-area-inset-left, 0px)) !important;
    padding-right: calc(16px + env(safe-area-inset-right, 0px)) !important;
}

.photo-capture-dialog.mud-dialog-fullscreen .mud-dialog-actions {
    flex-shrink: 0;
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)) !important;
    padding-left: calc(16px + env(safe-area-inset-left, 0px)) !important;
    padding-right: calc(16px + env(safe-area-inset-right, 0px)) !important;
}

.photo-capture-dialog.mud-dialog-fullscreen .photo-capture-video-container {
    max-height: none !important;
    flex: 1 !important;
    min-height: 200px;
}

.photo-capture-dialog.mud-dialog-fullscreen .photo-capture-video {
    max-height: none !important;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.photo-capture-dialog.mud-dialog-fullscreen .photo-capture-preview-container {
    max-height: none !important;
    flex: 1 !important;
    min-height: 200px;
}

.photo-capture-dialog.mud-dialog-fullscreen .photo-capture-preview-img {
    max-height: none !important;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.photo-capture-dialog.mud-dialog-fullscreen .mud-button-root {
    min-height: 48px;
}


/* ChatAttachmentViewerModal: Betrachter fuer PDF, GAEB, E-Mail, Audio und Video eines
   Chat-Anhangs (Bilder gehen ins ImageAnnotatorOverlay, siehe AuraMobileDesign.md).
   Was war: `<div style="height: 80vh">` im Markup und ein Dialog mit MaxWidth.ExtraLarge
   ohne FullScreen. Auf dem Telefon war das ein gerahmter Kasten mit der kompletten
   PDF.js-Werkzeugleiste darin, und die 80vh rechnen mit der GROSSEN Viewporthoehe (ohne
   eingeklappte Browserleisten) — der Kasten lief unten unter die Adressleiste.
   Der Formfaktor kommt aus `FullScreen = IsMobile` an den beiden Aufrufstellen in
   ChatComponent; hier haengt nur noch an MudBlazors eigener Vollbild-Klasse. Damit gibt es
   KEINE zweite Mobile-Definition neben auraViewport.js. */
.chat-attachment-viewer-body {
    width: 100%;
    height: 80dvh;
}

.chat-attachment-viewer-dialog.mud-dialog-fullscreen {
    display: flex !important;
    flex-direction: column !important;
}

.chat-attachment-viewer-dialog.mud-dialog-fullscreen .mud-dialog-title {
    flex-shrink: 0;
    padding-top: calc(8px + env(safe-area-inset-top, 0px)) !important;
    padding-left: calc(16px + env(safe-area-inset-left, 0px)) !important;
    padding-right: calc(16px + env(safe-area-inset-right, 0px)) !important;
}

.chat-attachment-viewer-dialog.mud-dialog-fullscreen .mud-dialog-content {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
    padding-left: calc(8px + env(safe-area-inset-left, 0px)) !important;
    padding-right: calc(8px + env(safe-area-inset-right, 0px)) !important;
}

/* Im Vollbild bestimmt der Dialog die Hoehe, nicht der Kasten — mit seinen 80dvh ragte er
   sonst unter der Aktionsleiste heraus. `min-height: 0` ist Pflicht: ohne das weigert sich
   das Flex-Kind zu schrumpfen, das innere `overflow` greift nie und der Betrachter schiebt
   den ganzen Dialog auf (Anti-Pattern in AuraMobileDesign.md). */
.chat-attachment-viewer-dialog.mud-dialog-fullscreen .chat-attachment-viewer-body {
    height: auto;
    flex: 1 1 auto;
    min-height: 0;
}

.chat-attachment-viewer-dialog.mud-dialog-fullscreen .mud-dialog-actions {
    flex-shrink: 0;
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px)) !important;
    padding-left: calc(16px + env(safe-area-inset-left, 0px)) !important;
    padding-right: calc(16px + env(safe-area-inset-right, 0px)) !important;
}

.chat-attachment-viewer-dialog.mud-dialog-fullscreen .mud-button-root {
    min-height: 48px;
}

/* PhotoCaptureDialog: Handy-spezifisch */
@media (max-width: 480px) {
    .photo-capture-dialog .mud-dialog-title {
        padding-top: calc(4px + env(safe-area-inset-top, 0px)) !important;
        padding-bottom: 4px !important;
    }

    .photo-capture-dialog .mud-dialog-content {
        padding-left: calc(12px + env(safe-area-inset-left, 0px)) !important;
        padding-right: calc(12px + env(safe-area-inset-right, 0px)) !important;
    }

    .photo-capture-dialog .mud-dialog-actions {
        padding-left: calc(12px + env(safe-area-inset-left, 0px)) !important;
        padding-right: calc(12px + env(safe-area-inset-right, 0px)) !important;
    }

    .photo-capture-dialog .photo-capture-action-buttons {
        flex-direction: column !important;
    }

    .photo-capture-dialog .photo-capture-action-buttons > .mud-button-root {
        flex: unset !important;
        width: 100%;
    }

    .photo-capture-dialog .photo-capture-thumbnails img {
        height: 48px !important;
        width: 48px !important;
    }
}

.recording-pulse {
    animation: pulse-recording 1.2s ease-in-out infinite;
}

@keyframes pulse-recording {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
}

/* --------------------------------------------------------------------------------------
   Reduzierte Bewegung respektieren.

   Die Systemeinstellung (Windows: Barrierefreiheit -> Animationseffekte) wurde bisher
   nirgends im Chat ausgewertet. Ein laengerer AgentMode-Lauf laesst jede neu erscheinende
   Tool-Zeile einfliegen; zusammen mit den Endlos-Spinnern ergibt das ein unruhiges Bild
   genau fuer die Nutzer, die das ausdruecklich abgewaehlt haben.

   Die Regel steht bewusst global und mit !important: die Animationen sind überwiegend in
   Blazor-Scoped-Stylesheets definiert, deren Selektoren durch das b-Attribut höhere
   Spezifität haben. Sie trifft damit auch MudBlazor-eigene Übergänge (Dialoge, Ripple).

   Bewusst NICHT mit abgeschaltet wird der Aufnahme-Indikator: er ist ein Statuszeichen,
   kein Schmuck. Statt zu blinken steht er still auf voller Deckkraft, bleibt also sichtbar.

   Ebenfalls ausgenommen: funktionale Fortschrittsanzeigen, siehe den Block weiter unten.
   Sie sind der Grund, warum diese Regel nicht einfach „alles anhalten" heißen darf.
   -------------------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    .recording-pulse {
        animation: none !important;
        opacity: 1;
    }

    /* ----------------------------------------------------------------------------------
       Funktionale Fortschrittsanzeigen laufen weiter — app-weit, nicht nur im Chat.

       Eine stehende Fortschrittsanzeige ist keine ausgelassene Dekoration, sie ist eine
       Falschaussage: Sie behauptet „hier hängt etwas", während der Vorgang in Ruhe
       weiterläuft. Genau so wurde es gemeldet — „Passung aktualisieren" in der
       Vergabe-Übersicht zeigte einen stehenden Spinner, und zwar alle Spinner der Seite
       gleichzeitig, weil die Regel oben mit `*` auf jedes Element wirkt.

       Vorher war diese Ausnahme auf `.chat-messages-container` eingeschränkt. Damit stand
       JEDER Spinner außerhalb des Chats still, sobald im Betriebssystem
       (Windows: Barrierefreiheit -> Visuelle Effekte -> Animationseffekte) die
       Bewegungsreduzierung eingeschaltet ist.

       Dauer und Wiederholung müssen hier konkret stehen: Die Regel oben setzt beide mit
       !important, und es gibt kein CSS-Schlüsselwort, das auf den Wert einer anderen
       Autoren-Regel zurückfällt — `revert` und `unset` landen beim Browser-Vorgabewert
       (0s bzw. 1) und würden den Spinner erst recht anhalten. Die Werte stammen aus
       MudBlazor 8.15.0. Weicht eine künftige Fassung ab, dreht der Spinner nur
       geringfügig anders schnell; kaputt geht dabei nichts.

       Eigene Spinner (kein MudBlazor) nehmen sich in ihrem eigenen Stylesheet aus, direkt
       neben ihrer `animation`-Zeile — dort steht die Dauer schon, und zwei Zeilen
       auseinander kann sie nicht auseinanderlaufen. Muster: siehe
       `Components/Documents/DocumentListComponent.razor.css`.
       ---------------------------------------------------------------------------------- */
    .mud-progress-circular.mud-progress-indeterminate,
    .mud-progress-circular-indeterminate-child,
    .mud-progress-circular-circle.mud-progress-indeterminate {
        animation-duration: 1.4s !important;
        animation-iteration-count: infinite !important;
    }

    /* Der unbestimmte Balken (MudProgressLinear) besteht aus zwei Laufbalken mit eigener
       Verzögerung. Die Verzögerung rührt die Regel oben nicht an, deshalb genügen Dauer
       und Wiederholung. */
    .mud-progress-linear.mud-progress-indeterminate .mud-progress-linear-bar,
    .mud-progress-linear .mud-progress-linear-bar.mud-progress-linear-1-indeterminate,
    .mud-progress-linear .mud-progress-linear-bar.mud-progress-linear-2-indeterminate {
        animation-duration: 2.1s !important;
        animation-iteration-count: infinite !important;
    }

    /* Bootstrap-Spinner: In AURA werden sie an rund vierzig Stellen benutzt (Dokumentgenerator,
       Inventar, Grundriss-Ansicht …) und standen bis 1.1.1186 genauso still wie die von
       MudBlazor. Hier ist keine Zahl nötig: Bootstrap legt die Dauer als eigene Variable ab,
       also wird genau der Wert weiterverwendet, den die Klasse selbst mitbringt — `.spinner-grow`
       setzt ihn auf 1,5 s und bekommt damit automatisch die richtige Dauer. */
    .spinner-border,
    .spinner-grow {
        animation-duration: var(--bs-spinner-animation-speed) !important;
        animation-iteration-count: infinite !important;
    }
}

/* Kompakt-Ansicht: enger gefasste vertikale Abstaende.
   Wird ueber UserSettingsState.ChatViewMode == Compact aktiviert. */

.chat-messages-container.compact-view .chat-messages-inner {
    padding: 2px 8px !important;
}

.chat-messages-container.compact-view .chat-message-wrapper {
    margin-bottom: 1px !important;
}

.chat-messages-container.compact-view .system-message {
    margin-bottom: 1px !important;
}

.chat-messages-container.compact-view .message-group {
    margin-bottom: 0 !important;
}

.chat-messages-container.compact-view .chat-bubble-content {
    padding: 0.5rem 0.75rem 0.1rem !important;
    line-height: 1.35 !important;
}

.chat-messages-container.compact-view .chat-timestamp {
    margin-bottom: 1px !important;
}

.chat-messages-container.compact-view .chat-bubble-content p {
    margin-bottom: 0.15rem !important;
    line-height: 1.35 !important;
}

.chat-messages-container.compact-view .chat-bubble-content h1,
.chat-messages-container.compact-view .chat-bubble-content h2,
.chat-messages-container.compact-view .chat-bubble-content h3,
.chat-messages-container.compact-view .chat-bubble-content h4,
.chat-messages-container.compact-view .chat-bubble-content h5,
.chat-messages-container.compact-view .chat-bubble-content h6 {
    margin: 0.25rem 0 0.15rem 0 !important;
}

.chat-messages-container.compact-view .chat-bubble-content ul,
.chat-messages-container.compact-view .chat-bubble-content ol {
    margin: 0.15rem 0 !important;
}

.chat-messages-container.compact-view .chat-bubble-content li {
    margin: 0.05rem 0 !important;
    line-height: 1.35 !important;
}

.chat-messages-container.compact-view .chat-bubble-content pre,
.chat-messages-container.compact-view .chat-bubble-content blockquote {
    margin: 0.25rem 0 !important;
}

.chat-main-area:has(.chat-messages-container.compact-view) .chat-input-wrapper {
    padding: 4px !important;
}

.chat-main-area:has(.chat-messages-container.compact-view) .custom-chat-input {
    min-height: 38px !important;
    padding: 6px 14px !important;
}

/* Workaround: Diese Regeln sitzen bewusst in app.css statt im scoped MainLayout.razor.css.
   Grund: Aturis.Aura.Ui.styles.css (Blazor Scoped CSS Bundle für die Aura.Ui RCL) wird im
   Tenant-Hosting nicht ausgeliefert (404), darum landen scoped CSS-Regeln aus MainLayout.razor.css
   nicht beim Client. Bis das Static-Asset-Setup gefixt ist, müssen UI-kritische Panel-Regeln hier. */

/* Items im Two-Column-Nav-Panel: Default-Browser-Link-Styling (blau + Underline) hat
   sich durchgesetzt, weil MudBlazor's .mud-nav-link-Reset im Panel-Kontext nicht greift.
   Hart per !important auf den Mud-Theme-Text zurücksetzen — gilt für Web und Mobile. */
.two-col-panel-overlay .mud-nav-link,
.two-col-panel-overlay a {
    color: var(--mud-palette-text-primary) !important;
    text-decoration: none !important;
}

/* Web (Desktop, >= 960 px): Panel sitzt direkt unter der AppBar (flush), aber HINTER dem AppBar-
   z-index. Dadurch erscheint der AppBar-Box-Shadow ON TOP des Panels — Schatten bleibt sichtbar.
   z-index 1099 < AppBar 1100 = MudAppBar überlagert Panel im überlappenden x/y-Bereich. */
:where([data-aura-view="desktop"]) .two-col-panel-overlay {
    top: var(--mud-appbar-height, 64px) !important;
    z-index: 1099 !important;
}

/* MailView- und MailsOverview-Toolbar auf Mobile (< 960 px): Buttons zu Icon-only kompaktieren.
   MudBlazor v8 wickelt die Button-Struktur als <button>→<.mud-button-label>→[icon, text]; ein
   display:none auf .mud-button-label würde auch das Icon mit verstecken (das sitzt drin).
   Lösung: Text-Knoten per font-size:0 kollabieren, Icon-Größe ist über fixe SVG-width/height
   gesetzt und bleibt sichtbar. Padding reduzieren damit die Buttons nicht ungleich groß sind.
   Such-Feld in MailsOverview-Toolbar bleibt sichtbar — nimmt restliche Breite. */
:where([data-aura-view="mobile"]) .mailview-toolbar .mud-button-root,
:where([data-aura-view="mobile"]) .mailsoverview-toolbar .mud-button-root {
    min-width: 0 !important;
    padding: 6px !important;
    margin-right: 0 !important;
    font-size: 0 !important;
}
:where([data-aura-view="mobile"]) .mailview-toolbar .mud-button-root .mud-button-icon-start,
:where([data-aura-view="mobile"]) .mailsoverview-toolbar .mud-button-root .mud-button-icon-start {
    margin: 0 !important;
    font-size: initial !important;
}
/* Such-Feld nimmt den verbleibenden Platz in der MailsOverview-Toolbar */
:where([data-aura-view="mobile"]) .mailsoverview-toolbar .mud-input-text-field,
:where([data-aura-view="mobile"]) .mailsoverview-toolbar .mud-input-control {
    max-width: none !important;
    flex: 1 1 auto;
}

/* Mobile (< 960 px): Panel über volle Bildschirmhöhe.
   Bewusst KEINE explizite height — top:0 + bottom:0 lassen den Browser die Höhe aus dem Viewport
   ausrechnen. 100vh / 100dvh haben auf Mobile (besonders im DevTools-Emulator) öfter Macken und
   ergeben Werte, die ein paar % unter dem tatsächlichen Viewport liegen — das Panel hört dann
   früher auf als die Rail-Drawer daneben.
   Padding-top:8px = Rail-Padding-top auf Mobile (Drawer-Temporary sitzt bei top:0, Rail hat 8px
   internes padding-top), damit der Panel-Header auf der gleichen Höhe wie das erste Rail-Icon
   startet. z-index 1400 > AppBar/Backdrop, damit Panel über allem liegt und Klicks ankommen.
   Bottom hängt an --aura-keyboard-inset: öffnet die Tastatur (z.B. Projektsuche im Panel),
   endet das Panel an der Tastaturkante statt dahinter weiterzulaufen. */
:where([data-aura-view="mobile"]) .two-col-panel-overlay {
    position: fixed !important;
    top: 0 !important;
    bottom: var(--aura-keyboard-inset, 0px) !important;
    height: auto !important;
    padding-top: 8px !important;
    padding-bottom: 8px !important;
    z-index: 1400 !important;
}
/* Default-Margins der Kinder zurücksetzen, sonst rutscht der Header durch das User-Agent-
   Stylesheet (z.B. <ul>-Default-Margin in MudNavMenu) zusätzlich nach unten. */
:where([data-aura-view="mobile"]) .two-col-panel-overlay .two-col-panel-header {
    margin-top: 0 !important;
    padding-top: 0 !important;
}
:where([data-aura-view="mobile"]) .two-col-panel-overlay .mud-navmenu,
:where([data-aura-view="mobile"]) .two-col-panel-overlay ul {
    margin-top: 0 !important;
    padding-top: 0 !important;
}

/* Kalender (Heron.MudCalendar) auf Mobile (< 960 px):
   - Heron-interne View-Auswahl-Buttons werden via CSS ausgeblendet (Show*=false hat das Rendering
     der View selbst blockiert — leerer Day-Content). Ihre Funktion uebernimmt das eigene
     Overlay-MudMenu.
   - Overlay-Icon (.cal-view-switch-overlay) absolut rechts oben auf der Heron-Toolbar. z-index 2,
     damit es ueber den Toolbar-Inhalten liegt, aber unter Popups.
   - Heron-Toolbar erlaubt Flex-Wrap, falls die Nav-Buttons (Chevrons/Heute/Datum) bei sehr engen
     Geraeten nicht in eine Zeile passen. */
.cal-view-switch-overlay {
    position: absolute;
    top: 8px; /* visuell zentriert mit Heron's Nav-Buttons (Toolbar padding-top ~8 px + Button-Center ~20 px) */
    right: 8px;
    z-index: 2;
}

:where([data-aura-view="mobile"]) .cal-wrapper-mobile .mud-cal-toolbar {
    flex-wrap: wrap;
    gap: 4px;
    padding-right: 56px; /* Platz fuer das absolut positionierte View-Switch-Overlay (Size.Large) */
}
/* Heron's interne View-Auswahl-Buttons (Tag/Arbeitswoche/Woche/Monat) verstecken.
   `.mud-cal-toolbar-nav` ist Heron's NAVIGATION-Block (Chevrons/Datum/Heute) — den BEHALTEN.
   Die View-Buttons sitzen als zweiter direkter Kind-Container daneben (ohne eigene Klasse),
   darum :not() zum Invertieren: alle direkten Kinder verstecken, AUSSER toolbar-nav. */
:where([data-aura-view="mobile"]) .cal-wrapper-mobile .mud-cal-toolbar > *:not(.mud-cal-toolbar-nav) {
    display: none !important;
}

/* Mobile-AppBar-Suchzeile: fixed direkt unter der AppBar, sichtbar wenn _appbarSearchOpen.
   z-index 1099 < AppBar (1100), damit AppBar-Schatten und Dropdowns drueber bleiben.
   Box-Shadow ahmt eine eigene flache Trennung zur Page nach. Full-Width Padding,
   Such-DynamicComponent darin nimmt flex-grow:1, Close-Icon rechts. */
.mobile-search-row {
    position: fixed;
    top: var(--mud-appbar-height, 64px);
    left: 0;
    right: 0;
    z-index: 1099;
    background: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12);
}

/* Nested MudMenu-Activators (z.B. TaskMonitor "Aufgaben" im UserAvatarDropdown) bekommen von
   MudBlazor v8 die Klasse `mud-menu-sub-menu-activator`. Per Default rendert das Wrapper-Element
   mit groesseren Horizontal-Gutters als die Geschwister-MudMenuItems im selben Menue (die hier
   8 px / 12 px verwenden), was den Text gegenueber den anderen Eintraegen einrueckt. Wir
   ueberschreiben mit den exakten Sibling-Werten (8 px vertical / 12 px horizontal) und resetten
   die browser-default `<p>`-Margins der `.mud-menu-item-text`, damit "Aufgaben" pixelgenau mit
   "Konto/Hilfe/..." flushed. */
.mud-menu-sub-menu-activator {
    padding: 8px 12px !important;
}

.mud-menu-sub-menu-activator > .mud-menu-item-text,
.mud-menu-sub-menu-activator > p {
    margin: 0 !important;
    margin-block: 0 !important;
    margin-inline: 0 !important;
    padding: 0 !important;
    padding-block: 0 !important;
    padding-inline: 0 !important;
    text-indent: 0 !important;
}

/* ReportTemplateDetailPage: auf Mobile blenden wir den nativen MudTabs-Header (mit den drei
   Tabs nebeneinander) aus und ersetzen ihn durch einen eigenen Single-Tab-Navigator mit
   Chevron-Pfeilen + zentriertem Label. Sonst werden Labels wie "Automatisierung" truncated zu
   "AUT" weil zu wenig Platz da ist. */
/* MudBlazor v8 rendert die Tab-Leiste je nach Version unter wechselnden Klassen — wir matchen
   alle bekannten Varianten, damit auf Mobile der native Header zuverlaessig ausgeblendet ist. */
.report-tabs-mobile-no-header > .mud-tabs-toolbar,
.report-tabs-mobile-no-header .mud-tabs-tabbar,
.report-tabs-mobile-no-header .mud-tabs-tabbar-wrapper,
.report-tabs-mobile-no-header .mud-tabs-toolbar-content,
.report-tabs-mobile-no-header .mud-tabs-header {
    display: none !important;
}

/* ReportView Mobile: Aktions-Buttons in einer fixierten Bottom-Bar. Toggle-Header schaltet
   die Buttons sichtbar/unsichtbar — kollabiert ist nur die Header-Zeile (~40 px) am unteren
   Bildschirmrand, expanded liegen die Buttons darüber. */
.report-actions-bottom-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 100;
    background: var(--mud-palette-surface);
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
    padding: 4px 8px 8px;
}

.report-actions-bottom-bar .actions-toggle-header {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    cursor: pointer;
    padding: 6px;
    user-select: none;
    border-bottom: 1px solid var(--mud-palette-divider);
    color: var(--mud-palette-primary);
    font-weight: 600;
}

.report-actions-bottom-bar .actions-toggle-header .mud-icon-root {
    color: var(--mud-palette-primary);
}

.report-actions-bottom-bar .actions-content {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding-top: 8px;
}

/* MudMenu mit ActivatorContent wickelt seinen Inhalt in einen inline-block-Container ein —
   eine FullWidth-MudButton-Activator wuerde sonst trotzdem nur Content-Breit. Die Klasse
   `mobile-fullwidth-menu` (auf MudMenu im Mobile-Zustand gesetzt) zwingt nur den Menu-Wrapper
   und dessen direkte Kinder auf block + 100%; den inneren MudButton lassen wir bei seinem
   natuerlichen inline-flex (sonst stacken Icon + Text vertikal statt nebeneinander). */
.mobile-fullwidth-menu,
.mobile-fullwidth-menu > * {
    display: block !important;
    width: 100% !important;
}

/* SmartIndexPromptEditor Dialog: Switch + Beschreibungs-Zeile auf Mobile vertikal stacken.
   Per @media weil CascadingValue IsMobile aus MainLayout Dialog-Content nicht erreicht (Dialogs
   leben ausserhalb von @Body im MudDialogProvider).
   Doppel-Klassen-Selektor (.web-search-switch-row.flex-row) hat Specificity (0,2,0) und gewinnt
   gegen MudBlazors `.flex-row { flex-direction: row !important; }` (0,1,0), unabhaengig von der
   Stylesheet-Ladereihenfolge. */
:where([data-aura-view="mobile"]) .web-search-switch-row.flex-row {
    flex-direction: column !important;
    align-items: flex-start !important;
}

/* Beschreibungstext am linken Rand des Switches ausrichten (NICHT am Label). MudSwitch hat
   eine kleine padding-left (~12 px) fuer den Focus-Ring vor dem eigentlichen Track — den
   gleichen Offset geben wir dem p darunter, damit beide am gleichen X starten. */
:where([data-aura-view="mobile"]) .web-search-switch-row.flex-row > p.mud-typography {
    padding-left: 12px;
}

/* Generator-Page Mobile: VoiceControls als fixierte Bottom-Bar mit 3 Buttons nebeneinander
   (Assistent Start / Stop / Sprach-Monitor-Toggle). */
.gen-voice-controls-mobile {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 100;
    background: var(--mud-palette-surface);
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
    padding: 8px;
    display: flex;
    gap: 6px;
}

.gen-voice-controls-mobile .gen-voice-btn {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
}

/* Bild-Annotator: laufende Texteingabe.
   Diese beiden Elemente werden von wwwroot/js/imageAnnotator.js erzeugt und tragen daher
   KEIN Scoped-CSS-Attribut — die Stile muessen global stehen, nicht in
   ImageAnnotatorOverlay.razor.css. Position, Schriftgroesse und Farbe setzt das Skript
   inline in Bildschirm-Pixeln, damit der Text exakt dort landet, wo er beim
   Festschreiben auf den Canvas gezeichnet wird. */
.image-annotator-text-entry {
    position: absolute;
    z-index: 2;
    margin: 0;
    /* 1px Rand + 2px Padding = TEXT_BOX_INSET (3) in imageAnnotator.js */
    padding: 0 2px;
    /* Leicht abgedunkelt, damit auch weisser Text auf einem weissen Plan sichtbar bleibt —
       der Kasten verschwindet beim Festschreiben wieder */
    background: rgba(0, 0, 0, 0.3);
    border: 1px dashed rgba(255, 255, 255, 0.9);
    border-radius: 2px;
    outline: none;
    white-space: pre;
    box-sizing: content-box;
    /* Rand + Padding gehen als TEXT_BOX_INSET in imageAnnotator.js ein — beim Aendern
       dort mit anpassen, sonst verschiebt sich der Text beim Festschreiben.
       line-height setzt das Skript ueber die font-Kurzschreibweise. */
}

.image-annotator-text-entry::placeholder {
    color: rgba(255, 255, 255, 0.55);
    font-weight: normal;
}

/* Eigener Griff zum Verschieben: ein Klick IN den Kasten setzt den Textcursor,
   gezogen wird ausschliesslich am Griff */
.image-annotator-text-handle {
    position: absolute;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 3px;
    cursor: move;
    touch-action: none;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

/* Vier-Wege-Pfeil als Verschiebe-Andeutung, ohne Abhaengigkeit von einer Icon-Bibliothek */
.image-annotator-text-handle::before {
    content: "✥";
    color: #202020;
    font-size: 0.8em;
    line-height: 1;
}

/* Utility fuer MudTextField: hebt MudBlazors `resize: none` auf. Nur vertikal, sonst wird
   die Textarea breiter als ihr Dialog. Details: AuraMobileDesign.md, Mobile-Patterns. */
.aura-resizable-textarea textarea.mud-input-root {
    resize: vertical !important;
    max-width: 100%;
}

/* Utility für die aufgeklappten Detailzeilen des Kalkulationsassistenten (Phase 4 und 5;
   Phase 2 setzt denselben Wert direkt auf ihre Detailzeile, siehe VergabePhase.razor.css).
   Die Detailzeilen spannen per colspan über alle Spalten ihrer Tabelle; in Phase 4 und 5 ist
   die breiter als das Fenster. Über diese volle Breite gezogen wäre der Inhalt — Langtext,
   Angebotsübersicht, Kalkulations-Aufschlüsselung — nur mit horizontalem Scrollen lesbar,
   deshalb bleibt er auf Lesebreite und klebt beim Scrollen am linken Rand, wie die
   eingefrorenen Pos.- und Kurztext-Spalten. Global statt scoped, weil dieselbe Regel in
   mehreren Phasen gilt.

   Die Breite ist zusätzlich an den verfügbaren Platz gekoppelt: eine feste Obergrenze allein
   reicht nicht, weil die Tabelle horizontal scrollt. Ist der Block breiter als der sichtbare
   Bereich, läuft er rechts heraus und genau das Scrollen wäre wieder nötig, das die Begrenzung
   verhindern soll.

   Maßstab ist dabei 100cqi — die Breite des Phasen-Rumpfes (.preisspiegel-root bzw.
   .angebotserstellung-root, dort als Container deklariert), NICHT die Fensterbreite: der
   Navigationsbereich links gehört nicht zum verfügbaren Platz, mit einer vw-Angabe lief der
   Inhalt auf schmalen Bildschirmen weiterhin über. Die vw-Zeile davor bleibt als Rückfallebene
   für Browser ohne Container-Queries stehen — ohne sie fiele dort die ganze Deklaration weg
   und die Zeile hätte gar keine Begrenzung mehr.

   Die 900 px sind derselbe Wert, auf den Phase 2 ihre Detailzeile begrenzt
   (VergabePhase.razor.css) — die Detailzeilen lesen sich damit in allen Phasen gleich. */
.calc-detail-lesebreite {
    max-width: min(900px, 85vw);
    max-width: min(900px, 100cqi);
    position: sticky;
    left: 0;
}

/* Kurztext-Zelle mit Aufklapp-Indikator (Kalkulationsassistent Phase 4 und 5).
   Das Chevron steht in einer eigenen Spalte links neben dem Text statt im Textfluss: sonst
   rücken die Icons die erste Zeile ein und ein umgebrochener Kurztext beginnt darunter
   versetzt. Global statt scoped, weil MudIcon das Scope-Attribut nicht mitrendert und
   dieselbe Regel in beiden Phasen gilt. */
.calc-kurztext-zeile {
    display: flex;
    align-items: center;
    gap: 6px;
}

.calc-kurztext-aufklapper {
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    opacity: 0.55;
}

.calc-kurztext-aufklapper .mud-icon-root {
    width: 18px;
    height: 18px;
    font-size: 18px;
}

/* min-width: 0 lässt den Text im Flex-Container umbrechen, statt die Zelle aufzudehnen. */
.calc-kurztext-inhalt {
    min-width: 0;
}

/* --- DialogHeader (Components/Shared/DialogHeader.razor) -------------------------------------
   Der farbige Balken soll die volle Dialogbreite einnehmen. Er hat sich früher mit
   margin:-16px -24px aus dem Padding des Titelbereichs herausgezogen — das passt aber nur,
   solange der Titel wirklich 24px rechtes Padding hat. Sobald der Dialog einen Schließen-Button
   bekommt, setzt MudBlazor `.mud-dialog-title:has(.mud-button-close) { padding-inline-end: 64px }`,
   und der Balken endete 40px vor dem rechten Rand. Statt die Werte nachzurechnen, bekommt der
   Titelbereich hier gar kein Padding mehr — der Balken bringt es selbst mit. */
.mud-dialog .mud-dialog-title:has(> .aura-dialog-header) {
    padding: 0 !important;
}

.aura-dialog-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 24px;
    background: var(--mud-palette-primary);
    border-top-left-radius: inherit;
    border-top-right-radius: inherit;
}

/* Der Schließen-Button liegt absolut oben rechts im Dialog. Titel und optionale Header-Aktionen
   brauchen deshalb rechts Platz, sonst laufen sie darunter. */
.mud-dialog .mud-dialog-title:has(.mud-button-close) > .aura-dialog-header {
    padding-inline-end: 64px;
}

/* Der Schließen-Button sitzt jetzt auf dem farbigen Balken und braucht dessen Kontrastfarbe. */
.mud-dialog .mud-dialog-title:has(> .aura-dialog-header) .mud-button-close {
    color: var(--mud-palette-primary-text, #fff);
}
