﻿html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* ============================================================================
   Accessibility: WCAG 2.1 AA (contrast, non-text contrast, focus visible)
   See docs/UIStyleGuide.md §15. Ratios are measured against the RESOLVED Kendo
   Default Ocean Blue v15 swatch, not the hex fallbacks in this file. app.css
   loads after the theme, so these :root tokens win over the theme's own.
   ============================================================================ */
:root {
    /* --- Kendo token overrides (the theme is the cause) --- */
    --kendo-color-subtle: #595959;              /* was #666: 3.80 on selected alt grid rows -> 4.64 */
    --kendo-color-warning-on-surface: #8F5A00;  /* was #B87D00: 3.52 on white -> 5.00 */
    --kendo-color-on-warning: #1F1F1F;          /* was white: 2.03 on #F5A601 -> 8.11 (solid warning buttons) */

    /* --- CartCARE accessibility tokens --- */
    --cc-focus-ring: #0E5781;                   /* = primary-on-surface; 7.78 on white, >= 5.5 on every light ground */
    --cc-focus-ring-inverse: #FFFFFF;           /* on a solid primary/selected fill (5.10 vs #1274AC) */
    --cc-focus-width: 2px;
    --cc-control-border: #8C8C8C;               /* 3.36 on white: SC 1.4.11 boundary for inputs/checkbox/radio/switch */
    --cc-link: #0A58CA;                         /* 5.96 on the darkest light row (#F6F6F6) */
    --cc-text-muted: #5C636A;                   /* 5.64 on grid alt rows; use for muted text inside grids */
}

/* Kendo utility classes that read the RAW warning token (2.03:1) */
.k-text-warning,
.k-color-warning {
    color: var(--kendo-color-warning-on-surface) !important;
}

/* Kendo utility classes that read the RAW secondary token (oklch 56% gray, #777: 4.48:1 on white, less
   on alternate and selected rows). The token itself stays: it also fills secondary buttons. Used as
   muted text in ~19 components (BarcodeLayoutDialog's "14 (fixed)", ...), so it follows the subtle
   token, including its darker value inside selected rows. */
.k-text-secondary,
.k-color-secondary {
    color: var(--kendo-color-subtle) !important;
}

/* Bootstrap 5.1 link + muted text (fail on #FAFAFA / alt grid rows) */
a,
.btn-link {
    color: var(--cc-link);
}

.text-muted {
    color: var(--cc-text-muted) !important;
}

/* Selected grid/tree rows are tinted with 25% primary (#C4DDEB on a plain row, down to #B4CCDB on a
   hovered alternate row), where the muted tokens above fall to 4.2:1 (#595959) and 3.7:1 (#5C636A).
   Darken the TOKENS inside a selected row rather than repainting the row: everything muted (.text-muted,
   --kendo-color-subtle, the hint classes that read them) follows, and the selection keeps Kendo's tint.
   #404040 is 6.2:1 and #41464B 5.7:1 on the darkest selected ground (#B4CCDB). */
.k-table-row.k-selected,
.k-table-td.k-selected,
.k-grid-stack-cell.k-selected {
    --kendo-color-subtle: #404040;
    --cc-text-muted: #41464B;
}

/* A row's own actions menu, hidden while that row is open for inline editing so only Save and Cancel
   show. Telerik marks the open row with .k-grid-edit-row. AccountProductsPage and TemplateCreateGrid
   still carry their own copies of this rule in their inline <style>. */
.k-grid .k-grid-edit-row .hide-when-editing {
    display: none;
}

/* A link inside running text must not rely on color alone (axe link-in-text-block).
   Drawer links and button-styled links are standalone and keep their own look. */
:is(p, li, dd, td, .k-form-hint, .k-notification-content) a:not(.k-button):not([class*="btn"]):not(.k-drawer-link) {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* --- SC 1.4.11: control boundaries ---------------------------------------
   Re-point the border TOKEN on the control itself rather than setting
   border-color, so Kendo's own :checked / .k-invalid / .k-focus colors (which
   use other tokens) still win. Children are reset so the picker's inner
   button separator keeps its hairline. */
:where(.k-input, .k-picker, .k-checkbox, .k-radio, .k-switch-track, .k-switch-thumb) {
    --kendo-color-border: var(--cc-control-border);
}

:where(.k-input, .k-picker) * {
    --kendo-color-border: oklch(0% 0 0deg / 0.08);
}

/* --- SC 2.4.7 / 1.4.11: one focus indicator for the whole app -------------
   2px solid #0E5781 with a 2px gap: the gap shows the page ground, so the
   ring never needs to contrast with the button fill itself. !important is
   deliberate: the Kendo theme (.k-button:focus{outline:0}, .k-link{outline:0})
   and ~20 scoped component rules (with the [b-xxxx] attribute, so higher
   specificity) set outline:none, and this has to beat all of them for
   keyboard focus only. :focus-visible keeps mouse clicks ring-free.
   Do not add outline:none anywhere without a replacement focus style. */
:is(a[href], button, summary, select, textarea,
    input:not(.k-input-inner),
    [tabindex]:not([tabindex="-1"]),
    [role="button"], [role="link"], [role="tab"], [role="menuitem"], [role="option"],
    [role="treeitem"], [role="switch"], [role="checkbox"], [role="radio"], [role="gridcell"],
    .k-button, .k-chip, .k-link, .k-menu-link, .k-switch, .k-checkbox, .k-radio,
    .k-drawer-item, .k-tabstrip-item, .k-table-td, .k-table-th, .k-pager-nav,
    .k-calendar-td, .k-listgroup-item):focus-visible {
    outline: var(--cc-focus-width) solid var(--cc-focus-ring) !important;
    outline-offset: 2px !important;
}

/* Cells and list-like items sit inside a clipping container (overflow:auto
   grids, drawers, tab strips): draw the ring INSIDE so it is not cut off. */
:is(.k-table-td, .k-table-th, .k-drawer-item, .k-drawer-link, .k-tabstrip-item, .k-calendar-td,
    .k-listgroup-item, [role="gridcell"], [role="treeitem"], [role="option"],
    .k-menu-link, .k-panelbar .k-link):focus-visible {
    outline-offset: -2px !important;
}

/* Kendo moves a CLASS, not DOM focus, for the active option in popups
   (DropDownList, ComboBox, MultiSelect, AutoComplete: focus stays in the
   input via aria-activedescendant) and for TreeView/TreeList nodes. */
.k-list-item.k-focus,
.k-treeview-leaf.k-focus,
.k-table-row.k-focus > .k-table-td,
.k-table-td.k-focus {
    box-shadow: inset 0 0 0 var(--cc-focus-width) var(--cc-focus-ring) !important;
}

/* Text inputs and pickers: the real <input> is borderless inside a styled
   wrapper, so ring the WRAPPER. This also shows on mouse focus, which is the
   platform convention for text fields. */
.k-input:focus-within,
.k-input.k-focus,
.k-picker:focus-within,
.k-picker.k-focus,
.cp-box:focus-within {
    outline: var(--cc-focus-width) solid var(--cc-focus-ring) !important;
    outline-offset: 1px !important;
}

/* Solid fills where the inset ring would sit on primary: invert it. */
.k-drawer-item.k-selected:focus-visible,
.k-drawer-item.k-selected.k-focus,
.k-drawer-item.k-selected .k-drawer-link:focus-visible,
.k-list-item.k-selected.k-focus {
    outline-color: var(--cc-focus-ring-inverse) !important;
    box-shadow: inset 0 0 0 var(--cc-focus-width) var(--cc-focus-ring-inverse) !important;
}

/* Windows High Contrast / forced colors: let the system color draw it. */
@media (forced-colors: active) {
    :focus-visible {
        outline-color: Highlight !important;
    }
}

/* --- SC 2.4.1: skip link (MainLayout). Off screen until it has focus. --- */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 30000;
    padding: 8px 12px;
    background: #fff;
    color: var(--cc-link);
    font-weight: 600;
    text-decoration: underline;
    border-radius: 4px;
}

.skip-link:focus {
    left: 8px;
    top: 8px;
}

/* The drawer links (MainLayout) fill their item and keep the item's look. */
.k-drawer-link,
.k-drawer-link:hover {
    color: inherit;
    text-decoration: none;
}

html, body, .page {
    height: 100%;
    max-height: 100%;
    width: 100%
}

/* The page h1 is FocusOnNavigate's target (Routes.razor): Blazor gives it tabindex="-1" and focuses it after every
   navigation. That focus is programmatic and not operable, so it draws no ring. Anything a user can Tab to does. */
h1[tabindex="-1"]:focus {
    outline: none;
}

.page-container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
}

.page-grid-container {
    flex: 1;
    min-height: 0;
    overflow-y: hidden;
    overflow-x: auto;
}

.content > .container-fluid {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.page-container-xl {
    width: 100%;
    max-width: 1600px;
    margin: 0 auto;
}

.page-container-md {
    width: 100%;
    max-width: 992px;
    margin: 0 auto;
}

.page-container-sm {
    width: 100%;
    max-width: 768px;
    margin: 0 auto;
}

.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."
}

.validation-message {
    color: #d51923;
    margin-top: 0.25rem;
    display: flex;
    font-size: 12px;
    font-style: italic;
}

.k-label.k-form-label {
    margin-bottom: 0.25rem;
}

.k-form-label + .validation-message {
    margin-top: 0;
    margin-bottom: 0.25rem;
}

/* SC 1.4.11: 3.36:1 boundary (was rgba(0,0,0,.2), 1.61:1). .k-checkbox:checked is more specific and keeps primary. */
.k-checkbox {
    border-color: var(--cc-control-border);
}

