﻿@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
@import url('root.css');

html, body {
    font-size: 14px;
    font-family: Calibri, 'Gill Sans', 'Gill Sans MT', 'Trebuchet MS', sans-serif;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: #0071c1;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.icon-primary

.content {
    clear: both;
    padding-top: 1.1rem;
}

.valid.modified {
    outline: none !important;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

/* Put on a dialog's form until its action button has been pressed once. A dialog that opens with
   every empty field already complaining reads as something having gone wrong, when all that has
   happened is that the user has not filled it in yet; and the complaint that matters is the one
   raised by the attempt to save. The EditContext still validates as it always did and the messages
   are rendered - only showing them waits, so nothing about what is or is not valid changes. Once
   the action has been pressed the class comes off and the fields report as the user corrects them. */
.validation-quiet .validation-message {
    display: none;
}

/* The red ring goes with the message. Not display:none - this class sits on the input itself, so
   hiding it would take the field away rather than the outline. */
.validation-quiet .invalid {
    outline: none;
}

/* And Syncfusion's own red, which is a separate thing again: a Syncfusion input reads the
   EditContext directly and puts e-error on its wrapper, which colours the border AND the floating
   label. That is what was left showing - a red box with a red caption and no message to say what
   was wrong, which is worse than the message would have been. The two colours below are
   bootstrap5.css's own non-error values (#ced4da border, #6c757d label), not invented ones, so the
   field reads exactly as an untouched field does. */
.validation-quiet .e-input-group.e-error,
.validation-quiet .e-input-group.e-control-wrapper.e-error,
.validation-quiet .e-input-group.e-error input.e-input,
.validation-quiet .e-input-group.e-control-wrapper.e-error input.e-input,
.validation-quiet .e-input-group.e-error .e-input-group-icon,
.validation-quiet .e-input-group.e-control-wrapper.e-error .e-input-group-icon,
.validation-quiet .e-input.e-error,
.validation-quiet .e-float-input.e-error input,
.validation-quiet .e-float-input.e-control-wrapper.e-error input,
.validation-quiet .e-float-input.e-error textarea,
.validation-quiet .e-float-input.e-control-wrapper.e-error textarea {
    border-color: #ced4da;
}

.validation-quiet .e-float-input.e-error label.e-float-text,
.validation-quiet .e-float-input.e-control-wrapper.e-error label.e-float-text,
.validation-quiet .e-float-input.e-error input:focus ~ label.e-float-text,
.validation-quiet .e-float-input.e-control-wrapper.e-error input:focus ~ label.e-float-text {
    color: #6c757d;
}

.col-hidden {
    visibility: collapse;
}

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 50px;
    /* 1001, not 1000: Syncfusion DashboardLayout panels default to z-index:1000, the same as
       the header. On a tie the later DOM element wins, and <main> follows the header — so the
       panels would paint over the (now overlaying) sidebar that lives inside this header.
       The +1 keeps the sidebar above page content while staying below transient popups/dialogs,
       which Syncfusion stacks higher again. */
    z-index: 1001;
    background-color: var(--primary-dark);
}

/* By default the sidebar is a fixed overlay: expanding it covers the left edge rather than
   pushing the page, so nothing reflows on a normal toggle. When the user PINS the menu
   (body.sidebar-pinned) the content shrinks beside it — an opt-in push/resize mode whose
   margin transition drives a single, smooth dashboard-grid reflow. */
main {
    margin-top: 50px;
    margin-left: 48px;
    transition: margin-left 0.25s ease;
}

body.sidebar-pinned main {
    margin-left: 220px;
}

.logo-main {
    max-width: 128px;
    padding:10px 0px 0px 0px;
    margin-right: 30px;
}

.access-control-wrapper
{
    float: right;
    padding: 5px 5px 0px 0px;
}

.clickable {
    cursor: pointer;
}

.form-control {
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    padding: 1px;
    padding-left: 8px;
    outline: none;
    border: 1px solid var(--primary-mid);
    -webkit-transition: all 0.30s ease-in-out;
    -moz-transition: all 0.30s ease-in-out;
    -ms-transition: all 0.30s ease-in-out;
    -o-transition: all 0.30s ease-in-out;
    height: calc(1.5em + 0.5rem );
}


    .form-control:focus {
        /* box-shadow: 0 0 5px #B0CFE0;*/
        border: 1px solid var(--primary-mid);
    }

.searchButton {
    border: 1px solid var(--primary-mid);
    background: var(--primary-mid);
    text-align: center;
    color: #fff;
    border-radius: 0 5px 5px 0;
    cursor: pointer;
    height: 28px;
    padding-top: 2px;
}

.input-wrapper {
    position: relative;
    margin-top: 18px;
}

.input-wrapper-search {
    margin-top: 5px;
    min-width: 60%;
    float: left;
}


/* CSS for Transaction Page Layouts */
/* Generic flex helpers */
.flex-valign-center {
    display: flex;
    align-items: center; /* vertical centering */
    gap: 12px; /* spacing between items – optional */
}

.flex-col {
    display: flex;
    flex-direction: column;
}

.flex-col-fill {
    display: flex;
    flex-direction: column;
    flex: 1 1 0;
    min-height: 0;
}

.no-grow {
    flex: 0 1 auto;
}

/* List/master-list page header: title on the left, "New" action on the right */
.list-page-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.list-page-header .e-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    white-space: nowrap;
}

