/* ================================================================================================
   DataPhyx grid & entity-header restyle (app-wide).

   Loaded AFTER the Syncfusion bootstrap4 theme in _Host.cshtml so these rules win without needing
   heavy !important stacking. Grid rules are scoped to .dpx-grid-shell .e-grid: SfDynamicGrid wraps
   every grid in a plain <div class="dpx-grid-shell"> because Syncfusion's SfGrid CssClass parameter
   is not reliably rendered onto the .e-grid root in this build, whereas a plain wrapper div always
   is. The wrapper uses display:contents so it adds no box of its own and never affects layout.
   Entity page-header helpers (.entity-page-*) are additive and used by EntityMainLayout.
   ================================================================================================ */

:root {
    --dpx-accent: #2563eb;
    --dpx-accent-dark: #1d4ed8;
    --dpx-border: #e2e8f0;
    --dpx-text: #1e293b;
    --dpx-muted: #64748b;
    --dpx-header-grad-top: #ffffff;
    --dpx-header-grad-bottom: #f8fafc;
}

/* Wrapper SfDynamicGrid puts around every grid. The grid's Height is 100% of this box, so this box
   decides the grid height. Default: the viewport less the header, title and tab strip, which
   follows window size and browser zoom. Inside the entity layout on desktop it fills the active
   tab exactly instead (EntityMainLayout.razor makes the active tab a flex column). */