/* Telerik modal stacking: leave the wrapper's z-index alone.
   Telerik gives every modal it opens (TelerikDialog, a modal TelerikWindow such as a Grid popup editor, and the
   DialogFactory alerts and confirms) a z-index above the last one, as an inline style on its .k-dialog-wrapper,
   so whatever opened last is on top. A global `.k-dialog-wrapper { z-index: 20002 !important }` used to sit here
   to lift every dialog over the Drawer and TelerikLoaderContainer (20000). It overrode that inline style,
   flattened every modal to one value and left the order to DOM position, so an alert could open BEHIND the
   dialog that raised it. Raise nothing here, and never add a per-dialog z-index to work around it (the error
   window over the phone drawer, below, is the one exception).
   The Drawer takes a z-index only in OVERLAY mode (phones, Kendo's 11000), where it stays above a dialog; in
   push mode (desktop) dialogs cover it. Left as is on purpose: nothing a user does opens a dialog while the phone
   drawer is open, only an error raised in the background could, and the error window is lifted for that below.
   If more is needed, lower the drawer and its own backdrop (.k-drawer-overlay > .k-overlay) together, or the
   drawer sinks under its own dimming.
   Inside a wrapper, leave the backdrop (.k-overlay) and the dialog at Telerik's own values too, which already put
   the dialog on top. Pinning the dialog low means pinning the backdrop lower, or the dialog sits under its own
   dimming and can't be clicked. */

/* The ONE exception to leaving wrappers alone: the error window (ErrorDialogHost) is raised in the background and
   can open while the phone's overlay drawer (11000) is expanded, where it would sit behind the drawer and could
   not be dismissed. Lifted only in that state, so everywhere else Telerik's own order still decides. */
body:has(.k-drawer-overlay.k-drawer-expanded) .k-dialog-wrapper:has(.cartcare-error-window) {
    z-index: 11001 !important;
}

/* TelerikLoaderContainer: under Telerik's modal range (backdrop 10000, wrappers 10001 and up), so a page loader
   shown while a dialog is open (a reload run from inside the dialog, an alert raised mid-load) stays behind it.
   Kendo's own 20000 put page loaders over dialogs once the wrapper rule above was gone. Still over everything a
   page draws itself: fixed action bars (1500) and most hand-built modals (1000-2000). A loader INSIDE a dialog is
   confined to that dialog's wrapper, so this value never changes how it stacks. */
.k-loader-container {
    z-index: 9000;
}

/* The icon sits in a flex row beside an item name; pin it so a long name wraps instead of squeezing the button
   (docs/UIStyleGuide.md §12, "Pin the flex children"). */
.product-photo-btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
}

    .product-photo-btn .k-button {
        padding: 2px;
        /* Lighthouse target-size: a small icon button is about 22px; 24px is the floor. */
        min-width: 24px;
        min-height: 24px;
    }

/* Name + icon on one line inside a grid cell or card. */
.product-name-with-photo {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    max-width: 100%;
}

/* Fixed 4:3 stage so the dialog does not jump in size as the photo arrives or fails. */
.product-photo-viewer__stage {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    max-height: 70vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--kendo-color-surface-alt, #f8f9fa);
    border-radius: 4px;
    overflow: hidden;
}

.product-photo-viewer__img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

    /* Hidden, not removed, while loading: the load/error events still have to fire. */
    .product-photo-viewer__img.is-loading {
        opacity: 0;
        position: absolute;
    }