.no-grow-no-shrink {
    flex: 0 0 auto
}

.scroll-y {
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
}

.footer-50 {
    flex: 0 0 50px;
}

.height-full-page {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 125px);
}

/* Manage Persons detail panel.

   Two columns that finish level: identity and contact fields on the left, address on the right. The
   address box takes whatever height the left column ends up needing, rather than being pinned to a
   row count that only looks right at one font size. */
.person-detail-col {
    display: flex;
    flex-direction: column;
}

.person-detail-fill {
    flex: 1 1 auto;
    min-height: 0;
}

.person-detail-fill > div {
    display: flex;
    flex-direction: column;
}

.person-detail-fill .e-input-group {
    flex: 1 1 auto;
}

.person-detail-fill textarea.e-input {
    height: 100%;
    resize: none;
}

.person-detail-sep {
    margin: 0.4rem 0 0.7rem;
    opacity: 0.35;
}

.height-45 {
    flex: 0 0 45%;
    min-height: 0;
    height: 45%;
}
.height-50 {
    flex: 0 0 50%;
    min-height: 0;
    height: 45%;
}

.height-even-split{
    flex: 1 1 0;
    min-height: 0;
}

.two-panel-main-area {
    display: flex;
    flex: 1 1 0;
    min-height: 0;
    gap: 2rem;
}

.left-panel-33{
    display: flex;
    flex-direction: column;
    flex: 0 0 33.33%;
    overflow: hidden;
}

.left-panel-66 {
    display: flex;
    flex-direction: column;
    flex: 0 0 66.67%;
    overflow: hidden;
}
.left-panel-50 {
    display: flex;
    flex-direction: column;
    flex: 0 0 50%;
    overflow: hidden;
}
.left-panel-80 {
    display: flex;
    flex-direction: column;
    flex: 0 0 80%;
    overflow: hidden;
}

