/* =========================================================================
   Staff app (XAF Blazor) in the customer portal's look. The shell, page header, cards, KPI tiles, lists and
   timelines come from TicketingSystem.UI.Shared (shell.css, content.css); this file only fits XAF's own
   pieces into them: the fixed-height shell (XAF pins <body>), the view toolbar, list views (DxGrid), detail
   views (DxFormLayout groups as cards), popups and the sign-in page. Light and dark: tokens only.
   ========================================================================= */

/* ---------- shell: fixed to the window, the view area scrolls ----------- */
/* The root also carries XAF's "app" class (its scripts look for it); keep the portal grid and page colour. */
.app.ts-xaf-shell {
    display: grid;
    background: var(--ts-surface-page);
    color: var(--ts-text);
}

.ts-xaf-shell {
    height: 100%;
    min-height: 0;
    grid-template-rows: var(--ts-header-height) minmax(0, 1fr);
    overflow: hidden;
    font-size: var(--ts-font-size-md);
}

.ts-xaf-shell .app-sidebar { min-height: 0; overflow: hidden; }
.ts-xaf-shell .app-sidebar__nav { position: static; max-height: none; flex: 1 1 auto; min-height: 0; }
.ts-xaf-shell .app-main { min-height: 0; overflow: hidden; }
.ts-xaf-shell .app-main:focus { outline: none; }

.ts-view {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding-bottom: 0;
}

.ts-view--mdi { overflow: auto; }

.ts-view-content {
    flex: 1 1 auto;
    min-height: 0;
    overflow: auto;
    padding-bottom: var(--ts-space-5);
}

/* List views fill the view area and scroll inside the grid (XAF: .app .main-content > .grid-content); so do
   full-height viewers (dashboard, report preview: one layout item). The footer stays under them. */
.ts-view-content > .grid-content { height: 100%; min-height: 300px; }

/* Forms and the home page scroll as a page instead, with the footer after the content like the portal's. */
.ts-xaf-shell .app-main:has(.ts-view-content .detail-view-content):not(:has(.xaf-single-layout-item)) { overflow-y: auto; }
.ts-xaf-shell .app-main:has(.ts-view-content .detail-view-content):not(:has(.xaf-single-layout-item)) :is(.ts-view, .ts-view-content) {
    flex: 1 0 auto;
    overflow: visible;
}

/* Under a filling list the footer would take two lines on phones; skip it there. */
@media (max-width: 767.98px) {
    .ts-xaf-shell .app-main:has(.ts-view-content > .grid-content, .xaf-single-layout-item) .app-footer { display: none; }
}

/* Links like the portal's: accent colour, underlined on hover only (Fluent underlines them always). */
.ts-xaf-shell :where(a:not(.dxbl-btn):not(.app-sidebar__nav-link)) { color: var(--ts-accent-text); text-decoration: none; }
.ts-xaf-shell :where(a:not(.dxbl-btn):not(.app-sidebar__nav-link)):hover { text-decoration: underline; }
.ts-xaf-shell a.app-header__brand,
.ts-xaf-shell a.app-header__user-name,
.ts-xaf-shell a.kpi-card-link { color: var(--ts-text); }
.ts-xaf-shell a.app-header__brand:hover,
.ts-xaf-shell a.kpi-card-link:hover,
.ts-xaf-shell a.app-sidebar__nav-link:hover { text-decoration: none; }
/* Reference links in grid cells keep the row's colour (settled rows are muted, components.css .ts-row--settled). */
.ts-xaf-shell .dxbl-grid td a:not(.dxbl-btn) { color: inherit; }

/* XAF's header tools (notifications bell, quick access) at the foot of the navigation. */
.ts-xaf-shell .app-sidebar__tools { padding: 8px 12px; border-top: 1px solid var(--ts-border); }
.ts-xaf-shell .app-sidebar__tools:empty { display: none; }
.ts-xaf-shell .app-sidebar__tools .dxbl-toolbar { background: transparent; }

/* ---------- page header + toolbar bar ------------------------------------ */
.ts-page-header { margin-bottom: var(--ts-space-4); }
.ts-back:empty { display: none; }
.ts-ticket-meta { font-size: 0.875rem; }
.ts-unsaved { color: var(--ts-text-muted); font-size: 0.875rem; font-style: italic; white-space: nowrap; }

/* XAF's NavigateBack button as the portal's "← All tickets" crumb link. */
.ts-back .dxbl-btn {
    gap: 4px;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ts-text-muted);
    font-size: 0.8125rem;
    font-weight: 400;
    min-height: 0;
    box-shadow: none;
}

.ts-back .dxbl-btn:hover { color: var(--ts-accent-text); text-decoration: underline; background: transparent; }

/* The view toolbar sits in the portal's filter bar (content.css .filters look). */
.ts-toolbar {
    margin-bottom: var(--ts-space-4);
    padding: 6px var(--ts-space-3);
    background: var(--ts-surface);
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-radius-md);
}