.dpx-grid-shell {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 220px);
    min-height: 320px;
}

    /* The grid itself is a flex column too: toolbar, header and pager keep their natural height
       and the scrolling row area takes the rest. This keeps the rows sized to the box on resize and
       zoom without depending on Syncfusion recalculating its inline content height. */
    .dpx-grid-shell > .e-grid {
        flex: 1 1 0;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

        .dpx-grid-shell > .e-grid > :not(.e-gridcontent) {
            flex: 0 0 auto;
        }

        .dpx-grid-shell > .e-grid > .e-gridcontent {
            flex: 1 1 0;
            min-height: 0;
            display: flex;
            flex-direction: column;
        }

            .dpx-grid-shell > .e-grid > .e-gridcontent > .e-content {
                flex: 1 1 0;
                height: auto !important;
                min-height: 0;
            }

@media (min-width: 768px) {
    .entity-main-layout .e-item.e-active > .dpx-grid-shell {
        flex: 1 1 0;
        height: auto;
    }
}

/* ---------------------------------------------------------------------------------- Grid shell */
.dpx-grid-shell .e-grid {
    border: 1px solid var(--dpx-border);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
    font-family: inherit;
}

/* ------------------------------------------------------------------------------------- Toolbar */
.dpx-grid-shell .e-grid .e-toolbar {
    border: none;
    border-bottom: 1px solid var(--dpx-border);
    padding: 4px 6px;
    background: #fff;
}

    .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item .e-tbar-btn {
        border-radius: 8px;
        font-weight: 600;
        color: #334155;
        transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
    }

    .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item .e-tbar-btn:hover {
        background: #f1f5f9;
    }

    /* Emphasize the primary Add action. */
    .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item#Grid_add .e-tbar-btn,
    .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item[title="Add"] .e-tbar-btn {
        background: var(--dpx-accent);
        color: #fff;
    }

        .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item#Grid_add .e-tbar-btn:hover,
        .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item[title="Add"] .e-tbar-btn:hover {
            background: var(--dpx-accent-dark);
        }

        .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item#Grid_add .e-tbar-btn .e-icons,
        .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item[title="Add"] .e-tbar-btn .e-icons,
        .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item#Grid_add .e-tbar-btn .e-tbar-btn-text,
        .dpx-grid-shell .e-grid .e-toolbar .e-toolbar-item[title="Add"] .e-tbar-btn .e-tbar-btn-text {
            color: #fff;
        }

    /* Rounded search box with a focus ring. */
    .dpx-grid-shell .e-grid .e-toolbar .e-input-group.e-search {
        border-radius: 8px;
        background: #f8fafc;
        border: 1px solid var(--dpx-border);
        padding: 2px 8px;
    }

        .dpx-grid-shell .e-grid .e-toolbar .e-input-group.e-search.e-input-focus {
            border-color: var(--dpx-accent);
            box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
            background: #fff;
        }

/* ---------------------------------------------------------------------------- Column header row
   Sticky positioning itself is handled by EnableStickyHeader; here we just make it read clearly. */
.dpx-grid-shell .e-grid .e-gridheader {
    border-top: none;
    border-bottom: 2px solid var(--dpx-border);
}

    .dpx-grid-shell .e-grid .e-gridheader .e-headercell,
    .dpx-grid-shell .e-grid .e-gridheader .e-detailheadercell,
    .dpx-grid-shell .e-grid .e-gridheader .e-grouptopleftcell {
        background: linear-gradient(180deg, var(--dpx-header-grad-top), var(--dpx-header-grad-bottom));
        border-color: #eef2f7;
    }

    .dpx-grid-shell .e-grid .e-gridheader .e-headercelldiv,
    .dpx-grid-shell .e-grid .e-gridheader .e-headertext {
        color: #334155;
        font-weight: 700;
        font-size: 12.5px;
        letter-spacing: 0.2px;
    }

    /* Sorted column: accent the header text + sort arrow. */
    .dpx-grid-shell .e-grid .e-gridheader .e-headercell.e-focused,
    .dpx-grid-shell .e-grid .e-gridheader .e-sortfilter .e-headertext {
        color: var(--dpx-accent-dark);
    }

    .dpx-grid-shell .e-grid .e-gridheader .e-sortnumber {
        background: var(--dpx-accent);
        color: #fff;
    }

    .dpx-grid-shell .e-grid .e-gridheader .e-icon-ascending::before,
    .dpx-grid-shell .e-grid .e-gridheader .e-icon-descending::before {
        color: var(--dpx-accent);
    }

/* ---------------------------------------------------------------------------------------- Rows */
.dpx-grid-shell .e-grid .e-row .e-rowcell {
    border-color: #f1f5f9;
    color: var(--dpx-text);
    padding-top: 9px;
    padding-bottom: 9px;
}

.dpx-grid-shell .e-grid .e-row:nth-child(even) .e-rowcell {
    background: #fbfdff;
}

.dpx-grid-shell .e-grid .e-row:hover .e-rowcell {
    background: #eff6ff !important;
}

/* Left accent bar on the hovered/selected row. */
.dpx-grid-shell .e-grid .e-row:hover .e-rowcell:first-child {
    box-shadow: inset 3px 0 0 var(--dpx-accent);
}

.dpx-grid-shell .e-grid .e-row .e-selectionbackground {
    background: #dbeafe !important;
}

/* ------------------------------------------------------------------------- Details chip button */
.dpx-details-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    font-weight: 600;
    color: var(--dpx-accent-dark);
    background: #eff6ff;
    border: 1px solid #dbeafe;
    padding: 5px 12px;
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

    .dpx-details-btn:hover {
        background: #dbeafe;
        border-color: #bfdbfe;
    }

    .dpx-details-btn:hover .dpx-details-arrow {
        transform: translateX(2px);
    }

.dpx-details-arrow {
    transition: transform 0.15s ease;
}

/* -------------------------------------------------------------------------------- Empty state */
.dpx-grid-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 6px;
    padding: 48px 24px;
    margin: 8px;
    background: #f8fafc;
    border: 1px dashed var(--dpx-border);
    border-radius: 12px;
    color: var(--dpx-muted);
}

.dpx-grid-empty-icon {
    width: 56px;
    height: 56px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 14px;
    background: #eff6ff;
    color: var(--dpx-accent);
    margin-bottom: 6px;
}

    .dpx-grid-empty-icon .e-icons {
        font-size: 26px;
    }

.dpx-grid-empty-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    color: #334155;
}

.dpx-grid-empty-text {
    margin: 0;
    max-width: 460px;
    font-size: 0.9rem;
}

/* ------------------------------------------------------------------------------------------------------
   Proposed versus confirmed overlay

   The confirmed value reads normally and the proposal sits beside it, visibly secondary. A suggestion that
   looked like data would be worse than no overlay at all - somebody would read it as the value.
   ------------------------------------------------------------------------------------------------------ */