.right-panel-fill {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.flex-row-mb-2 {
    display: flex;
    align-items: center;
    width: 100%;
    margin-bottom: 0.5rem; /* same as Bootstrap mb-2 */
}

    .flex-row-mb-2 > :last-child {
        margin-left: auto; /* push right */
    }

/* Keep table columns aligned when you split header/body */
.table-fixed {
    table-layout: fixed;
}

/* Right-align an SfNumericTextBox (e.g. money fields). Syncfusion puts CssClass on the
   wrapper but the value lives in the inner <input class="e-numerictextbox">, so target that. */
.num-right input,
input.num-right.e-numerictextbox {
    text-align: right;
    padding-right: 8px !important;
}

/* Syncfusion Tab: make the content area fill and allow shrinking */
.tab-shell {
    display: flex;
    flex-direction: column;
    flex: 1 1 0;
    min-height: 0;
}

    .tab-shell .e-tab {
        display: flex;
        flex-direction: column;
        flex: 1 1 0;
        min-height: 0;
    }

        .tab-shell .e-tab .e-tab-header {
            flex: 0 0 auto;
        }

        .tab-shell .e-tab .e-content {
            display: flex;
            flex-direction: column;
            flex: 1 1 0;
            min-height: 0;
        }
            /* only the active pane should be flex (inactive remain display:none) */
            .tab-shell .e-tab .e-content .e-item {
                flex: 1 1 0;
                min-height: 0;
            }

                .tab-shell .e-tab .e-content .e-item.e-active {
                    display: flex;
                    flex-direction: column;
                }
/*Dashboard Grid formatiing*/
    .panel-fill {
        height: 100%;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }
    .grid-fill{


        height: 100%;
        min-height: 0;
    }

/* Asset register rows coloured by what the schedule needs: red where a
   requirement is past due, amber where one is inside its notice window.

   Applied to .e-rowcell rather than the row, because Syncfusion sets the colour
   on the cells; a rule on the row alone loses to it. Selection still paints its
   own background, so a coloured row stays visible when picked. */
/* !important, deliberately. The theme sets cell colour separately for normal,
   alternate, hover and selected rows, so out-specifying every one of them is a
   losing game — and a status colour should hold in all of them anyway. */
.e-grid tr.asset-overdue td.e-rowcell {
    color: var(--warning) !important;
    font-weight: 500;
}

.e-grid tr.asset-due-now td.e-rowcell {
    color: var(--amber) !important;
    font-weight: 500;
}

/* A field that does not apply to this kind of line at all — On Order and Allocated on a service
   line, where there is nothing outstanding and nothing to allocate. Reads "n/a" rather than 0,
   because 0 is a figure and this is the absence of one. Centred and muted so the eye skips it. */
.e-input-group.not-applicable input,
input.not-applicable {
    text-align: center;
    font-style: italic;
    opacity: 0.55;
}

/* A partner's activity where the stock went back the way it came — a Sales Return
   on the customer side, a supplier-return adjustment on the purchase side. The
   reference prefix already says which it is; the colour is reinforcement, never
   the only signal, so nothing is lost if it is not perceived. Same cell-level
   rule and !important as the two above, for the same reason. */
.e-grid tr.reverse-movement td.e-rowcell {
    color: var(--steel-blue) !important;
    font-weight: 500;
}

/* Activity record editor: readings, equipment and notes on tabs so the dialog
   reads as three short tables rather than one long form. The bodies scroll —
   these lists run to a handful of rows, so paging would be ceremony. */
/* Fixed, not max — the dialog keeps one height whichever tab is open and however
   many rows it holds, instead of resizing as the record fills up. Sized for four
   line items plus the header, which covers most requirements without scrolling. */
.record-editor-tabs .record-tab-body {
    height: 232px;
    overflow-y: auto;
    padding: 8px 4px;
}

    .record-editor-tabs .record-tab-body table {
        margin-bottom: 0;
    }

/* The readings on a record. Cells sit on the bottom of the row rather than the middle: a field
   carrying a label — "As found", "As left" — is taller than the plain ones beside it, so centring
   left a mixed specification with its inputs at three or four different heights. Bottom-aligning
   puts every input on one line whatever sits above it. */
.readings-table td {
    vertical-align: bottom;
}

/* The kind heading between groups is a label, not a row of inputs, so it keeps to the top. */
.readings-table tr.reading-kind-row td {
    vertical-align: top;
}

/* The note belongs to the reading above it, so it is tucked under that row rather than reading as
   a line of its own: no top border, and inset from the left so the eye follows the indent back. */
.readings-table tr.reading-note-row td {
    border-top: 0;
    padding-top: 0;
    padding-left: 28px;
}

/* The specification, inside the requirement's own dialog. Same reasoning as the record editor's
   tab body: fixed rather than max, so the dialog keeps one height whatever the point count is —
   a calibration specification runs long, and a dialog that grows with it ends up taller than the
   screen. */
.task-points-body {
    height: 260px;
    overflow-y: auto;
}

/* The table inside a grid's expanded row.

   Both detail panels — a requirement's actions and a record's readings — use this, because they
   were visibly different things doing the same job: one was a Syncfusion grid nested inside a grid
   row, the other a bootstrap table with a heavy underlined header. Neither read as part of the row
   it belonged to.

   Restrained on purpose: no outer border, a quiet header, and the whole thing indented so it reads
   as the detail of the row above rather than as a second table competing with it. */
.detail-subtable {
    margin: 0;
    background: transparent;
}

    .detail-subtable > thead > tr > th {
        border-top: 0;
        border-bottom: 1px solid rgba(0, 0, 0, 0.08);
        font-size: 0.75rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.04em;
        color: #6c757d;
        padding: 4px 8px;
        background: transparent;
    }

    .detail-subtable > tbody > tr > td {
        border-top: 0;
        border-bottom: 1px solid rgba(0, 0, 0, 0.04);
        padding: 5px 8px;
        vertical-align: middle;
    }

    .detail-subtable > tbody > tr:last-child > td {
        border-bottom: 0;
    }

.detail-subtable-empty {
    padding: 6px 8px;
    font-size: 0.85rem;
}

/* Matches the height of the inputs beside it, so the verdict sits on the same
   line as the readings it describes rather than floating above them. */
.result-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 52px;
    height: 32px;
    font-size: 0.75rem;
    letter-spacing: 0.02em;
}

