/* ════════════════════════════════════════════════════════════════════════════
   Global dialog theme
   ----------------------------------------------------------------------------
   Unscoped (global) CSS rules that theme every dialog in the app using the
   shared `.inv-dialog` class. This lives OUTSIDE Blazor's CSS isolation on
   purpose — Syncfusion's SfDialog renders its markup into a portal attached
   to the document body, so scoped `::deep` selectors from a host page's
   .razor.css don't reach it reliably. By keeping the chrome styling here,
   every dialog looks identical no matter which page or component opens it.

   Usage contract:
     <SfDialog CssClass="inv-dialog …"> …your header / content… </SfDialog>

   Available modifier classes (all also global):
     .inv-dialog__content        — flex-column wrapper around content
     .inv-dialog__search         — input-group-sized filter row
     .inv-dialog__search-row     — flex row for search + side buttons
     .inv-dialog__state          — empty-state placeholder
     .inv-dialog__grid           — grid wrapper w/ rounded corners + border
     .inv-dialog__actions        — right-aligned action-button row
     .inv-dialog__summary-bar    — selection-count pill at the top

   All colors route through --shell-* theme tokens defined in app.css so that
   bootstrap/fluent2/material3/tailwind3 × light/dark/high-contrast all work.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Dialog chrome ─────────────────────────────────────────────────────── */
.inv-dialog.e-dialog {
    border-radius: 1.35rem;
    overflow: hidden;
    box-shadow: var(--shell-shadow-strong);
    background: var(--shell-panel-background-soft);
}

.inv-dialog .e-dlg-header-content {
    background: var(--shell-hero-background);
    color: var(--shell-text-inverse);
    border-bottom: none;
    padding: 0.85rem 1.15rem;
}

.inv-dialog .e-dlg-header {
    color: var(--shell-text-inverse);
    font-weight: 800;
    font-size: 1.05rem;
}

.inv-dialog .e-btn.e-dlg-closeicon-btn {
    color: var(--shell-text-inverse);
}

.inv-dialog .e-btn.e-dlg-closeicon-btn:hover {
    background: rgba(255, 255, 255, 0.14);
}

.inv-dialog .e-dlg-content {
    background: var(--shell-panel-background-soft);
    color: var(--shell-text-primary);
    padding: 1rem;
}

.inv-dialog .e-footer-content {
    background: var(--shell-panel-background-soft);
    border-top: 1px solid var(--shell-border);
    padding: 0.65rem 1rem;
}

/* ── Content primitives ────────────────────────────────────────────────── */
.inv-dialog__content {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.inv-dialog__content p {
    margin: 0;
    font-size: 0.92rem;
    color: var(--shell-text-primary);
    line-height: 1.5;
}

.inv-dialog__search-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.inv-dialog__search {
    flex: 1;
    min-width: 0;
}

.inv-dialog__state {
    display: grid;
    place-items: center;
    min-height: 180px;
    padding: 1rem;
    border: 1px dashed var(--shell-border-strong, var(--shell-border));
    border-radius: 1rem;
    color: var(--shell-text-secondary);
    font-size: 0.92rem;
    background: var(--shell-item-background-subtle);
}

/* ── Grid inside dialogs ──────────────────────────────────────────────── */
.inv-dialog__grid {
    min-width: 0;
}

.inv-dialog__grid .e-grid {
    border-radius: 1rem;
    overflow: hidden;
    border: 1px solid var(--shell-border);
    background: var(--shell-panel-background-soft);
}

.inv-dialog__grid .e-gridheader {
    background: color-mix(in srgb, var(--shell-contrast-surface-bg, var(--shell-panel-background)) 90%, var(--shell-button-primary) 10%);
    border-top-left-radius: 1rem;
    border-top-right-radius: 1rem;
}

.inv-dialog__grid .e-headercell {
    color: var(--shell-text-primary);
    text-align: center !important;
    white-space: normal !important;
    overflow-wrap: break-word;
    line-height: 1.25;
}

.inv-dialog__grid .e-headercell .e-headercelldiv {
    justify-content: center;
    text-align: center;
    white-space: normal;
}

.inv-dialog__grid .e-gridheader .e-columnheader {
    height: auto !important;
    min-height: 38px;
}

.inv-dialog__grid .e-rowcell {
    color: var(--shell-text-primary);
}

/* ── Right-align numeric editor cells ──────────────────────────────────
   Any grid inside a dialog that uses the `.cs-num` / `.cs-num-txt` classes
   on its inline editor (SfTextBox / SfNumericTextBox) gets right-aligned
   input text. Lives here in the global stylesheet because SfDialog renders
   to a portal on document.body — scoped `::deep` rules from a dialog's own
   .razor.css don't reliably reach portal-rendered descendants.

   Syncfusion's default .e-input rules left-align, so the !important is
   needed to win over the library's own cascade order (loaded from the
   theme CSS after app.css). Selector covers both the bare <input> and
   the .e-input wrapper Syncfusion sometimes puts between them. */
.cs-num input,
.cs-num .e-input,
.cs-num-txt input,
.cs-num-txt .e-input { text-align: right !important; }

/* ── Actions row ──────────────────────────────────────────────────────── */
/* The dialog's content host (.e-dlg-content) has padding: 1rem, but SfButton
   variants on Material3 / Fluent2 render a drop shadow that extends past the
   visual border by a few pixels, so the last button looked flush against the
   dialog's right wall. padding-right: 0.5rem gives the whole row a small
   inset beyond the content padding so Cancel has breathing room and aligns
   visually with the left content gutter. */
.inv-dialog__actions {
    display: flex;
    /* A row with more buttons than the dialog is wide wraps onto a second
       line instead of pushing the first (primary) button out of view. */
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 0.65rem;
    margin-top: 0.25rem;
    padding-right: 0.5rem;
}

/* ── Summary bar (selection count / running totals) ───────────────────── */
.inv-dialog__summary-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.5rem 0.75rem;
    border-radius: 0.85rem;
    background: color-mix(in srgb, var(--shell-button-primary) 8%, var(--shell-panel-background-soft));
    border: 1px solid color-mix(in srgb, var(--shell-button-primary) 20%, transparent);
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--shell-text-primary);
}