.ts-toolbar:empty { display: none; }
.ts-toolbar .dxbl-toolbar { background: transparent; }

/* The page's main "New" action is its primary button, like the portal's "Submit a ticket". */
.ts-xaf-shell .ts-toolbar .dxbl-btn[data-action-name="New"] {
    background: var(--ts-accent);
    border-color: var(--ts-accent);
    color: var(--ts-on-accent);
}

.ts-xaf-shell .ts-toolbar .dxbl-btn[data-action-name="New"]:hover { background: var(--ts-accent-hover); border-color: var(--ts-accent-hover); }
.ts-xaf-shell .ts-toolbar .dxbl-btn[data-action-name="New"] img.dxbl-image { filter: brightness(0) invert(1); }

/* Monochrome action icons (the portal's icons are monochrome Bootstrap Icons); XAF's Fluent set is coloured. */
.ts-xaf-shell { --ts-icon-filter: grayscale(1) brightness(0.55); }
body.dxbl-theme-dark .ts-xaf-shell { --ts-icon-filter: grayscale(1) brightness(1.9); }
:is(.ts-xaf-shell, .dxbl-modal) .dxbl-toolbar .dxbl-btn:not([data-action-name="New"]) img.dxbl-image,
.ts-xaf-shell .dxbl-fl .dxbl-btn img.dxbl-image { filter: var(--ts-icon-filter, grayscale(1) brightness(0.55)); }

/* Save / Save and New under the form, bottom-right like the portal's submit buttons; sticky so long forms
   keep them in reach, on a solid bar so nothing shows through. It sits in the flow after the last card, so at
   the end of the page it never covers content. Empty (list views) = hidden. */
.ts-form-actions {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    justify-content: flex-end;
    margin-top: var(--ts-space-4);
    padding: var(--ts-space-3) 0;
    border-top: 1px solid var(--ts-border);
    background: var(--ts-surface-page);
}

.ts-form-actions:empty { display: none; }
.ts-form-actions .dxbl-toolbar { background: transparent; }

/* ---------- list views (DxGrid) like the portal's grids --------------------- */
.ts-view-content .dxbl-grid {
    border-color: var(--ts-border);
    border-radius: var(--ts-radius-md);
    background: var(--ts-surface);
}

/* SLA due + badge wrap in narrow cells instead of being clipped (same as the portal lists). */
.ts-view-content .dxbl-grid .ts-sla { flex-wrap: wrap; row-gap: 2px; }

/* Cell classes from GridCellStyleController / ClampedTextPropertyEditor: the record key in the accent colour,
   codes on one line, titles at most two lines. On the tinted rows the key takes the stronger accent (4.5:1). */
.ts-view-content .dxbl-grid td.ts-cell-key { color: var(--ts-accent-text); font-weight: 600; }
.ts-view-content .dxbl-grid :is(.ts-row--danger, .ts-row--warning) > td.ts-cell-key { color: var(--ts-accent-text-strong); }
.ts-view-content .dxbl-grid td:is(.ts-cell-key, .ts-cell-code) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }

/* Column filter funnels appear on hover (or while a filter is set), not in every header at rest. */
.ts-view-content .dxbl-grid th:not(:hover):not(:focus-within) .dxbl-grid-filter-menu-funnel-btn:not(.dxbl-grid-filter-menu-funnel-btn-filled):not(.dxbl-grid-filter-menu-funnel-btn-active) { opacity: 0; }

/* ---------- detail views + popups: layout groups as the portal's info cards ---------- */
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-group {
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-radius-md);
    background: var(--ts-surface);
    box-shadow: none;
    overflow: visible;
}

/* Group caption = the portal's card label ("DETAILS"): small, uppercase, muted. */
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-group > .dxbl-group-header {
    padding: var(--ts-space-4) var(--ts-space-5) 0;
    min-height: 0;
    border: 0;
    background: transparent;
    color: var(--ts-text-muted);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Layout items pad themselves by 6px: 18px here lines the fields up with the card label. */
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-group > .dxbl-group-body { padding: var(--ts-space-2) 18px var(--ts-space-4); }

/* Read-only fields (AllowEdit false, no permission) read like the portal's info lists: text, not an empty box. */
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-text-edit.dxbl-disabled[is-read-only] {
    border-color: transparent;
    background: transparent;
    box-shadow: none;
}

:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-text-edit.dxbl-disabled[is-read-only] :is(input, textarea) {
    padding-left: 0;
    color: var(--ts-text);
    -webkit-text-fill-color: var(--ts-text);
    opacity: 1;
}

/* Multi-line text too (e.g. the anonymize confirmation): lines of text as tall as their content, no grey box. */
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-text-edit.dxbl-disabled[is-read-only] textarea {
    padding-left: 0;
    color: var(--ts-text);
    -webkit-text-fill-color: var(--ts-text);
    opacity: 1;
    resize: none;
    field-sizing: content;
}

:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-text-edit.dxbl-disabled[is-read-only] .dxbl-btn { display: none; }

/* Read-only references and files render through a template (lookup name, file link): text and link colours too,
   not the disabled grey (2.4:1, below AA). */
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-text-edit.dxbl-disabled[is-read-only] .dxbl-text-edit-template { color: var(--ts-text); }
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-text-edit.dxbl-disabled[is-read-only] .dxbl-text-edit-template a { color: var(--ts-accent-text); }

/* An empty read-only value shows the portal's dash. */
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-text-edit.dxbl-disabled[is-read-only][field-text=""] input { display: none; }
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-text-edit.dxbl-disabled[is-read-only][field-text=""]::after {
    content: "\2014";
    color: var(--ts-text-muted);
}

/* Field captions like the portal's info-list terms. */
:is(.ts-view-content, .dxbl-modal-body) .dxbl-fl .dxbl-fl-cpt { color: var(--ts-text-muted); font-weight: 500; }

/* Tabbed groups (comments, work log, nested lists) sit in a card too. */
.ts-view-content .dxbl-fl .dxbl-fl-gt > .dxbl-tabs {
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-radius-md);
    background: var(--ts-surface);
    padding: var(--ts-space-2) var(--ts-space-4) var(--ts-space-4);
}