/* Grid row-action icons.

   Global, not component-scoped. These began life in RowActions.razor.css, which
   meant Blazor's CSS isolation applied them only inside that one component —
   every other grid using the same class names got no flex, no centring and no
   icon sizing, which is why their action columns rendered left-aligned and
   inconsistently sized. Defined here once so any grid can use them. */
.row-action-icons {
    display: flex;
    gap: 6px;
    justify-content: center;
    align-items: center;
}

.icon-btn {
    width: 18px;
    height: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    text-decoration: none;
    color: var(--primary-dark);
}

    .icon-btn:hover {
        color: var(--primary-mid);
    }


/* The add/remove icons are plain <img> and had no styling at all, so they drew
   at the SVG's intrinsic size and sat wherever the cell put them. */
.line-item-add,
.line-item-remove {
    width: 18px;
    height: 18px;
    cursor: pointer;
    vertical-align: middle;
}

/* Host for a percentage-height SfGrid inside a flex column.
   Constrains the grid box at CSS-layout time so it never paints at full
   content height before Syncfusion's post-render JS applies the scrollbar.
   overflow:hidden clips the rows that briefly spill before Syncfusion sizes
   the inner .e-content scroller, preventing the page-height flash. */
.grid-host {
    position: relative;
    overflow: hidden;
}

    .grid-host > .e-grid {
        position: absolute;
        inset: 0;
        overflow: hidden;
    }

/* This is the scrolling viewport */
.scroll-table {
    height: 100%; /* or a fixed height like 400px */
    overflow: auto;
}
    .scroll-table table {
        border-collapse: separate;
        border-spacing: 0;
    }

    /* Sticky header cells */
    .scroll-table thead th {
        position: sticky;
        top: 0;
        z-index: 5; /* keep above body rows */
        background: #fff; /* IMPORTANT so rows don't show through */

        box-shadow: 
            inset 0 -1px 0 #dee2e6, /* bottom */
    }

    /* Optional: if your header row has background/border styling */
    .scroll-table thead tr {
        position: relative;
        z-index: 6;
    }

/* ============================================================
   Custom Syncfusion Styles
   ============================================================ */
/* Grid Highlight filter icon */
.e-grid .e-filtered::before {
    color: #1b6ec2;
    font-size: large;
}

/* Disabled Button and Checkbox Styles*/

/* unchecked + disabled (frame) */
/*.e-checkbox-wrapper .e-checkbox:disabled + .e-frame {
    border-color: var(--primary-mid) !important;
    background: transparent !important;
    opacity: 1 !important;
}*/

    /* checked + disabled (frame) */
    .e-checkbox-wrapper .e-checkbox:disabled + .e-frame.e-check {
        background-color: var(--primary-mid) !important;
        border-color: var(--primary-mid) !important;
        color: #fff !important; /* tick color uses "color" */
        opacity: 1 !important;
    }

}

/* Half greyed output multiselect fix */



/* buttons to match theme */

button.e-btn.e-primary-custom {
    background-color: var(--primary-dark) !important;
    color: var(--white) !important;
    border: 1px solid var(--primary-dark) !important;
}

    button.e-btn.e-primary-custom:hover {
        background-color: var(--accent-dark) !important;
        border-color: var(--accent-dark) !important;
        color: var(--white) !important;
    }
.e-btn.e-outline-primary {
    background-color: transparent !important;
    color: var(--primary-dark) !important;
    border: 1px solid var(--primary-dark) !important;
}

    .e-btn.e-outline-primary:hover {
        background-color: var(--primary-mid) !important; /* matches your --primary-mid */
        color: var(--white) !important;
    }

/* Lucide glyphs for Syncfusion button icons (IconCss="licon-..."). Rendered via CSS mask so they
   inherit the button's text colour (white on primary, dark on default), matching the LucideIcon SVGs
   used elsewhere (DocumentRecords row actions, grid RowActions, sidebar). */
.e-btn .e-btn-icon[class*="licon-"] {
    display: inline-block;
    width: 16px;
    height: 16px;
    vertical-align: middle;
    background-color: currentColor;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: 16px 16px;
    mask-size: 16px 16px;
}

/* Breathing room between the glyph and the button label */
.e-btn .e-btn-icon.e-icon-left[class*="licon-"] {
    margin-right: 8px;
}