.inv-dialog__summary-bar strong {
    color: var(--shell-button-primary);
}

/* ── Shared busy overlay ─────────────────────────────────────────────
   Any dialog can drop
     <div class="inv-dialog__busy" role="status" aria-live="polite">
         <div class="inv-dialog__busy-spinner"></div>
         <div class="inv-dialog__busy-label">Saving…</div>
     </div>
   inside its Content area and toggle its visibility via a Blazor
   @if (_isBusy) guard. The overlay is absolutely positioned over the
   dialog content, dims the panel behind, and centres a CSS-only spinner
   + optional status label so the user sees the wait immediately without
   having to read the status banner.

   Why a custom spinner instead of SfSpinner:
     • Zero JS round-trip — renders the instant _isBusy flips true.
     • One set of theme tokens drives the colour, matches dialog chrome.
     • No risk of interacting with the SfDialog's own z-index stack.

   Tradeoff: no determinate progress ring. If a call needs a progress %
   bar later, swap the spinner div for <SfProgressBar>.
   ──────────────────────────────────────────────────────────────────── */
.inv-dialog__busy {
    position: absolute;
    inset: 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    /* Frosted dim over the panel — uses the same gradient token so the
       blur blends with the dialog instead of looking like a pasted layer. */
    background: color-mix(in srgb, var(--shell-panel-background-soft) 72%, rgba(0,0,0,0.18));
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    pointer-events: all;    /* blocks clicks on controls underneath */
    cursor: wait;
    animation: inv-dialog-busy-fade 140ms ease-out;
}

@keyframes inv-dialog-busy-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.inv-dialog__busy-spinner {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 3px solid color-mix(in srgb, var(--shell-button-primary) 25%, transparent);
    border-top-color: var(--shell-button-primary);
    animation: inv-dialog-busy-spin 0.9s linear infinite;
}

@keyframes inv-dialog-busy-spin {
    to { transform: rotate(360deg); }
}

.inv-dialog__busy-label {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--shell-text-primary);
    letter-spacing: 0.01em;
}

/* Host needs position:relative for the overlay's `inset:0` to latch
   onto the dialog content. The content primitive already stacks
   flex-column; adding position:relative is inert otherwise. */
.inv-dialog__content { position: relative; }

/* ── Shared status banners (warn / ok / error / info) ─────────────────
   Any dialog can drop <div class="inv-dialog__status inv-dialog__status--warn">
   without having to re-declare colours. Status tokens flip automatically for
   dark and high-contrast themes.
   ──────────────────────────────────────────────────────────────────────── */
.inv-dialog__status {
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    font-size: 0.85rem;
    font-weight: 500;
    border-left: 3px solid transparent;
}
.inv-dialog__status--error   { background: var(--shell-status-error-bg);
                                border-left-color: var(--shell-status-error-border);
                                color: var(--shell-status-error-text); }
.inv-dialog__status--warning { background: var(--shell-status-warn-bg);
                                border-left-color: var(--shell-status-warn-accent);
                                color: var(--shell-status-warn-text); }
.inv-dialog__status--info    { background: var(--shell-status-info-bg);
                                border-left-color: var(--shell-status-info-border);
                                color: var(--shell-status-info-text); }
.inv-dialog__status--ok      { background: var(--shell-status-ok-bg);
                                border-left-color: var(--shell-status-ok-accent);
                                color: var(--shell-status-ok-text); }