.dpx-proposal-cell {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.dpx-proposal-confirmed {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Dashed, so it reads as pending rather than settled.

   Both class names are used in the selector so this beats Syncfusion's own .e-badge sizing on specificity
   rather than with !important. e-badge ships a smaller font than the grid cell, which made the proposed value
   read as a footnote beside the confirmed one. The two are alternatives to each other and somebody is being
   asked to choose between them, so they carry the same text size and the dashed border alone marks which is
   pending. */
.e-badge.dpx-proposal-badge {
    cursor: help;
    font-weight: 600;
    white-space: nowrap;
    border: 1px dashed currentColor;
    background: transparent;
    font-size: inherit;
    line-height: inherit;
    height: auto;
    vertical-align: baseline;
}

.dpx-proposal-actions {
    display: inline-flex;
    gap: 2px;
    opacity: 0;
    transition: opacity .12s ease-in-out;
}

/* The buttons appear on hover or keyboard focus. Focus-within matters: hover-only controls are
   unreachable by keyboard, and confirming a proposal is exactly the kind of deliberate action somebody
   may be tabbing to. */
.dpx-proposal-cell:hover .dpx-proposal-actions,
.dpx-proposal-cell:focus-within .dpx-proposal-actions {
    opacity: 1;
}

.dpx-proposal-result {
    white-space: nowrap;
}

/* ============================================================================================
   File Load Wizard
   Syncfusion 19.2 has no SfStepper - it arrives in v20 - so the steps are plain markup. No
   component version to keep in step with, and the whole thing is five list items.
   ============================================================================================ */

.dpx-wizard { width: 100%; max-width: none; }

.dpx-wizard-title { margin: 0 0 16px 0; }

.dpx-steps {
    display: flex;
    list-style: none;
    margin: 0 0 20px 0;
    padding: 0;
    gap: 4px;
}

.dpx-step {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-bottom: 3px solid #d8d8d8;
    color: #7a7a7a;
    font-size: 13px;
}

.dpx-step-marker {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: #d8d8d8;
    color: #fff;
    font-size: 12px;
    flex: 0 0 auto;
}

.dpx-step-current { border-bottom-color: #0d6efd; color: #1b1b1b; font-weight: 600; }
.dpx-step-current .dpx-step-marker { background: #0d6efd; }

.dpx-step-done { border-bottom-color: #198754; color: #3f3f3f; }
.dpx-step-done .dpx-step-marker { background: #198754; }

.dpx-wizard-panel {
    border: 1px solid #e3e3e3;
    border-radius: 4px;
    padding: 18px;
    background: #fff;
}

.dpx-wizard-file { margin-bottom: 14px; }
.dpx-wizard-meta { color: #6d6d6d; font-size: 12px; margin-left: 6px; }
.dpx-wizard-field { margin: 12px 0; max-width: 380px; }
.dpx-wizard-field label { display: block; font-size: 12px; color: #4a4a4a; margin-bottom: 4px; }

.dpx-wizard-results { list-style: none; padding: 0; margin: 8px 0 16px 0; }
.dpx-wizard-results li { padding: 2px 0; }

.dpx-wizard-note { margin-top: 14px; padding: 10px 12px; border-radius: 4px; background: #f1f3f5; color: #333; font-size: 13px; }
.dpx-wizard-good { margin-top: 14px; padding: 10px 12px; border-radius: 4px; background: #e7f6ec; color: #14532d; font-size: 13px; }
.dpx-wizard-bad  { margin-top: 14px; padding: 10px 12px; border-radius: 4px; background: #fdecea; color: #7f1d1d; font-size: 13px; }

/*  The delimiter picker on the Profile step. Wraps rather than shrinks: the hint beside it is a
    sentence, and a sentence squeezed into a narrow column is worse than one on its own line.  */
.flw-delimiter { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 14px 0; }
.flw-delimiter label { font-size: 13px; font-weight: 600; color: #333; }
.flw-delimiter-hint { font-size: 12px; color: #666; flex: 1 1 260px; min-width: 0; }

/*  Amber, not red. One column is a strong hint and not a certainty - a single-column file is legal,
    just rare - so this reads as something to check rather than something that has already failed.  */
.flw-delimiter-warning { margin-top: 12px; padding: 10px 12px; border-radius: 4px; background: #fff8e1; color: #7a4f01; font-size: 13px; }
.flw-delimiter-warning code { background: rgba(0,0,0,.06); padding: 1px 5px; border-radius: 3px; word-break: break-all; }

.dpx-wizard-running {
    margin-top: 16px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    color: #444;
}

.dpx-spinner {
    width: 14px;
    height: 14px;
    border: 2px solid #c9c9c9;
    border-top-color: #0d6efd;
    border-radius: 50%;
    animation: dpx-spin 0.8s linear infinite;
    flex: 0 0 auto;
}

@keyframes dpx-spin { to { transform: rotate(360deg); } }

/* Profile results, shown on the Map step - the column list is what the mapping decision is made from. */
.dpx-wizard-profile { margin: 14px 0; }
.dpx-wizard-profile-head { font-size: 13px; color: #444; margin-bottom: 6px; }

.dpx-profile-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.dpx-profile-table th {
    text-align: left;
    padding: 6px 8px;
    border-bottom: 2px solid #e3e3e3;
    color: #555;
    font-weight: 600;
}
.dpx-profile-table td { padding: 5px 8px; border-bottom: 1px solid #f0f0f0; }
.dpx-profile-table tbody tr:hover { background: #f8f9fa; }

/* Samples are arbitrary client data and can be long; clipped so one wide value cannot stretch the table. */
.dpx-profile-sample {
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #666;
}

/* A mapped column whose values will not fit its target. Marked on the row rather than only in the banner
   above, so the offending column is findable in a long list without counting back from the warning. */
.dpx-profile-overflow { background: #fdecea; }
.dpx-profile-overflow td { color: #7f1d1d; font-weight: 600; }

/* The mapping screen rendered inside the wizard's Map step. Framed and scrollable so a long mapping grid
   cannot push the wizard's own controls off the page - "Done mapping" has to stay reachable. */
.dpx-wizard-mapping {
    margin-top: 14px;
    border: 1px solid #d5d9dd;
    border-radius: 4px;
    overflow: hidden;
}

.dpx-wizard-mapping-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px;
    background: #f1f3f5;
    border-bottom: 1px solid #d5d9dd;
    font-size: 13px;
    position: sticky;
    top: 0;
    z-index: 2;
}

/* The embedded page keeps its own h1; shrunk here so it does not compete with the wizard's title. */
.dpx-wizard-mapping .general-container > h1 { font-size: 18px; margin: 10px 0; }

/* A step the run has reached can be reopened; one it has not is inert and should not invite a click. */
.dpx-step-clickable { cursor: pointer; }
.dpx-step-clickable:hover { background: #f1f3f5; }

/* The embedded mapping grid needs the whole width, not the reading width the wizard's text panels want.
   Bootstrap's col-4 inside it becomes unusably narrow when the container is capped - which is what made the
   mapping tiles too small to read or touch. */
.dpx-wizard-mapping .general-container,
.dpx-wizard-mapping .container,
.dpx-wizard-mapping .container-fluid {
    max-width: none !important;
    width: 100% !important;
    padding-left: 8px;
    padding-right: 8px;
}

/* The mapping panel's own scroll region: tall enough to work in, capped so the wizard controls stay reachable. */
.dpx-wizard-mapping .tableau-container { min-height: 0; }

/* A deactivated rule is still shown - it occupies its slot in the unique key - but muted, because it will
   not load anything. */
.dpx-profile-inactive td { opacity: .55; font-style: italic; }

/* PBI 6791 (APF-12): a row with a change waiting for approval, and the line above the grid that says so. */
.dpx-grid .e-row.dpx-row-pending td:first-child { box-shadow: inset 4px 0 0 #d97706; }
.dpx-grid .e-row.dpx-row-pending { background: rgba(217, 119, 6, 0.06); }
.dpx-pending-banner { margin: 0 0 8px 0; padding: 6px 10px; border-left: 4px solid #d97706; background: #fffbeb; color: #78350f; font-size: 13px; }
.dpx-pending-banner a { margin-left: 8px; }