.e-btn .e-btn-icon.e-icon-right[class*="licon-"] {
    margin-left: 8px;
}

.e-btn .e-btn-icon.licon-save {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z'/%3E%3Cpath d='M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7'/%3E%3Cpath d='M7 3v4a1 1 0 0 0 1 1h7'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z'/%3E%3Cpath d='M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7'/%3E%3Cpath d='M7 3v4a1 1 0 0 0 1 1h7'/%3E%3C/svg%3E");
}

.e-btn .e-btn-icon.licon-printer {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6'/%3E%3Crect x='6' y='14' width='12' height='8' rx='1'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2'/%3E%3Cpath d='M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6'/%3E%3Crect x='6' y='14' width='12' height='8' rx='1'/%3E%3C/svg%3E");
}

/* Sign-off: the act that closes a record and issues its certificate. */
.e-btn .e-btn-icon.licon-lock {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2'/%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'/%3E%3C/svg%3E");
}

/* Action buttons that search rather than save — the action bars pick this from the caption. */
.e-btn .e-btn-icon.licon-search {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
}

/* Raise Adjustments on the stock-check review: the sliders the sidebar and Quick Links give
   Adjustments (LucideIcon "sliders-horizontal"). */
.e-btn .e-btn-icon.licon-sliders-horizontal {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 5H3'/%3E%3Cpath d='M12 19H3'/%3E%3Cpath d='M14 3v4'/%3E%3Cpath d='M16 17v4'/%3E%3Cpath d='M21 12h-9'/%3E%3Cpath d='M21 19h-5'/%3E%3Cpath d='M21 5h-7'/%3E%3Cpath d='M8 10v4'/%3E%3Cpath d='M8 12H3'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10 5H3'/%3E%3Cpath d='M12 19H3'/%3E%3Cpath d='M14 3v4'/%3E%3Cpath d='M16 17v4'/%3E%3Cpath d='M21 12h-9'/%3E%3Cpath d='M21 19h-5'/%3E%3Cpath d='M21 5h-7'/%3E%3Cpath d='M8 10v4'/%3E%3Cpath d='M8 12H3'/%3E%3C/svg%3E");
}

.e-btn .e-btn-icon.licon-x {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E");
}

.e-btn .e-btn-icon.licon-external-link {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 3h6v6'/%3E%3Cpath d='M10 14 21 3'/%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 3h6v6'/%3E%3Cpath d='M10 14 21 3'/%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'/%3E%3C/svg%3E");
}

.e-btn .e-btn-icon.licon-arrow-right {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3Cpath d='m12 5 7 7-7 7'/%3E%3C/svg%3E");
}

/* File picker (InputFile "Choose file") button — outline primary to match theme */

.custom-file-upload {
    font: inherit;
    color: var(--primary-dark);
}

.custom-file-upload::file-selector-button {
    background-color: transparent;
    color: var(--primary-dark);
    border: 1px solid var(--primary-dark);
    border-radius: 4px;
    padding: 4px 14px;
    margin-right: 12px;
    cursor: pointer;
    font: inherit;
    transition: background-color .15s ease, color .15s ease;
}

    .custom-file-upload::file-selector-button:hover {
        background-color: var(--primary-mid);
        color: var(--white);
    }

/* Older WebKit/Blink fallback for the same native file-input button */
.custom-file-upload::-webkit-file-upload-button {
    background-color: transparent;
    color: var(--primary-dark);
    border: 1px solid var(--primary-dark);
    border-radius: 4px;
    padding: 4px 14px;
    margin-right: 12px;
    cursor: pointer;
    font: inherit;
}

/*line items*/

.clickable{
    cursor: pointer;
}

.line-item-removing {
    pointer-events: none;
    opacity: 0.4;
}

/* ---- A spinner that masks the page, not just its own corner of it ----

   Syncfusion's spinner pane is position:absolute at 100% of its offset parent, so what it covers
   depends entirely on where the SfSpinner happens to sit in the markup. Ops-Stock puts its spinners
   in a bare div near the top of the page, which resolves to the body and masks the viewport; the
   asset pages put theirs inside flex columns and dialogs, so the mask covered only that container
   and the rest of the page went on taking clicks while the server was answering.

   Fixed to the viewport instead, so it does not matter what encloses it. !important because the
   theme's own .e-spinner-pane rule is equally specific and would otherwise win on source order. */
.spinner-full-page.e-spinner-pane,
.spinner-full-page .e-spinner-pane {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    width: 100vw !important;
    height: 100vh !important;
}