.product-photo-viewer__loading {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.product-photo-viewer__error {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    color: var(--kendo-color-subtle, #5c6670);
}

/* Manage dialog (ProductPhotoDialog). */
.product-photo-dialog .product-photo-dialog__preview {
    aspect-ratio: 4 / 3;
    max-height: 240px;
}

/* "Photo requirements" panel, shown above the Choose/Replace button so the limits are read before a file is picked
   (ProductPhotoRequirements). Kendo info tokens with hex fallbacks, docs/UIStyleGuide.md §1. */
.product-photo-requirements {
    margin: 12px 0 0;
    padding: 0.6rem 0.9rem;
    border-left: 3px solid var(--kendo-color-info, #0058e9);
    border-radius: 2px;
    background: var(--kendo-color-info-subtle, #e5eefd);
    color: var(--kendo-color-info-on-subtle, #003494);
    font-size: 0.9rem;
}

.product-photo-requirements__title {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 6px;
    font-size: 0.95rem;
    font-weight: 600;
}

.product-photo-requirements__list {
    display: grid;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
}

    .product-photo-requirements__list li {
        display: flex;
        align-items: flex-start;
        gap: 6px;
    }

.product-photo-requirements__check {
    flex: 0 0 auto;
    margin-top: 2px;
}

.product-photo-requirements__label {
    font-weight: 600;
}

.product-photo-dialog .product-photo-dialog__phi {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 8px 0 0;
}

    .product-photo-dialog .product-photo-dialog__phi .k-svg-icon {
        flex: 0 0 auto;
        margin-top: 2px;
    }

.product-photo-dialog .product-photo-dialog__empty {
    color: var(--kendo-color-subtle, #5c6670);
}

.product-photo-dialog .product-photo-dialog__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}

.product-photo-dialog .product-photo-dialog__hint {
    margin: 8px 0 0;
    font-size: .85rem;
    color: var(--kendo-color-subtle, #5c6670);
}

.product-photo-status {
    display: block;
    margin-top: 8px;
    font-size: .9rem;
}

.product-photo-status--ok {
    color: var(--kendo-color-success-on-subtle, #1b5e20);
}

.product-photo-status--error {
    color: var(--kendo-color-error-on-subtle, #9b1c1c);
}

/*.k-card:not(*/
/*.k-card-primary,*/
/*.k-card-secondary,*/
/*.k-card-tertiary,*/
/*.k-card-success,*/
/*.k-card-info,*/
/*.k-card-warning,*/
/*.k-card-error,*/
/*.k-card-dark,*/
/*.k-card-light,*/
/*.k-card-inverse) {*/
/*    border-color: #e0f2fe;*/

/*    & .k-card-header {*/
/*        border-color: #e0f2fe;*/
/*        background-color: #f0f9ff;*/

/*        & .k-card-title {*/
/*            font-weight: 500;*/
/*        }*/
/*    }*/
/*}*/

.dashboard-tile {
    /*background-color: #f8fafc;*/
    background-color: #fff;
    border-radius: 0.5rem;
    border: 1px solid #e2e8f0;
    padding: 1.25rem 1rem;
    margin-bottom: 0;
    position: relative;
    width: 100%;
    height: 100%;

    .dashboard-tile-description {
        font-size: 0.875rem;
        line-height: 1.25rem;
        font-weight: 500;
        margin: 0;
        color: #2A70B8;
    }
}

.dashboard-tile-value {
    font-size: 1.875rem;
    line-height: 2.25rem;
    font-weight: 500;
    letter-spacing: -0.025em;
    margin: 0 !important;
    color: #111827;
}

.dashboard-tile-subtext {
    font-size: 0.875rem;
    line-height: 1.25rem;
    margin: 0 !important;
    color: #4B5563;
}

@media (min-width: 768px) {
    .dashboard-tile {
        padding: 1.25rem;
    }
}

/* Dashboard tile counts. #2A70B8 is 5.11:1 (the old #6DA7DA was 2.56:1); standalone links, so no underline at rest. */
.custom-link {
    color: #2A70B8 !important;
    text-decoration: none !important;
    cursor: pointer !important;

    &:hover {
        color: #1D5A96 !important;
        text-decoration: underline !important;
    }
}

.quick-grid-striped tr:nth-child(even) {
    background: rgba(0, 0, 0, 0.05)
}

.k-validation-summary > ul {
    margin-bottom: 0;
}

.scroll-shadows {
    overflow: auto;
    background-image: linear-gradient(to top, white, white),
        linear-gradient(to top, white, white),
        linear-gradient(to top, rgba(0, 0, 0, 0.25), rgba(255, 255, 255, 0)),
        linear-gradient(to bottom, rgba(0, 0, 0, 0.25), rgba(255, 255, 255, 0));
    background-position: bottom center, top center, bottom center, top center;
    background-color: white;
    background-repeat: no-repeat;
    background-size: 100% 10px, 100% 10px, 100% 5px, 100% 5px;
    background-attachment: local, local, scroll, scroll;
}

/* STATS TILE */
.stat-tile-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.75rem;
}

.stat-tile {
display: flex;
flex-wrap: wrap;
align-items: baseline;
justify-content: space-between;
/*row-gap: .25rem;*/
column-gap: .5rem;
border-radius: .25rem;
padding: 0.625rem 0.875rem;
background-color: #fff;
border: 1px solid #e9ecef;
overflow: hidden;

& .stat-title {
    font-size: 0.875rem;
    font-weight: 500;
    margin-bottom: 0;
    color: #6b7280;
}

    & .stat-subtitle {
        font-size: 1rem;
        font-weight: 500;
        margin-bottom: 0;
        color: #374151;
    }

    & .stat-value {
        width: 100%;
        font-size: 1.5rem;
        font-weight: 600;
        margin-bottom: 0;
        color: #111827;
    }
}

/* Status palette shared by Dashboard stat tiles and status TelerikCards
   (cart menu, inspections). One source of truth for each status color. */
.stat-tile.stat-tile-success,
.k-card.card-status-success {
    background-color: #f0fdf4;
    border-color: #bbf7d0;

    & .stat-title {
        color: #15803d;
    }

    & .stat-subtitle {
        color: #166534;
    }

    & .stat-value {
        color: #14532d;
    }
}

.stat-tile.stat-tile-warning,
.k-card.card-status-warning {
    background-color: #fefce8;
    border-color: #fef08a;

    & .stat-title {
        color: #a16207;
    }

    & .stat-subtitle {
        color: #854d0e;
    }

    & .stat-value {
        color: #713f12;
    }
}

.stat-tile.stat-tile-danger,
.k-card.card-status-danger {
    background-color: #fef2f2;
    border-color: #fecaca;

    & .stat-title {
        color: #b91c1c;
    }

    & .stat-subtitle {
        color: #991b1b;
    }

    & .stat-value {
        color: #7f1d1d;
    }
}

/* Info/primary status — no stat-tile equivalent; mirrors the palette above for
   informational TelerikCards (e.g. Cart Information). */
.k-card.card-status-info {
    background-color: #eff6ff;
    border-color: #bfdbfe;
}

@media (min-width: 576px) {
    .stat-tile-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 768px) {
    .stat-tile-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (min-width: 992px) {
    .stat-tile-grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

@media (min-width: 1200px) {
    .stat-tile-grid {
        grid-template-columns: repeat(6, 1fr);
    }
}

.rotate-90-cw {
    transform: rotate(90deg);
}

.no-bottom-margin {
    margin-bottom: 0 !important;
}


/* Restock page */

/* "The template changed while this restock was open" notice on /admin/restocks.
   Explains why a restock's item list legitimately doesn't match its template: the list is built once,
   when the restock opens, and never rebuilt. Uses the Kendo warning tokens (with hex fallbacks) rather
   than a hard-coded palette — see docs/UIStyleGuide.md §1. */
.note-template-drift {
    border-left: 3px solid var(--kendo-color-warning, #ff9800);
    background: var(--kendo-color-warning-subtle, #fff3e0);
    color: var(--kendo-color-warning-on-subtle, #8a5000);
    padding: 0.6rem 0.9rem;
    margin: 0 0 1rem;
    font-size: 0.9rem;
    border-radius: 2px;
}

    .note-template-drift ul {
        margin: 0.35rem 0 0;
        padding-left: 1.2rem;
    }

    .note-template-drift li + li {
        margin-top: 0.25rem;
    }

/* The green "nothing is wrong here" empty state on the ops-console pages
   (/containers-behind-template, /templates/scheduled). An empty grid would read as "no data / something
   is broken"; this says the system is healthy and explains the normal transient case. Kind-neutral name
   because both pages share it. Token colors per docs/UIStyleGuide.md §1. */
.note-all-current {
    border-left: 3px solid var(--kendo-color-success, #37b400);
    background: var(--kendo-color-success-subtle, #e8f5e9);
    color: var(--kendo-color-success-on-subtle, #1b5e20);
    padding: 0.6rem 0.9rem;
    margin: 0 0 1rem;
    font-size: 0.9rem;
    border-radius: 2px;
}

.containers-behind-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    margin: 0 0 0.75rem;
    font-size: 0.92rem;
}

/* Self-contained chips for this page. Deliberately NOT reusing `.chip`: the base `.chip` rule is
   defined only inside component-scoped <style> blocks (TemplateAddItemsDialog / TemplateCreateGrid),
   which per docs/UIStyleGuide.md §2 are global but present only while THAT component renders — so a
   `.chip` here would be unstyled, and adding a competing base `.chip` to app.css would fight those
   rules at equal specificity and could restyle the template dialogs. Prefixed instead. */
.cbt-chip {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1.4;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    border: 1px solid transparent;
    white-space: nowrap;
}

.cbt-chip--info {
    background: var(--kendo-color-info-subtle, #e3f2fd);
    color: var(--kendo-color-info-on-subtle, #10556f);
    border-color: var(--kendo-color-info, #3f9fda);
}

.cbt-chip--danger {
    background: var(--kendo-color-error-subtle, #fdecea);
    color: var(--kendo-color-error-on-subtle, #8a1c13);
    border-color: var(--kendo-color-error, #d9534f);
}

/* "A template change is scheduled" banner on the template editor, and its twin on the ops console.
   Amber rather than red: a waiting change is normal, it just must not be invisible. Token colors per
   docs/UIStyleGuide.md §1. */
.note-template-scheduled {
    border-left: 3px solid var(--kendo-color-warning, #ff9800);
    background: var(--kendo-color-warning-subtle, #fff3e0);
    color: var(--kendo-color-warning-on-subtle, #8a5000);
    padding: 0.6rem 0.9rem;
    font-size: 0.9rem;
    border-radius: 2px;
}

    .note-template-scheduled .note-sub {
        margin-top: 0.3rem;
        font-size: 0.84rem;
        opacity: 0.9;
    }

    .note-template-scheduled .note-actions {
        margin-top: 0.5rem;
        display: flex;
        flex-wrap: wrap;
        gap: 0.4rem;
    }

/* --- /templates/scheduled ops console ------------------------------------------------------------- */
.sched-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    margin: 0 0 0.75rem;
    font-size: 0.92rem;
}

/* Same reasoning as .cbt-chip above: prefixed rather than reusing a `.chip` that only exists inside
   component-scoped style blocks. */
.sched-chip {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1.4;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    border: 1px solid transparent;
    white-space: nowrap;
}

.sched-chip--info {
    background: var(--kendo-color-info-subtle, #e3f2fd);
    color: var(--kendo-color-info-on-subtle, #10556f);
    border-color: var(--kendo-color-info, #3f9fda);
}

.sched-chip--warning {
    background: var(--kendo-color-warning-subtle, #fff3e0);
    color: var(--kendo-color-warning-on-subtle, #8a5000);
    border-color: var(--kendo-color-warning, #ff9800);
}

.sched-chip--danger {
    background: var(--kendo-color-error-subtle, #fdecea);
    color: var(--kendo-color-error-on-subtle, #8a1c13);
    border-color: var(--kendo-color-error, #d9534f);
}

.sched-chip--success {
    background: var(--kendo-color-success-subtle, #e8f5e9);
    color: var(--kendo-color-success-on-subtle, #1b5e20);
    border-color: var(--kendo-color-success, #37b400);
}

.sched-chip--muted {
    background: var(--kendo-color-base-subtle, #f0f0f0);
    color: var(--kendo-color-subtle, #656565);
    border-color: var(--kendo-color-border, #e0e0e0);
}

/* The recipients toggle and its one-line explanation, above the grid on the scheduled-changes console. */
.sched-recipients {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    margin: 0 0 0.75rem;
}

.sched-recipients-panel {
    /* Matches the shared admin-settings card width so the form does not stretch across a wide grid page. */
    max-width: 820px;
    margin: 0 0 1rem;
}

/* The outcome of the last operator action, held above the grid so it survives the reload that follows.
   Success and failure are different colors and different icons — an operator glancing at this page must
   not have to read to find out which one happened. */
.sched-result {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.6rem 0.9rem;
    margin: 0 0 0.75rem;
    font-size: 0.9rem;
    border-radius: 2px;
    border-left: 3px solid transparent;
}

    .sched-result > div {
        flex: 1;
    }

.sched-result--success {
    border-left-color: var(--kendo-color-success, #37b400);
    background: var(--kendo-color-success-subtle, #e8f5e9);
    color: var(--kendo-color-success-on-subtle, #1b5e20);
}

.sched-result--error {
    border-left-color: var(--kendo-color-error, #d9534f);
    background: var(--kendo-color-error-subtle, #fdecea);
    color: var(--kendo-color-error-on-subtle, #8a1c13);
}

/* "Rescheduling will not fix this" — a correction sitting inside an already-red block, so it needs to
   separate itself from the failure text above it without becoming a second alarm. */
.sched-recreate {
    margin-top: 0.4rem;
    padding-top: 0.4rem;
    border-top: 1px solid var(--kendo-color-error, #d9534f);
}

/* A Conflicted or Failed row must not read like every other row. */
.sched-attention {
    border-left: 3px solid var(--kendo-color-error, #d9534f);
    background: var(--kendo-color-error-subtle, #fdecea);
    color: var(--kendo-color-error-on-subtle, #8a1c13);
    padding: 0.5rem 0.75rem;
    margin: 0.35rem 0;
    font-size: 0.86rem;
    border-radius: 2px;
}

    .sched-attention .sched-reference {
        display: block;
        margin-top: 0.25rem;
        font-family: var(--bs-font-monospace, monospace);
        font-size: 0.8rem;
    }

.sched-detail {
    padding: 0.5rem 0.25rem;
}

.sched-detail-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 0.35rem 1.25rem;
    margin-bottom: 0.6rem;
    font-size: 0.86rem;
}

    .sched-detail-grid .sched-label {
        display: block;
        font-size: 0.76rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.03em;
        color: var(--kendo-color-subtle, #656565);
    }

/* The event timeline. A left rule plus a dot per entry reads as a sequence without needing a table. */
.sched-timeline {
    list-style: none;
    margin: 0;
    padding: 0 0 0 1rem;
    border-left: 2px solid var(--kendo-color-border, #e0e0e0);
}

    .sched-timeline li {
        position: relative;
        padding: 0 0 0.6rem 0.6rem;
        font-size: 0.86rem;
    }

        .sched-timeline li::before {
            content: "";
            position: absolute;
            left: -1.35rem;
            top: 0.42rem;
            width: 0.5rem;
            height: 0.5rem;
            border-radius: 50%;
            background: var(--kendo-color-border-alt, #b0b0b0);
        }

        .sched-timeline li.sched-timeline--alarming::before {
            background: var(--kendo-color-error, #d9534f);
        }

    .sched-timeline .sched-event-head {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 0.5rem;
    }

    .sched-timeline .sched-event-label {
        font-weight: 600;
    }

    .sched-timeline .sched-event-when {
        font-size: 0.78rem;
        color: var(--kendo-color-subtle, #656565);
    }

    .sched-timeline .sched-event-detail {
        margin: 0.1rem 0 0;
    }

.restocks-header {
    display: flex;
    align-items: center;
    justify-content:space-between;
}

.restocks-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    user-select: none;
}

/* The off-side label used to be dimmed with opacity (3.61:1); subtle text instead (7.00:1). */
.toggle-label {
    font-weight: 600;
    color: var(--kendo-color-subtle);
}

    .toggle-label.active {
        color: #0067B8;
    }

.restocks-toggle input[type="checkbox"] {
    width: 44px;
    height: 24px;
    appearance: none;
    border-radius: 999px;
    background: #80868B;
    position: relative;
    cursor: pointer;
}

    .restocks-toggle input[type="checkbox"]::after {
        content: "";
        position: absolute;
        top: 3px;
        left: 3px;
        width: 18px;
        height: 18px;
        border-radius: 50%;
        background: #fff;
        transition: transform 0.15s ease;
    }

    .restocks-toggle input[type="checkbox"]:checked::after {
        transform: translateX(20px);
    }

/* Hide and Disable expansion button for closed restocks with no audits */
tr:has(.audit-none) td.k-hierarchy-cell span {
    display: none !important;
}

tr:has(.audit-none) td.k-hierarchy-cell {
    pointer-events: none !important;
    cursor: default !important;
}

/*Hide and Disable expansion button for inner cells for failed audits */
tr.issue-no-detail td.k-hierarchy-cell span {
    display: none !important;
}

tr.issue-no-detail td.k-hierarchy-cell {
    pointer-events: none !important;
    cursor: default !important;
}

/* checkbox alignment */

.issue-filter-toggle {
    display: flex;
    gap: 1rem;
    margin-bottom: 0.5rem;
}

.issue-filter-toggle label {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.9rem;
}

/* Restock Report Toggle Slider */
.audit-filter-toggle {
    margin-bottom: 0.75rem;
}

.audit-filter-toggle .k-switch-label-on,
.audit-filter-toggle .k-switch-label-off {
    display: inline;
}

/* visual representation of changed values in issues table */

.changed-value {
    font-weight: 700;
}

/* Rounds the create product dialog warning */
.confirm-rounded {
    border-radius: 8px;
    overflow: hidden;
}

/* Alternate (secondary-attention) utilities — purple, fills the gap between primary and warning */
.text-alternate { color: #6f42c1 !important; }
.bg-alternate { background-color: #6f42c1 !important; }
.border-alternate { border-color: #6f42c1 !important; }

/* Ensure Telerik dropdown popups render above dialog overlays.
   Use descendant :has() — DropDownList wraps the popup in a
   .k-child-animation-container, so the popup isn't a direct child. */
.k-animation-container:has(.k-popup) {
    z-index: 100002 !important;
}

/* Same bug, different popup: a Tooltip renders .k-tooltip rather than .k-popup,
   so the rule above does not reach it and one raised inside a dialog fires and
   is drawn UNDER the .k-dialog-wrapper — invisible, with no error and
   nothing wrong in the markup. Declaring the Tooltip inside DialogContent does
   not help: Telerik appends every animation container to the body regardless.
   A tooltip is never the thing that should be covered, so this is not scoped to
   one dialog. */
.k-animation-container:has(.k-tooltip) {
    z-index: 100003 !important;
}

/* Deep-link flash highlight for template item rows targeted by the in-use / lookup
   dialog "View" action. Fades a yellow background in and out so the user can spot
   the row that was being inspected. */
@keyframes template-deeplink-flash-anim {
    0%   { background-color: rgba(255, 220, 0, 0.55); }
    60%  { background-color: rgba(255, 220, 0, 0.55); }
    100% { background-color: transparent; }
}

tr.template-deeplink-flash > td {
    animation: template-deeplink-flash-anim 1.8s ease-out;
}

/* Shared phased-modal chrome (Choice -> Busy -> Done). A plain markup modal (NOT
   TelerikDialog) is used because a TelerikDialog does not reliably re-render its
   content when the phase is flipped imperatively mid-operation. Used by the
   template Educational copy/convert dialog and the template Duplicate dialog. */
.edu-modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 2000;
    padding: 1rem;
}

.edu-modal {
    background: var(--kendo-color-surface, #fff);
    color: var(--kendo-color-on-surface, inherit);
    border-radius: 6px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
    width: min(680px, 94vw);
    max-height: 90vh;
    overflow: auto;
}

.edu-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 1.25rem;
    border-bottom: 1px solid var(--kendo-color-border, #e0e0e0);
}

.edu-modal__title {
    margin: 0;
    font-size: 1.05rem;
}

.edu-modal__close {
    background: none;
    border: none;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    color: inherit;
}

.edu-modal__body {
    padding: 1.25rem;
}

/* --- Viewport-safe sizing for ALL Telerik dialogs ------------------------------
   No dialog should span the whole screen on either axis. This covers custom
   dialogs AND the predefined Alert/Confirm/Prompt dialogs (which size to their
   message and, with a long sentence, would otherwise stretch full-width). The
   widest dialog in the app sets Width="800px", so this 820px cap shrinks nothing
   real — it only reins in content-sized dialogs; a dialog's own inline Width
   below the cap still wins, and long text simply wraps within the bound. The
   title bar and action buttons stay pinned while only the body scrolls. */
.k-dialog-wrapper .k-dialog,
.k-dialog-wrapper .k-window {
    max-width: min(820px, 94vw);
}

.k-dialog-wrapper .k-dialog-content,
.k-dialog-wrapper .k-window-content {
    max-height: 70vh;
    overflow-y: auto;
    overflow-x: hidden;
}

/* Floor-restock offer dialog: at-a-glance summary chips + compact lists. */
.tcfr-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.tcfr-chip {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 600;
    line-height: 18px;
    white-space: nowrap;
}

.tcfr-chip-add    { background: #e6f4ea; color: #1e7e34; }
.tcfr-chip-remove { background: #fdecea; color: #c0392b; }
.tcfr-chip-kit    { background: #eae6f7; color: #5b3ea8; }
.tcfr-chip-warn   { background: #fff4e5; color: #9A5B00; }
/* Quantity raise (blue) reads as distinct from a genuine ADD (green): the item is already on the cart,
   only how many are expected changed. Neutral carries the "already at the new quantity" count — nothing
   to do. Both live HERE, in the global tcfr-chip family, not in a component style block: this dialog is
   also shown from the admin editor, where a component-scoped modifier renders as unstyled inline text. */
/* Floor-restock pick list: WRAP rather than clip. Every column here can hold a value longer than its
   width — a product name plus its generic underneath, a lot number, a drawer named after its cart — and
   the grid default (nowrap + ellipsis) truncates silently. A clipped destructive action reading "ulled"
   is the worst version of this, but a half-shown lot number is the same failure: the row stops being
   something a tech can act on. Wrapping keeps every value whole and lets the row grow instead.
   Global, not component-scoped: Telerik renders these cells in its own DOM, which carries no Blazor
   isolation attribute, so a .razor.css rule would never reach them. */
.floor-restock-items .k-table-td,
.floor-restock-items .k-table-th,
.floor-restock-items .k-grid td,
.floor-restock-items .k-grid th {
    white-space: normal;
    overflow-wrap: anywhere;
    vertical-align: top;
}

/* Header labels wrap too, so a two-word title keeps its second word instead of losing it to an ellipsis. */
.floor-restock-items .k-column-title {
    white-space: normal;
}

.tcfr-chip-qty     { background: #e8f0fe; color: #1a56b8; }
.tcfr-chip-neutral { background: #eef0f2; color: #4a5560; }

/* Keep a long grouped "needs full restock" list readable but bounded. */
.tcfr-missing-list {
    max-height: 160px;
    overflow-y: auto;
    padding-left: 1.1rem;
}

.template-change-floor-restock-dialog .tcfr-alert .k-alert-content {
    font-size: 13px;
}

/* "Prepare for redeploy" opt-in: checkbox top-aligned with a stacked title + helper text so the long
   explanation no longer wraps awkwardly beside a floating checkbox. */
.redeploy-sweep-option {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 8px 10px;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    background: #f7f9fc;
}

.redeploy-sweep-option .k-checkbox {
    margin-top: 2px;
    flex: 0 0 auto;
}

.redeploy-sweep-option label {
    margin: 0;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.redeploy-sweep-title {
    font-weight: 600;
}

.redeploy-sweep-help {
    color: #5C636A;
    font-size: 12.5px;
    line-height: 1.35;
}

/* Label + sweep-count status stacked beside the checkbox. The count sits OUTSIDE the <label> so
   clicking it doesn't toggle the box and its changing text isn't part of the accessible name. */
.redeploy-sweep-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.redeploy-sweep-count {
    margin-top: 4px;
    font-size: 12.5px;
    line-height: 1.35;
    color: #1d4ed8;
    font-weight: 600;
}

.redeploy-sweep-count.redeploy-sweep-count-muted {
    color: #5C636A;
    font-weight: 400;
}

.redeploy-sweep-count.redeploy-sweep-count-error {
    color: #b91c1c;
    font-weight: 400;
}

/* ─────────────────────────────────────────────────────────────────────────
   Floor-restock selection tree: row status highlighting, the future-item
   legend, and the container name cell.

   These moved here from FloorRestockSelectionDialog's inline <style> block.
   A component's <style> only exists in the DOM while that component renders,
   so leaving them there meant the rules would disappear the moment the
   selection UI moved to its own page — a green build that silently ships
   expired rows with no red on them, which is the most safety-relevant signal
   on the screen. They are shared by more than one component now, which
   app.css is the single source for.
   ───────────────────────────────────────────────────────────────────────── */

/* Container name over a smaller template name, in the tree's expandable cell. */
.container-name-cell {
    display: inline-block;
    line-height: 1.3;
}

.container-name-cell .template-name {
    font-size: 0.75rem;
    margin-top: 1px;
    line-height: 1.2;
}

/* Row highlighting for expired items */
.k-treelist .treelist-row-expired {
    background-color: #fee2e2 !important;
}

.k-treelist .treelist-row-expired:hover {
    background-color: #fecaca !important;
}

/* Row highlighting for pull range items */
.k-treelist .treelist-row-pull-range {
    background-color: #fef3c7 !important;
}

.k-treelist .treelist-row-pull-range:hover {
    background-color: #fde68a !important;
}

/* Row highlighting for device-less future items (informational blue, mirrors card-status-info) */
.k-treelist .treelist-row-future {
    background-color: #eff6ff !important;
}

.k-treelist .treelist-row-future:hover {
    background-color: #dbeafe !important;
}

/* Legend explaining the future-item highlight */
.future-legend {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-left: 3px solid #bfdbfe;
    background: #eff6ff;
    font-size: 0.85rem;
    line-height: 1.35;
    color: #334155;
}

.future-legend-icon {
    margin-top: 2px;
    color: #3b82f6;
    flex: 0 0 auto;
}

/* Master "select all items" checkbox + label */
.select-all-items-option {
    gap: 8px;
}

.select-all-items-option label {
    margin: 0;
    cursor: pointer;
    font-weight: 600;
}

/* ─────────────────────────────────────────────────────────────────────────
   Shared template-picker card styles.
   Used by both TemplateAddItemsDialog and TemplateItemMappingsDialog so the
   two item pickers stay visually identical. Kept here (single source) instead
   of duplicated in each component's inline <style>.
   ───────────────────────────────────────────────────────────────────────── */
.add-items-hint {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    padding: .5rem .75rem;
    background: var(--kendo-color-info-subtle, #e7f2ff);
    border-radius: 6px;
    font-size: .85rem;
    color: var(--kendo-color-on-app-surface, #212121);
}

.add-items-hint em {
    font-style: italic;
    color: var(--kendo-color-primary-on-surface, #0E5781);
}

.generic-card .k-card-body {
    padding: .75rem 1rem;
}

.added-item-card {
    border-left: 3px solid var(--kendo-color-primary, #0d6efd);
    background: var(--kendo-color-surface-alt, #f8f9fa);
}

/* "Already in template": no opacity (it took the text to 2.87:1). The .chip--existing label says it in words. */
.existing-item-card {
    border-left: 3px solid var(--kendo-color-border, #d6d6d6);
    background: var(--kendo-color-base-subtle, #f1f3f5);
    pointer-events: none;
}

.generic-row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    align-items: center;
}

.generic-row__main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

.generic-row__title-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

.generic-row__name {
    font-weight: 600;
    font-size: 1rem;
}

.generic-row__brand {
    font-size: .875rem;
}

.generic-row__meta {
    font-size: .8rem;
}

.generic-row__product-details {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem .75rem;
    font-size: .8rem;
    color: var(--kendo-color-subtle, #6c757d);
}

.generic-row__check {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    color: var(--kendo-color-subtle, #9e9e9e);
}

.added-item-card .generic-row__check {
    color: var(--kendo-color-primary, #0d6efd);
}

.existing-item-card .generic-row__check {
    color: var(--kendo-color-success, #198754);
}

.generic-row__actions {
    display: flex;
    align-items: center;
    gap: .5rem;
    flex-shrink: 0;
}

/* ── Chips: the GLOBAL base ────────────────────────────────────────────────────────────────────
   Until now this file carried only chip *modifiers* and every component defined its own base in a
   private <style> block. Any page that used a modifier without also defining a base therefore
   rendered the chip as plain unstyled text — which is exactly what happened to the "Missing" chip on
   FloorRestockPage and AdminRestocksPage: `class="chip chip--danger"` with no `.chip` and no
   `.chip--danger` anywhere in scope, so a clinically meaningful flag showed up as bare body text.
   (Already documented as a known fault in docs/CartAdoptionGate.md.)

   Why a global base is safe: Blazor injects a component's <style> block LATER in the document than
   this linked stylesheet, and these rules are equal specificity, so a component's own base still
   wins on every property it sets. This can only FILL GAPS, never fight an existing definition.

   Deliberately NO `text-transform: uppercase` here. Three components set it themselves and keep it;
   TemplateCreateGrid dropped it on purpose (uppercase at ~11px destroys word-shape on long labels),
   and putting it in the global base would silently reinstate it there. */
.chip {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    padding: 1px 8px;
    font-size: .75rem;
    font-weight: 600;
    border-radius: 999px;
}

/* BLUE = information. The canonical chip--info, stated here because two components each carried their
   own copy in a global <style> block and the copies disagreed: TemplateAddItemsDialog painted the text
   in the saturated --kendo-color-info, 4.31:1 on info-subtle (SC 1.4.3 needs 4.5:1), and whichever block
   rendered last won on any page holding both. Two classes so it outranks either copy; the text is the
   -on-subtle half of the pair, like every other chip here. */
.chip.chip--info {
    background: var(--kendo-color-info-subtle, #d6e9ff);
    color: var(--kendo-color-info-on-subtle, #001f52);
}

/* RED = a real unit is absent or a real operation failed — a runtime fact, never a configuration
   choice. Configuration surfaces (the template editor) deliberately never use this; their strongest
   color is amber. Bordered like .chip--shortage so it still reads as a flag in a dense grid, and
   text uses error-on-subtle (the saturated --kendo-color-error on error-subtle measures ~3.8:1 and
   the far worse warning pair measures 1.76:1 — always use the -on-subtle half of the pair). */
.chip--danger {
    background: var(--kendo-color-error-subtle, #f7d1d3);
    color: var(--kendo-color-error-on-subtle, #4d0a0e);
    border: 1px solid var(--kendo-color-error, #d51923);
}

/* GREEN = a task reached its intended ending. The counterpart to .chip--danger and, like it, a runtime
   fact rather than a configuration choice — a confirmed template-removal pull, not a setting that is
   switched on. Bordered to match, and the text uses success-ON-subtle for the reason spelled out above:
   white ink on the saturated --kendo-color-success FALLBACK (#37b400) measures ~2.6:1, and the fallback
   is what renders wherever the Kendo variables have not loaded — which is exactly where a reviewer
   looks. That pairing is what this replaces on FloorRestockPage. */
.chip--success {
    background: var(--kendo-color-success-subtle, #e8f5e9);
    color: var(--kendo-color-success-on-subtle, #1b5e20);
    border: 1px solid var(--kendo-color-success, #37b400);
}

/* GRAY = a task ended WITHOUT reaching its intended ending: withdrawn, canceled, closed by someone.
   The deliberate counterpart to .chip--success, which would claim the work was done. Neutral rather
   than red, because nothing went wrong; the work was simply taken off the list. */
.chip--closed {
    background: var(--kendo-color-base-subtle, #ebebeb);
    color: var(--kendo-color-base-on-subtle, #3d3d3d);
    border: 1px solid var(--kendo-color-border, #c4c4c4);
}

.chip--existing {
    background: var(--kendo-color-surface, #f1f3f5);
    color: var(--kendo-color-subtle, #6c757d);
    font-size: .65rem;
}

/* "This generic belongs to a scheduled template change that has not gone live." Shared by the Add Item
   dialog and the Manage Item Mappings generic picker (each defines the base .chip in its own style
   block; this is the color modifier only). Amber, matching the scheduled-change family elsewhere. */
.chip--scheduled {
    background: var(--kendo-color-warning-subtle, #fff3e0);
    color: var(--kendo-color-warning-on-subtle, #8a5000);
    border: 1px solid var(--kendo-color-warning, #ff9800);
}

/* Shortage indicator chip. Shared by the template item grid, the Manage dialog, and the item/brand
   pickers (each defines the base .chip in its own style block; this is the color modifier only).
   Amber "attention, not error" family, theme-aware via kendo vars. */
.chip--shortage {
    background: var(--kendo-color-warning-subtle, #fff3cd);
    color: var(--kendo-color-warning-on-subtle, #997404);
    border: 1px solid var(--kendo-color-warning, #ffc107);
    font-weight: 600;
}

/* "A generic in this account already maps this product, so importing would mint a second one."
   Amber "attention, not error" family: importing a duplicate is occasionally legitimate, so this must
   read as a caution the user can overrule, not as a blocked action. Declared after .chip--shortage so a
   product that is BOTH duplicated and in shortage still shows two visually distinct chips. */
.chip--duplicate {
    background: var(--kendo-color-warning-subtle, #fff3cd);
    color: var(--kendo-color-warning-on-subtle, #997404);
    border: 1px solid var(--kendo-color-warning, #ffc107);
    font-weight: 600;
}

/* PURPLE = this template is educational: its carts are training stock, and their expired items are
   tracked separately and never raise an alert. Purple rather than the amber/red families precisely
   because it is not a warning - it is a different KIND of template. Was six inline declarations on
   NewTemplatePage including a raw #6f42c1; there is no Kendo token for this hue, so the hex lives
   here, once, beside the other chip modifiers. */
.chip--educational {
    background: #6f42c1;
    color: #fff;
    letter-spacing: .3px;
}

/* NEUTRAL read-out of a configuration value, used by the Template Settings header strip so the card
   answers "what is this template set to do" without reading five hints. Grey on purpose: these are
   settings, not states - nothing here is wrong, so nothing here earns a color. Uses base-subtle
   rather than --kendo-color-surface, which the style guide reserves for card backgrounds. */
/* Informational blue: this row is a template position the cart does not hold yet, not a warning.
   Same hue family as .k-card.card-status-info and the future-item row tint, so "future" means one
   color everywhere in the app. Text uses the -on-subtle half of the token pair: the base token on a
   subtle background measures far below AA, and the hex fallback hides it because the fallback passes. */
.chip--future {
    background: var(--kendo-color-info-subtle, #eff6ff);
    color: var(--kendo-color-info-on-subtle, #10556f);
    border: 1px solid var(--kendo-color-info, #3f9fda);
}

.chip--setting {
    background: var(--kendo-color-base-subtle, #f0f0f0);
    color: var(--kendo-color-on-base, #212529);
    border: 1px solid var(--kendo-color-border, #e0e0e0);
}

/* NEUTRAL = this line was stocked with a SUBSTITUTE brand of its generic rather than the primary (the
   product a tech confirmed present, RestockItem.ConfirmedAccountProductId). Gray on purpose: a substitute
   is an allowed choice, not a fault and not a shortage, so it earns no warning color. The title attribute
   names the primary. Text uses the -on-subtle half of the token pair, as every chip above does. */
.chip--substitute {
    background: var(--kendo-color-base-subtle, #ebebeb);
    color: var(--kendo-color-base-on-subtle, #3d3d3d);
    border: 1px solid var(--kendo-color-border, #c4c4c4);
}

/* AMBER = stock that will be pulled at the next restock: its expiration falls inside its container's restock
   window, but it has not expired (that is .chip--danger). Used by the read-only Contents view
   (ContainerContentsReadOnly). A runtime fact about stock, so it carries its words ("Expiring soon") and never
   relies on the color alone. Text uses the -on-subtle half of the warning pair: the saturated --kendo-color-warning
   on warning-subtle measures 1.76:1. */
.chip--expiring {
    background: var(--kendo-color-warning-subtle, #fff3cd);
    color: var(--kendo-color-warning-on-subtle, #997404);
    border: 1px solid var(--kendo-color-warning, #ffc107);
}

/* "This control does NOT ride the form's Save." Amber, per the house rule that a configuration
   surface's strongest color is attention rather than error - writing immediately is the documented
   behaviour, not a fault. Pairs with a "Saved immediately" clause in the control's own hint; the
   style guide requires BOTH, because a checkbox that looks like the rest of a form will be assumed
   to wait for Save. Uses the -on-subtle half of the warning pair: the saturated --kendo-color-warning
   on warning-subtle measures 1.76:1. */
.chip--immediate {
    background: var(--kendo-color-warning-subtle, #fff3cd);
    color: var(--kendo-color-warning-on-subtle, #997404);
    border: 1px solid var(--kendo-color-warning, #ffc107);
}

/* ---- Settings: the value-field grid, the tile deck and the checkbox-as-switch ------------------
   Template Settings on NewTemplatePage and the Settings step of the create wizard
   (CreateTemplatePage). Prefixed .ts- so the names cannot collide with anything else.
   See docs/UIStyleGuide.md section 12 for why the deck is auto-fit and why the switch is a
   restyled TelerikCheckBox. */
/* The value fields above the deck. auto-fit, NOT a fixed track count: at every width the last row
   fills edge to edge, so there is never a trailing empty cell, and the fields stack on their own on
   a narrow screen with the row gap still between them. */
.ts-values {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1rem 1.25rem;
    align-items: start;   /* correct HERE: fields of comparable height */
}

.ts-values .k-form-field-wrap .k-input,
.ts-values .k-form-field-wrap .k-textbox,
.ts-values .k-form-field-wrap .k-picker {
    width: 100%;
}

.ts-values .k-form-hint {
    display: block;
    margin-top: .25rem;
    color: var(--kendo-color-subtle, #6c757d);
    font-size: .8rem;
}

.ts-deck {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: .75rem;
    align-items: stretch; /* NOT start - stretching is what kills the void */
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--kendo-color-border, #e0e0e0);
}

.ts-toggle {
    display: flex;
    flex-direction: column;
    gap: .4rem;
    padding: .7rem .85rem;
    border: 1px solid var(--kendo-color-border, #e0e0e0);
    border-radius: 6px;
    background: var(--kendo-color-base-subtle, #f0f0f0);
    transition: border-color .12s ease, background-color .12s ease;
}

.ts-toggle--on {
    border-color: var(--kendo-color-primary, #0d6efd);
    background: var(--kendo-color-surface, #fff);
}

/* flex-start, not center: a 2-line title next to a 20px control used to center the control against
   the middle line, so it aligned with neither the text above it nor its own first line. */
.ts-toggle__head {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
}

.ts-toggle__title {
    flex: 1 1 auto;
    margin: 0;
    font-size: .9rem;
    font-weight: 600;
    line-height: 1.3;
    cursor: pointer;   /* it is a real label-for target, so say so */
}

.ts-toggle__state {
    flex: 0 0 auto;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--kendo-color-subtle, #6c757d);
}

.ts-toggle--on .ts-toggle__state {
    color: var(--kendo-color-primary, #0d6efd);
}

/* The immediate-write badges share a flex row with a flexible title. Without this they are
   shrinkable (.chip is only inline-flex) and wrap mid-phrase at the deck 280px minimum, which is
   the one place the text must stay legible - it is the warning that the control does not wait
   for Save. Matches .ts-toggle__state, which is already pinned. */
.ts-toggle__head .chip {
    flex: 0 0 auto;
}

.ts-toggle__hint {
    margin: 0;
    font-size: .8rem;
    line-height: 1.35;
    color: var(--kendo-color-subtle, #6c757d);
}

/* The conditional sub-setting, nested inside its parent tile so expanding it spends the tile own
   slack rather than growing the deck row and pushing the Stock Items grid down the page. */
.ts-toggle__sub {
    margin-top: .35rem;
    padding: .5rem .6rem;
    border-left: 2px solid var(--kendo-color-primary, #0d6efd);
    border-radius: 0 4px 4px 0;
    background: var(--kendo-color-surface, #fff);
}

/* ---- checkbox rendered as a switch -------------------------------------------------------
   Deliberately NOT TelerikSwitch: that control renders no input element, so a label-for
   stops associating and there is no way to pass it an aria-label (Telerik components take no
   unmatched attributes). Kendo already ships .k-checkbox as appearance:none WITH a styled
   ::before, so re-dressing it as a track and thumb is supported, and the input, the label
   binding, the keyboard behavior and the OnChange signatures all survive untouched. */
.ts-toggle__head .k-checkbox {
    position: relative;
    flex: 0 0 auto;
    width: 38px;
    height: 20px;
    margin-top: .1rem;
    border-radius: 999px;
    border: 1px solid var(--kendo-color-border, #e0e0e0);
    background: var(--kendo-color-surface, #fff);
    transition: background-color .12s ease, border-color .12s ease;
    cursor: pointer;
}

/* Kendo draws the tick with ::before; repurpose it as the thumb and drop the glyph. */
.ts-toggle__head .k-checkbox::before {
    content: "";
    position: absolute;
    top: 50%;
    left: 2px;
    width: 14px;
    height: 14px;
    transform: translateY(-50%);
    border-radius: 50%;
    background: var(--kendo-color-subtle, #6c757d);
    transition: left .12s ease, background-color .12s ease;
    /* Kendo draws the checkmark by MASKING this pseudo-element with an inline SVG
       (.k-checkbox:checked::before { mask-image: url(...) }). Left in place it would mask the
       thumb down to the tick stroke and silently defeat border-radius. clip-path is NOT the
       property to reset - the theme never uses it on .k-checkbox. */
    -webkit-mask-image: none;
    mask-image: none;
}

.ts-toggle__head .k-checkbox:checked {
    background: var(--kendo-color-primary, #0d6efd);
    border-color: var(--kendo-color-primary, #0d6efd);
}

.ts-toggle__head .k-checkbox:checked::before {
    left: 20px;
    background: #fff;
    -webkit-mask-image: none;
    mask-image: none;
}

/* The armed tile borders in primary, which is also Kendo focus color - keep the ring itself
   distinguishable against it. */
.ts-toggle__head .k-checkbox:focus-visible {
    outline: 2px solid var(--kendo-color-on-base, #212529);
    outline-offset: 2px;
    box-shadow: none;
}

/* Drawer color swatch: the always-clickable square at the front of the template grid's drawer rows,
   and beside each drawer on the create wizard. Sized to sit comfortably in a 52px column without
   stretching the row. */
/*noinspection CssUnresolvedCustomProperty*/
.drawer-color-cell {
    display: block;
    width: 24px;
    height: 24px;
    margin: 0 auto;
    padding: 0;
    border-radius: 4px;
    /* A neutral ring rather than none: the palette contains #ffffff, which would otherwise be
       invisible against the grid surface. */
    border: 1px solid var(--kendo-color-border, #d6d6d6);
    /* Split fill only. The segmented border is reserved for the cart drawers themselves, where it has
       room to read; on a 24px icon it was busy rather than informative. Set inline per cell by
       DrawerColorConstants.InlineVariables; unset for an uncolored drawer, where
       drawer-color-cell--none takes over. */
    background: var(--dc-fill);
    /* Stop the fill at the INNER edge of the border. The default (border-box) paints it underneath,
       and these neutral borders are semi-transparent — including var(--kendo-color-border) itself — so
       whichever band happened to sit under a given stretch of edge showed through and read as a stray
       color bleeding around the rim. */
    background-clip: padding-box;
    cursor: pointer;
    transition: outline-offset 120ms ease-out;
}

.drawer-color-cell:hover:not(:disabled),
.drawer-color-cell:focus-visible {
    outline: 2px solid var(--kendo-color-primary, #3f51b5);
    outline-offset: 2px;
}

/* No color set — dotted outline, matching the "no color" slot in the picker ring. */
.drawer-color-cell--none {
    background-color: transparent;
    border: 1px dashed var(--kendo-color-subtle, #8f8f8f);
}

/* A drawer that has not been saved yet has no slot to attach a color to. Shown rather than hidden
   so the column does not appear to flicker in and out as rows are added. */
.drawer-color-cell--disabled {
    cursor: not-allowed;
    opacity: .4;
}

/* Hidden (not removed) while this cell's color ring is open: the ring is centered on this swatch, so
   the swatch would otherwise show through the ring's hole behind the center label. visibility rather
   than display so the cell keeps its size and the row does not twitch. */
.drawer-color-cell--picking {
    visibility: hidden;
}

/* The explanation + "Use existing generic" jump, inside the product card. */
.duplicate-generic-notice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    flex-wrap: wrap;
    margin: .35rem 0;
    padding: .4rem .6rem;
    font-size: .8rem;
    background: var(--kendo-color-warning-subtle, #fff3cd);
    color: var(--kendo-color-warning-on-subtle, #997404);
    border-left: 3px solid var(--kendo-color-warning, #ffc107);
    border-radius: 4px;
}

.duplicate-generic-card {
    border-color: var(--kendo-color-warning, #ffc107);
}

/* Selection summary bar ("N selected → Done") */
.selection-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .75rem 1rem;
    margin-top: .75rem;
    background: var(--kendo-color-primary-subtle, #e0edff);
    border: 1px solid var(--kendo-color-primary, #0d6efd);
    border-radius: 8px;
}

.selection-bar__summary {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-weight: 500;
    color: var(--kendo-color-on-app-surface, #212121);
}

.selection-bar__count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.6rem;
    height: 1.6rem;
    padding: 0 .4rem;
    border-radius: 999px;
    background: var(--kendo-color-primary, #0d6efd);
    color: #fff;
    font-weight: 700;
    font-size: .85rem;
}

/* Character-count field (CharCountField.razor). Shared by every field that shows a live
   N/MaxLength counter (product dialogs, template name editors), so it lives here, not in
   any one component's inline <style>. */
.field-char-count {
    display: block;
    font-size: 0.75rem;
    color: var(--kendo-color-subtle, #595959);
    margin-top: 2px;
}

.field-char-count.over {
    color: var(--kendo-color-error, #d32f2f);
    font-weight: 600;
}

/* Drawer colors are NOT defined here any more. The static .drawer-color--<name>
   rules that used to live at this spot could not survive multi-color drawers —
   one to three colors from the palette is hundreds of ordered combinations, so
   the values are generated instead. See DrawerColorConstants.cs. */

/* ---------------------------------------------------------------------------
   Report date bounds + Smart Select badge.
   Shared by InventoryReport and InspectionDetailReport (and any report module
   added later), so it lives here rather than in either component's <style> —
   a component's inline style only exists while that component is rendered.
   --------------------------------------------------------------------------- */
.report-date-bounds {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* A date-range field never SHRINKS inside a wrapping row of filters. The two bounds are allowed to
   wrap (so a narrow screen still works), which makes the field's minimum width a single bound — so
   in a crowded row the browser squeezed it to that and folded the range into a stack. Not shrinking
   moves the whole range to the next line instead, still side by side. */
.k-form-field:has(.report-date-bounds) {
    flex-shrink: 0;
}

.report-date-bound {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.report-date-sep {
    color: var(--kendo-color-subtle, #6b7280);
    font-size: 0.9rem;
}

.report-date-rolling {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.4rem;
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
    background: var(--kendo-color-info-subtle, #dbeafe);
    color: var(--kendo-color-info-on-subtle, #1d4ed8);
    font-size: 0.82rem;
    font-weight: 500;
    width: fit-content;
}

.report-date-rolling .k-svg-icon {
    color: var(--kendo-color-info-on-subtle, #1d4ed8);
}

/* ---------------------------------------------------------------------------
   Report caveats and the restock family's own marks.

   The scope note is for the sentence a report has to say about ITSELF before
   anybody reads a number off it — whose rows these are, what "previous" was
   rebuilt from, which restocks were never timed. Informational blue, matching
   .report-date-rolling above, because none of it is a warning: it is the
   report being honest about its own shape.
   --------------------------------------------------------------------------- */
.report-scope-note {
    display: flex;
    align-items: flex-start;
    gap: 0.45rem;
    padding: 0.4rem 0.65rem;
    border-radius: 4px;
    background: var(--kendo-color-info-subtle, #dbeafe);
    color: var(--kendo-color-info-on-subtle, #1d4ed8);
    font-size: 0.85rem;
    line-height: 1.35;
}

.report-scope-note .k-svg-icon {
    color: var(--kendo-color-info-on-subtle, #1d4ed8);
    flex: 0 0 auto;
    margin-top: 0.12rem;
}

/* An empty result that needs a sentence of explanation, as against one that
   speaks for itself. Deliberately quiet — nothing went wrong. */
.report-empty-note {
    padding: 0.75rem 0.9rem;
    margin-bottom: 1rem;
    border: 1px solid #e9ecef;
    border-radius: 0.25rem;
    background-color: #fff;
    color: #6b7280;
    font-size: 0.875rem;
}

/* The reader's own row on Restock Time, so they can find themselves in a
   comparison of twenty people. A tint and a rule, not a color change: the
   numbers in that row mean exactly what they mean in every other row. */
.restock-time-own-row > td {
    background-color: #eff6ff !important;
}

.restock-time-own-row > td:first-child {
    box-shadow: inset 3px 0 0 0 #2563eb;
}

.restock-time-you {
    margin-left: 0.4rem;
    padding: 0.05rem 0.35rem;
    border-radius: 3px;
    background: #dbeafe;
    color: #1d4ed8;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

/* Which way a cart's soonest expiration moved. Colored by DIRECTION, never by
   size: one day closer and thirty days closer are the same kind of problem, and
   a gradient would make the small one look acceptable. */
.exp-change {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    border-radius: 3px;
    font-size: 0.8rem;
    font-weight: 600;
}

.exp-change--out {
    background: #f0fdf4;
    color: #15803d;
}

.exp-change--in {
    background: #fef2f2;
    color: #b91c1c;
}

.exp-change--flat {
    background: #fefce8;
    color: #a16207;
}

/* Missing Item Reports. Same pill shape and the same three-color vocabulary as the expiration
   changes above, so a reader moving between the two restock reports does not have to relearn what a
   green chip means: green = the good outcome, red = the open problem, amber = neither.

   Colored by DIRECTION rather than by age. A report open for a week and one open for a day are the
   same kind of fact -- nobody has resolved it -- and the Hours Open column is where the size lives. */
.missing-outcome {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    border-radius: 3px;
    font-size: 0.8rem;
    font-weight: 600;
}

.missing-outcome--open {
    background: #fef2f2;
    color: #b91c1c;
}

/* The outcome that exists nowhere else in the app: the report was cleared BECAUSE the item was
   found. Every one of these is invisible to the open-reports screen. */
.missing-outcome--stocked {
    background: #f0fdf4;
    color: #15803d;
}

/* Cleared, but nothing was ever stocked -- somebody withdrew the report, or the restock moved on.
   Not a success and not an open problem, so it gets the third color rather than either. */
.missing-outcome--cleared {
    background: #fefce8;
    color: #a16207;
}

/* An empty reason is a finding, not a blank: it is the case a supply manager can do least with, and
   a lot of them means the handheld's quick-pick list is missing the real answer. Said in words and
   dimmed, rather than left as whitespace a reader has to interpret. */
.missing-reason--none {
    color: #6b7280;
    font-style: italic;
}

/* A row on the drawer breakdown that is not a drawer — the cart itself when nothing was open, a
   container since deleted, or work from a handheld too old to say which. The time is real, so the
   row stays; it is dimmed and italic so it does not get read as a drawer somebody could redesign. */
.drawer-pseudo {
    color: #6b7280;
    font-style: italic;
}

/* ---------------------------------------------------------------------------
   Which hospital a report row came from.

   Only ever shown when a result spans more than one account, which today means
   a SuperAdmin running a cross-account report. The NAME is the information —
   the color only makes two hospitals separable while scanning a dense grid, so
   it is assigned round-robin from the row's own name and carries no meaning.

   Six muted tints, none of them red or amber: a row from "Mercy" must not read
   as a warning just because it sorted third.
   --------------------------------------------------------------------------- */
.report-account-chip {
    display: inline-block;
    max-width: 100%;
    padding: 0.1rem 0.45rem;
    border-radius: 4px;
    border: 1px solid transparent;
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1.4;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
}

.report-account-chip-0 { background: #eff6ff; border-color: #bfdbfe; color: #1d4ed8; }
.report-account-chip-1 { background: #f0fdfa; border-color: #99f6e4; color: #0f766e; }
.report-account-chip-2 { background: #faf5ff; border-color: #e9d5ff; color: #7e22ce; }
.report-account-chip-3 { background: #f0fdf4; border-color: #bbf7d0; color: #15803d; }
.report-account-chip-4 { background: #f8fafc; border-color: #cbd5e1; color: #334155; }
.report-account-chip-5 { background: #fdf2f8; border-color: #fbcfe8; color: #be185d; }

/* A one-line note under a report filter, for the cases where the field's behavior is not obvious
   from its label — item names match partially, DIs do not. Quiet enough to skip once learned. */
.report-field-hint {
    margin-top: 0.2rem;
    color: #6b7280;
    font-size: 0.78rem;
    line-height: 1.3;
}

/* The grid's own Export command, kept only so the report's real Export to Excel button can click it
   from script (a programmatic SaveAsExcelFileAsync skips the grid's export pipeline). It is NOT a
   second button: without this rule it rendered as a small blank one beside the real one, which
   exported the same file. display:none is safe — a script click still fires on a hidden button, as
   TemplateCreateGrid's .template-export-hidden-trigger has shown. */
.compliance-export-hidden-trigger {
    display: none !important;
}

/* Report view tabs — the partition selector at the top of a report (Main / Educational).
   Base AND active state together in one place, deliberately: a modifier here with its base in a
   component style block is the .chip failure above, where the flag rendered as plain text.

   UNDERLINE tabs, not the round .report-bucket-pill: the hub's bucket pills sit directly above this
   row, and two rows of identical controls one above the other would read as one control that had
   wrapped. Same roles and aria-selected as those pills, so the accessibility story does not change
   with the shape. */
.report-view-tabs {
    display: flex;
    gap: 0.25rem;
    border-bottom: 1px solid #e5e7eb;
    margin-bottom: 1rem;
}

.report-view-tab {
    padding: 0.5rem 1rem;
    border: none;
    border-bottom: 2px solid transparent;
    background: none;
    color: #6b7280;
    font: inherit;
    font-weight: 500;
    cursor: pointer;
    /* Sit ON the container's border rather than above it, so the active tab joins the content. */
    margin-bottom: -1px;
}

.report-view-tab:hover {
    color: #374151;
}

.report-view-tab.is-active {
    color: #1d4ed8;
    border-bottom-color: #1d4ed8;
}

/* ContainerPicker (Components/Shared/Reports): one field for carts AND kits. Global rather than
   scoped because both popups render outside the component, where a scoped rule cannot reach.

   ONE color per kind, used on every surface that names it — the toggle, the chip, the summary and
   the tag at the end of each list row — so a kit reads as a kit at a glance anywhere it appears.
   Carts take the info blue the report already uses; kits take the purple the floor-restock chips
   use for kits (.tcfr-chip-kit). */
.cp-box {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    height: auto;
    min-height: 2.25rem;
    padding: 0.2rem 0.3rem 0.2rem 0.4rem;
    cursor: text;
}

.cp-values {
    display: flex;
    flex: 1 1 auto;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
    min-width: 0;
}

.cp-input {
    flex: 1 1 6rem;
    min-width: 6rem;
    border: none;
    outline: none; /* the .cp-box wrapper draws the ring on :focus-within (top of this file) */
    background: transparent;
    font: inherit;
    padding: 0.15rem 0.2rem;
}

/* Both kinds switched off: the field itself carries the message, since that is where the user's eye
   already is, and the report form disables Submit until a kind is back on. Amber, not red — this
   file keeps red for things that actually failed (see .chip--danger), and an empty choice is a
   caution the user resolves with one click. Text is the -on-subtle half of the pair for contrast. */
.cp-box.is-no-kind {
    border-color: var(--kendo-color-warning, #ffc107);
    background: var(--kendo-color-warning-subtle, #fff3cd);
}

.cp-box.is-no-kind .cp-input {
    cursor: default;
    text-overflow: ellipsis;
}

.cp-box.is-no-kind .cp-input::placeholder {
    color: var(--kendo-color-warning-on-subtle, #7a5a00);
    font-weight: 600;
    opacity: 1;
}

.cp-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    max-width: 14rem;
    padding: 1px 4px 1px 8px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 500;
    line-height: 1.4;
}

.cp-chip-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cp-chip-remove {
    border: none;
    background: none;
    padding: 0 0.2rem;
    color: inherit;
    font: inherit;
    line-height: 1;
    opacity: 0.6;
    cursor: pointer;
}

.cp-chip-remove:hover {
    opacity: 1;
}

/* "All carts": a stand-in for a lit kind with nothing picked, not a pick. Dashed and not removable,
   so it cannot be mistaken for one. */
.cp-chip-all {
    padding-right: 8px;
    border-style: dashed;
    background: transparent !important;
}

.cp-summary {
    padding-right: 8px;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
}

.cp-summary.is-open {
    box-shadow: 0 0 0 2px rgba(29, 78, 216, 0.25);
}

.cp-kinds {
    display: flex;
    flex: 0 0 auto;
    gap: 0.25rem;
    padding-left: 0.4rem;
    border-left: 1px solid #e5e7eb;
}

/* The kind toggles: DULL when off, filled in the kind's color when on. */
/* The border is the only thing that outlines an OFF toggle as a control, so it is held to the 3:1
   non-text contrast of SC 1.4.11 (#d1d5db measured 1.48:1 on white). */
.cp-kind-toggle {
    padding: 1px 10px;
    border: 1px solid var(--cc-control-border, #8C8C8C);
    border-radius: 999px;
    background: transparent;
    color: #6B7280;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
}

.cp-kind-toggle:hover {
    border-color: #6B7280;
    color: #4B5563;
}

/* Kind colors. Every lit surface for a kind reads from its block. */
.cp-kind-cart.cp-chip,
.cp-kind-cart.cp-kind-toggle.is-on,
.cp-kind-cart.cp-kind-tag {
    background: var(--kendo-color-info-subtle, #e3f2fd);
    color: var(--kendo-color-info-on-subtle, #10556f);
    border-color: var(--kendo-color-info, #3f9fda);
}

.cp-kind-kit.cp-chip,
.cp-kind-kit.cp-kind-toggle.is-on,
.cp-kind-kit.cp-kind-tag {
    background: #eae6f7;
    color: #5b3ea8;
    border-color: #a898d8;
}

.cp-kind-cart.cp-chip-all {
    color: var(--kendo-color-info-on-subtle, #10556f);
}

.cp-kind-kit.cp-chip-all {
    color: #5b3ea8;
}

/* Pharmacy trays, offered to pharmacy only. */
.cp-kind-tray.cp-chip,
.cp-kind-tray.cp-kind-toggle.is-on,
.cp-kind-tray.cp-kind-tag {
    background: #e3f2ec;
    color: #1d6a4f;
    border-color: #7fc2a6;
}

.cp-kind-tray.cp-chip-all {
    color: #1d6a4f;
}

/* The search list. */
.cp-list {
    min-width: 22rem;
    max-width: 32rem;
    max-height: 20rem;
    overflow-y: auto;
    padding: 0.25rem 0;
}

.cp-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.35rem 0.6rem;
    cursor: pointer;
}

/* :hover for the mouse and .is-highlighted for the keyboard, so pointing at rows costs no round
   trip to the server. */
.cp-option:hover,
.cp-option.is-highlighted {
    background: #f3f4f6;
}

.cp-option-check {
    flex: 0 0 1rem;
    color: #1d4ed8;
    font-weight: 700;
    text-align: center;
}

.cp-option-main {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-width: 0;
}

.cp-option-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cp-option.is-picked .cp-option-name {
    font-weight: 600;
}

.cp-option-parent {
    color: #6b7280;
    font-size: 0.75rem;
}

.cp-kind-tag {
    flex: 0 0 auto;
    padding: 0 6px;
    border: 1px solid transparent;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.cp-list-note {
    padding: 0.4rem 0.75rem;
    color: #6b7280;
    font-size: 0.78rem;
}

/* The "Carts (4)" list: every pick of one kind, in the order they were added, each removable. */
.cp-summary-panel {
    min-width: 16rem;
    max-width: 28rem;
    padding: 0.5rem 0.6rem;
}

.cp-summary-heading {
    margin-bottom: 0.4rem;
    color: #374151;
    font-size: 0.8rem;
    font-weight: 600;
}

.cp-summary-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    max-height: 12rem;
    overflow-y: auto;
}

/* LockNumberCell (Components/Shared/Locks): a grid cell's first lock number and its "+N" link on one
   line, and the popover list behind it. Global rather than scoped because the popover renders in
   Telerik's popup container, outside the component, where a scoped attribute does not reach. The link
   is pinned so a narrow column truncates the number before it pushes the only way to the rest onto a
   second line. */
.lock-number-cell {
    display: inline-flex;
    align-items: baseline;
    gap: .25rem;
    max-width: 100%;
}

.lock-number-cell__first {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.lock-number-cell__more {
    flex: 0 0 auto;
    padding: 0;
}

/* The "+N" panel (LockNumberCell). Global rather than in the component: one cell renders per grid row. */
.lock-number-cell__panel {
    padding: 0.5rem 0.75rem;
    max-width: min(320px, 90vw);
}

.lock-number-cell__panel:focus {
    outline: none; /* programmatic focus target (tabindex -1); nothing in it is operable */
}

.lock-number-cell__title {
    font-weight: 600;
    margin-bottom: 0.35rem;
}

.lock-number-list {
    display: grid;
    grid-template-columns: auto auto;
    gap: .25rem 1rem;
    margin: 0;
}

.lock-number-list dt {
    font-weight: 600;
}

.lock-number-list dd {
    margin: 0;
    font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------------------------------------
   Account time zone (AccountTimeZoneWarning, AccountTimeZoneDialog)
   --------------------------------------------------------------------------------------------- */

/* A missing account time zone, said out loud. Error palette because every time on the screen is
   wrong until it is fixed; the -on-subtle half for the text (see UIStyleGuide §1). */
.account-tz-warning {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.6rem 0.9rem;
    margin: 0 0 0.75rem;
    border-radius: 2px;
    border-left: 3px solid var(--kendo-color-error, #d9534f);
    background: var(--kendo-color-error-subtle, #fdecea);
    color: var(--kendo-color-error-on-subtle, #8a1c13);
    font-size: 0.9rem;
    line-height: 1.4;
}

.account-tz-warning > .k-svg-icon,
.account-tz-warning-icon {
    flex: 0 0 auto;
    margin-top: 0.15rem;
}

.account-tz-warning-body {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    flex: 1;
}

.account-tz-warning-title {
    font-weight: 600;
}

.account-tz-warning-actions {
    margin-top: 0.2rem;
}

/* ⚠ TELERIK'S "NOW" BUTTON READS THE SERVER'S CLOCK. Verified against Telerik.Blazor 15.0.1:
   TimeSelector.SetNow calls DateTime.Now, and on Blazor Server that runs on the web server, which
   is UTC in production. So "Now" filled in 8:11 PM for a Mountain-time account at 2:11 PM — and a
   scheduling dialog accepts it, because it is in the future. There is no parameter to supply a
   clock or hide the button, so it is hidden here, on every date/time and time picker in the app. */
.k-time-now {
    display: none !important;
}

/* Same defect in the calendar: its "Today" button and today highlight use the server's DATE, which
   after 6 PM Mountain is already tomorrow. Hidden only where a wrong day costs something — the
   scheduling pickers opt in with PopupClass="picker-account-clock" — because on the report date
   pickers it is off only in the evening and is a real convenience. */
.picker-account-clock .k-calendar-nav-today {
    display: none !important;
}

/* Report mailing list dialog (ReportMailingListDialog, 00172). In app.css rather than scoped: the
   Telerik dialog renders outside the component, where scoped styles never reach. */
.report-ml-add {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.report-ml-add-row {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.report-ml-error {
    color: #b00020;
    font-size: 0.85rem;
    font-weight: 600;
}

.report-ml-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-height: 50vh;
    overflow-y: auto;
}

.report-ml-person {
    border: 1px solid #d7dee7;
    border-radius: 6px;
    padding: 0.55rem 0.7rem;
    background: #fff;
}

.report-ml-person-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.report-ml-person-name {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem;
    min-width: 0;
    overflow-wrap: anywhere;
}

.report-ml-email {
    color: #6b7280;
    font-size: 0.85rem;
}

.report-ml-reports {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    margin-top: 0.4rem;
}

.report-ml-report {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.875rem;
    cursor: pointer;
}

/* Mailing list draft + review (00172). */
.report-ml-pause {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.7rem;
    margin-bottom: 0.75rem;
    border: 1px solid #d7dee7;
    border-radius: 6px;
    background: #f8fafc;
}

.report-ml-list.is-list-paused .report-ml-person {
    opacity: 0.7;
}

.report-ml-person.is-removed {
    opacity: 0.6;
    background: #f8fafc;
}

    .report-ml-person.is-removed .report-ml-person-name strong {
        text-decoration: line-through;
    }

.report-ml-tag {
    display: inline-block;
    padding: 0 0.4rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1.5;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

    .report-ml-tag.is-new { background: #C6EFCE; color: #006100; }
    .report-ml-tag.is-removed { background: #FFC7CE; color: #9C0006; }
    .report-ml-tag.is-changed { background: #DDEBF7; color: #1F4E79; }
    .report-ml-tag.is-paused { background: #FFEB9C; color: #9C5700; }

.report-ml-review {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    font-size: 0.875rem;
}

    .report-ml-review li {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 0.35rem;
        overflow-wrap: anywhere;
    }

.report-ml-review-detail {
    color: #6b7280;
}

.report-ml-plus {
    color: #006100;
    font-weight: 600;
}

.report-ml-minus {
    color: #9C0006;
    font-weight: 600;
}

/* ItemPicker (Item Utilization): items take the brand teal, kits keep the cp-kind-kit purple. */
.cp-kind-item.cp-chip,
.cp-kind-item.cp-kind-tag {
    background: #e6f4f1;
    color: #1f6b5c;
    border-color: #7fc4b4;
}

.cp-summary-clear {
    margin-left: 0.75rem;
    border: none;
    background: none;
    color: var(--kendo-color-primary, #3f51b5);
    font-size: 0.8rem;
    cursor: pointer;
    padding: 0;
}

/* Item Utilization: the hand-pick field steps back while Top / Bottom is choosing the items. */
.iu-picker-off .cp-box {
    opacity: 0.55;
}

.iu-dim {
    color: #6b7280;
    font-weight: 400;
}

.iu-kit-tag {
    margin-left: 0.4rem;
    font-size: 0.7rem;
}