.ts-view-content .dxbl-fl .dxbl-fl-gt .dxbl-tabs-content-panel { background: transparent; border: 0; }

/* Hand-made module layouts without captioned groups (e.g. security roles): the whole form is one card.
   (Not pages that draw their own header and cards, like the staff home, nor full-size single controls:
   report viewer / designer, dashboards.) */
.ts-view-content .detail-view-content > .dxbl-fl:not(:has(.dxbl-group, .ts-page-header, .xaf-single-layout-item)) {
    background: var(--ts-surface);
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-radius-md);
    padding: var(--ts-space-4) 18px;
}

.ts-view-content .detail-view-content > .dxbl-fl:not(:has(.dxbl-group, .ts-page-header, .xaf-single-layout-item)) .dxbl-fl-gt > .dxbl-tabs { border: 0; padding: 0; }

/* Help lines (XAF StaticText items, e.g. under each Ticket Emails switch): secondary text, close to their editor. */
.ts-view-content .xaf-static-text {
    color: var(--ts-text-secondary);
    font-size: var(--ts-font-size-sm);
}

/* ---------- popups (XAF PopupWindowTemplate on DxPopup) ---------------------------- */
.dxbl-theme-fluent .dxbl-modal .dxbl-modal-content { border-radius: var(--ts-radius-md); }
.dxbl-modal .dxbl-modal-header { font-family: var(--ts-font-family); font-weight: 600; }

/* ---------- theme settings (gear): a drop-down card instead of XAF's side sheet ---------- */
.ts-xaf-shell .theme-settings.show-dropdown .settings-bar {
    top: calc(var(--ts-header-height) - 4px);
    right: var(--ts-space-3);
    width: 280px;
    height: auto;
    max-height: calc(100% - var(--ts-header-height) - var(--ts-space-4));
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-radius-md);
    box-shadow: var(--ts-shadow-raised);
}

.ts-xaf-shell .settings-bar * { font-family: var(--ts-font-family); }
/* ---------- notifications --------------------------------------------------- */
/* XAF's messages ("Saved", warnings, errors) as the portal's pastel toasts: a tinted card with the icon in the
   tone colour and normal text, instead of a solid bar with white text (XAF sets .text-white with !important). */
.xaf-alert.alert {
    --ts-alert-tone: var(--ts-tone-info);
    border: 1px solid var(--ts-border);
    border-radius: var(--ts-radius-md);
    box-shadow: var(--ts-shadow-raised);
    background: var(--ts-surface) !important;
}

.xaf-alert.alert-success { --ts-alert-tone: var(--ts-tone-success); }
.xaf-alert.alert-warning { --ts-alert-tone: var(--ts-tone-warning); }
.xaf-alert.alert-danger { --ts-alert-tone: var(--ts-tone-danger); }

@supports (color: color-mix(in srgb, red 50%, blue)) {
    .xaf-alert.alert {
        border-color: color-mix(in srgb, var(--ts-alert-tone) 40%, transparent);
        background: color-mix(in srgb, var(--ts-alert-tone) 12%, var(--ts-surface)) !important;
    }
}

.xaf-alert.alert,
.xaf-alert.alert.text-white { color: var(--ts-text) !important; }
.xaf-alert.alert > .xaf-image { color: var(--ts-alert-tone); }
.xaf-alert .xaf-alert-close .xaf-image { color: var(--ts-text-muted) !important; }

/* ---------- sign-in -------------------------------------------------------- */
.ts-login .logon-toolbar { margin-top: var(--ts-space-2); }

.ts-login__separator {
    display: flex;
    align-items: center;
    gap: var(--ts-space-3);
    margin: var(--ts-space-4) 0;
    color: var(--ts-text-muted);
    font-size: 0.8125rem;
}

.ts-login__separator::before,
.ts-login__separator::after { content: ""; flex: 1; border-top: 1px solid var(--ts-border); }
