/* Theme overrides for Syncfusion components - loaded last to ensure highest specificity */

/* Fix for Syncfusion e-icons to inherit theme colors instead of staying black */
/* This file is loaded AFTER all other CSS including Syncfusion themes */

/* Force all e-icons to inherit color from parent */
.e-icons,
.e-icons::before,
.e-icons::after {
    color: inherit !important;
}

/* More specific selectors to ensure they apply in TreeView context */
.e-treeview .e-icons,
.e-treeview .e-icons::before,
.e-treeview .e-icons::after {
    color: inherit !important;
}

/* Ensure all icon types inherit color */
span.e-icons,
span.e-icons::before,
div.e-icons,
div.e-icons::before,
i.e-icons,
i.e-icons::before {
    color: inherit !important;
}

/* For any SVG-based icons */
.e-icons svg,
.e-icons svg path {
    fill: currentColor !important;
}

/* Override any hardcoded colors in Syncfusion's CSS */
.e-treeview .e-text-content .e-icons,
.e-treeview .e-text-content .e-icons::before {
    color: inherit !important;
}

/* Fix for parent items with children (those with expand/collapse icons) */
.e-treeview .e-list-item .e-icons.e-icon-collapsible,
.e-treeview .e-list-item .e-icons.e-icon-expandable,
.e-treeview .e-list-item .e-icons.e-icon-collapsible::before,
.e-treeview .e-list-item .e-icons.e-icon-expandable::before {
    color: inherit !important;
}

/* TreeView specific overrides */
.e-treeview .e-list-item .e-text-content div.e-list-icon.e-icons,
.e-treeview .e-list-item .e-text-content div.e-list-icon.e-icons::before {
    color: inherit !important;
}

/* Hover and active states - let JavaScript handle colors dynamically */
.e-treeview .e-list-item.e-hover .e-text-content div.e-list-icon.e-icons,
.e-treeview .e-list-item.e-hover .e-text-content div.e-list-icon.e-icons::before,
.e-treeview .e-list-item.e-active .e-text-content div.e-list-icon.e-icons,
.e-treeview .e-list-item.e-active .e-text-content div.e-list-icon.e-icons::before {
    color: inherit !important;
}

/* =========================================================================
   Scrollbar Theme Support - Light and Dark Themes
   ========================================================================= */

/* Scrollbar colours are derived from the element's own foreground, so they track whichever
   Syncfusion theme is active without a per-theme branch. The previous light/dark pair hardcoded
   eight greys and had no high-contrast case at all. */
:root {
    /* Scrollbar track (background) */
    --scrollbar-track-color: var(--tv-surface-alt);
    /* Scrollbar thumb (the draggable part) */
    --scrollbar-thumb-color: color-mix(in srgb, currentColor 30%, transparent);
    /* Scrollbar thumb on hover */
    --scrollbar-thumb-hover-color: color-mix(in srgb, currentColor 45%, transparent);
    /* Scrollbar thumb when active/dragging */
    --scrollbar-thumb-active-color: color-mix(in srgb, currentColor 60%, transparent);
}

/* =========================================================================
   AI Chat component CSS variables

   These names are kept (AiChat.razor.css alone references them ~86 times) but their values now
   resolve through the Tier-1 palette / Syncfusion theme variables instead of being a second
   hardcoded palette. That also removes the body[data-theme="dark"] duplicate below: data-theme is
   only ever "light" or "dark" (App.razor collapses high contrast onto one of the two), so the old
   branch left the high-contrast theme rendering light-theme greys.
   ========================================================================= */

:root {
    --color-bg-surface: var(--tv-surface);
    --color-bg-surface-alt: var(--tv-surface-alt);
    --color-border: var(--tv-color-border);
    --color-border-light: color-mix(in srgb, var(--tv-color-border) 50%, transparent);
    --color-text-primary: var(--color-sf-content-text-color, currentColor);
    --color-text-secondary: var(--tv-color-text-secondary);
    --color-bg-hover: var(--tv-color-hover);
    --color-primary: var(--tv-accent);
    --color-primary-dark: color-mix(in srgb, var(--tv-accent) 80%, black);
    --color-primary-light: color-mix(in srgb, var(--tv-accent) 10%, transparent);
    --color-code-bg: var(--tv-code-surface);
    --color-code-block-bg: var(--tv-code-block-surface);
    --color-code-block-text: var(--tv-code-block-text);
    --color-table-header-bg: color-mix(in srgb, currentColor 5%, transparent);
    --color-table-row-alt: color-mix(in srgb, currentColor 3%, transparent);
}

/* Base body styles. The surface and text colour come from the active Syncfusion theme rather
   than a hardcoded light pair plus a dark override. */
html, body {
    margin: 0;
    padding: 0;
    background-color: var(--tv-body-bg);
    color: var(--tv-body-fg);
}

/* The high-contrast theme ships **no** --color-sf-* custom properties at all (verified: zero
   definitions in highcontrast.css), and App.razor collapses it onto data-theme="dark". Without
   this branch every --color-sf-* above resolves to its light fallback, so a dark theme renders
   dark widgets on a light canvas.

   This is not a hand-rolled dark palette — the values still read the theme where it publishes
   one, so bootstrap5.3-dark continues to win with its own --color-sf-* values. Only the
   *fallback* differs, which is the one thing data-theme can still tell us.

   The selector must resolve on **html**, not body, for two reasons — App.razor sets data-theme
   on body, hence :has():
     1. A custom property is substituted at computed-value time on the element that declares it.
        The aliases above (--color-bg-surface: var(--tv-surface), :93) are declared at :root, so
        they are resolved once on html and descendants inherit the already-substituted result.
        Overriding --tv-surface on body therefore could not reach them, and AiChat's panels
        rendered white on a dark canvas.
     2. html's background is what propagates to the page canvas. A background set only on body
        paints the body box, leaving a light rim under high contrast. */
:root:has(body[data-theme="dark"]) {
    --tv-body-bg: color-mix(in srgb, var(--color-sf-content-bg-color, #1e1e1e) 96%, #000000);
    --tv-body-fg: var(--color-sf-content-text-color, #e0e0e0);
    --tv-surface: var(--color-sf-content-bg-color, #1e1e1e);
}

/* =========================================================================
   Brand primary — the Syncfusion "primary" is the TimeSolutions blue
   =========================================================================
   Every primary button, link, selected row, active nav item, focus ring and progress fill in
   the app takes its colour from the theme's --color-sf-primary family. Redefining that family
   here, in the one stylesheet that loads *after* the theme (see App.razor: the theme <link> is
   inserted immediately before this file), rebrands all of them at once. Components keep reading
   the theme's variable names; only what those names resolve to has changed. The app-level
   --palette-accent / --tv-accent alias --color-sf-primary, so they follow for free.

   Why the whole family and not just --color-sf-primary: bootstrap5.3.css does NOT derive its
   hover/pressed/light/lighter/dark/darker values from --color-sf-primary — each is a literal
   (#0b5ed7, #86b7fe, #cfe2ff, …). Override only the base and every hover flips back to Bootstrap
   blue. The derived values below are color-mix()ed from the chosen brand hue so the family stays
   internally consistent and the hue is still written down exactly once, in app.css. Four more
   variables outside the family (-content-bg-color-selected, -flyout-bg-color-pressed,
   -border-focus, -border-selected) are the same literal blue and are re-pointed at the end.

   Why BLUE, measured against white and the dark canvas #212529:

                              fill vs canvas    white text on fill   as link text
       light  --brand-blue          5.74               5.74               5.74   ✓ AA
       light  --brand-darkblue     11.98              11.98              11.98
       dark   --brand-blue          2.69               5.74               —  (links use -darker: 7.68)
       dark   --brand-darkblue      1.29                —                 1.29   ✗ invisible

   DARKBLUE is the flagship colour but disappears on the dark canvas, and running two hues meant
   the app looked like a different brand per theme. BLUE clears AA for text and links in light and
   carries white labels in dark, so it is the one primary for both. (Its dark fill-vs-canvas
   contrast of 2.69 is below the 3:1 component floor — accepted for the label contrast; Bootstrap's
   own dark primary sits at 3.43 / 4.50.) To change the brand primary later, change the one
   --tv-brand-primary line; nothing else references a hue.

   --color-sf-primary-shadow is an "r, g, b" triplet the theme feeds into rgba(); it cannot be
   derived with color-mix(), so it is the one place the hue is repeated, in a different notation.
   Keep it in step with --tv-brand-primary above it.

   The dark branch keys on data-theme like the block above, so highcontrast (which ships no
   --color-sf-* at all) also receives these values — meaning components' var(--color-sf-primary,
   #hex) fallbacks now resolve to brand blue there rather than to Bootstrap blue. Intended. */
:root {
    --tv-brand-primary: var(--brand-blue);
    --tv-brand-primary-shadow: 23, 104, 178;

    --color-sf-primary: var(--tv-brand-primary);
    --color-sf-primary-text-color: var(--brand-white);
    --color-sf-primary-shadow: var(--tv-brand-primary-shadow);

    /* Hover darkens, pressed darkens further — the same direction the theme takes. */
    --color-sf-primary-bg-color-hover:     color-mix(in srgb, var(--tv-brand-primary) 85%, black);
    --color-sf-primary-border-color-hover: color-mix(in srgb, var(--tv-brand-primary) 80%, black);
    --color-sf-primary-bg-color-pressed:     color-mix(in srgb, var(--tv-brand-primary) 75%, black);
    --color-sf-primary-border-color-pressed: color-mix(in srgb, var(--tv-brand-primary) 75%, black);
    --color-sf-primary-bg-color-disabled:    color-mix(in srgb, var(--tv-brand-primary) 65%, transparent);

    /* Tints, in the theme's own roles: -light is the soft border/outline (was #86b7fe),
       -lighter the selected/expanded wash (was #cfe2ff), -dark a mid fill, -darker the text that
       sits on the -lighter wash (was #052c65). Mixed toward the content surface rather than a
       fixed white so the wash sits on whatever the theme's panel colour is. */
    --color-sf-primary-light:   color-mix(in srgb, var(--tv-brand-primary) 45%, var(--color-sf-content-bg-color, white));
    --color-sf-primary-lighter: color-mix(in srgb, var(--tv-brand-primary) 15%, var(--color-sf-content-bg-color, white));
    --color-sf-primary-dark:    color-mix(in srgb, var(--tv-brand-primary) 90%, black);
    --color-sf-primary-darker:  color-mix(in srgb, var(--tv-brand-primary) 80%, black);

    /* Four siblings outside the -primary family are ALSO hardcoded Bootstrap blue in the theme
       (#0d6efd / #86b7fe) and drive the selected row in TreeView/ListView (the nav menu), the
       pressed flyout item, and the focus/selected input border. Left alone they stay Bootstrap
       blue next to a brand-blue primary — the mismatch the nav menu showed. */
    --color-sf-content-bg-color-selected: var(--tv-brand-primary);
    --color-sf-flyout-bg-color-pressed:   var(--tv-brand-primary);
    --color-sf-border-focus:    var(--color-sf-primary-light);
    --color-sf-border-selected: var(--color-sf-primary-light);
}

:root:has(body[data-theme="dark"]) {
    /* Same hue; only the tint roles invert. On a dark surface "darker" is the theme's *text* tint
       (was #6ea8fe): it must get lighter, not darker, to stay legible. 45 % toward white measures
       7.68 against #212529. */
    --color-sf-primary-lighter: color-mix(in srgb, var(--tv-brand-primary) 18%, var(--color-sf-content-bg-color, #212529));
    --color-sf-primary-darker:  color-mix(in srgb, var(--tv-brand-primary) 45%, white);
}

/* Modern browsers (Chrome, Edge, Safari, Opera) - Webkit scrollbars */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
}

*::-webkit-scrollbar {
    width: 12px;
    height: 12px;
}

*::-webkit-scrollbar-track {
    background: var(--scrollbar-track-color);
}

*::-webkit-scrollbar-thumb {
    background-color: var(--scrollbar-thumb-color);
    border-radius: 6px;
    border: 2px solid var(--scrollbar-track-color);
    /* The track token is a translucent color-mix, so without padding-box the thumb's own
       background paints through its border and the 2px inset pill gap disappears. */
    background-clip: padding-box;
}

*::-webkit-scrollbar-thumb:hover {
    background-color: var(--scrollbar-thumb-hover-color);
}

*::-webkit-scrollbar-thumb:active {
    background-color: var(--scrollbar-thumb-active-color);
}

/* Scrollbar corner (where horizontal and vertical scrollbars meet) */
*::-webkit-scrollbar-corner {
    background: var(--scrollbar-track-color);
}

/* Firefox - Standard scrollbar-color property */
* {
    scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
}

/* Specific styling for Syncfusion components with scrollable content */
.e-dialog .e-dlg-content::-webkit-scrollbar,
.e-popup::-webkit-scrollbar,
.time-registration-container::-webkit-scrollbar,
.e-content::-webkit-scrollbar {
    width: 12px;
    height: 12px;
}

.e-dialog .e-dlg-content::-webkit-scrollbar-track,
.e-popup::-webkit-scrollbar-track,
.time-registration-container::-webkit-scrollbar-track,
.e-content::-webkit-scrollbar-track {
    background: var(--scrollbar-track-color);
}

.e-dialog .e-dlg-content::-webkit-scrollbar-thumb,
.e-popup::-webkit-scrollbar-thumb,
.time-registration-container::-webkit-scrollbar-thumb,
.e-content::-webkit-scrollbar-thumb {
    background-color: var(--scrollbar-thumb-color);
    border-radius: 6px;
    border: 2px solid var(--scrollbar-track-color);
    background-clip: padding-box;
}

.e-dialog .e-dlg-content::-webkit-scrollbar-thumb:hover,
.e-popup::-webkit-scrollbar-thumb:hover,
.time-registration-container::-webkit-scrollbar-thumb:hover,
.e-content::-webkit-scrollbar-thumb:hover {
    background-color: var(--scrollbar-thumb-hover-color);
}

.e-dialog .e-dlg-content::-webkit-scrollbar-thumb:active,
.e-popup::-webkit-scrollbar-thumb:active,
.time-registration-container::-webkit-scrollbar-thumb:active,
.e-content::-webkit-scrollbar-thumb:active {
    background-color: var(--scrollbar-thumb-active-color);
}

/* High contrast mode support for scrollbars */
@media (prefers-contrast: high) {
    *::-webkit-scrollbar-thumb {
        border: 3px solid transparent;
        background-clip: padding-box;
    }
}

/* Forced colors mode (Windows High Contrast) */
@media (forced-colors: active) {
    *::-webkit-scrollbar {
        color-scheme: light dark;
    }
    *::-webkit-scrollbar-track {
        background: Canvas;
    }
    *::-webkit-scrollbar-thumb {
        background: ButtonText;
        border-color: Canvas;
    }
    *::-webkit-scrollbar-thumb:hover,
    *::-webkit-scrollbar-thumb:active {
        background: Highlight;
    }
}

/* =========================================================================
   Sidebar fix — preserve position:fixed inside pushed content
   =========================================================================
   Syncfusion SfSidebar adds .e-content-animation to the pushed content area
   and may apply a CSS transform for the push animation. Any CSS transform on
   an ancestor creates a new containing block for position:fixed descendants,
   making them behave like position:absolute and scroll with the page.
   Resetting to transform:none here restores correct fixed-positioning behavior
   while the margin-based push animation continues to work.
   ========================================================================= */
.e-content-animation {
    transform: none !important;
}

/* =========================================================================:
   Global Reusable Components - Theme Aware
   ============================================================================ */

/* Section Header - used throughout the application for consistent section titles */
.section-header {
    font-size: 16px;
    font-weight: 600;
    margin: 0 0 12px 0;
    border-bottom: 1px solid currentColor;
    padding-bottom: 8px;
}

/* High contrast mode support */
@media (forced-colors: active) {
    .section-header {
        color: CanvasText;
        border-bottom-color: CanvasText;
    }
}

/* =========================================================================
   EntityList - hide Syncfusion's built-in pager
   =========================================================================
   The grid uses a custom pager rendered in the TopBar (page input, prev/next
   buttons, page-size dropdown). The built-in .e-gridpager is redundant and
   must be hidden via global CSS — Blazor CSS isolation's ::deep does not
   reach into third-party component subtrees like SfGrid's rendered DOM.
   ========================================================================= */
.tv-entity-grid-wrapper .e-gridpager {
    display: none !important;
}

/* =========================================================================
   EntityList - group drop area
   =========================================================================
   Syncfusion renders .e-groupdroparea into the grid's own DOM subtree;
   Blazor scoped CSS cannot reach it, so styling lives here alongside the
   pager override above.
   ========================================================================= */
.tv-entity-grid-wrapper .e-groupdroparea {
    padding: var(--tv-space-2) var(--tv-space-3);
    font-size: var(--tv-text-body);
}

/* =========================================================================
   Main-layout sidebar z-index — must render above the sticky TopBar
   (z-index: 1000) on mobile where sidebar type is Over.
   Scope this override to the layout container to avoid affecting other
   Syncfusion sidebars.
   ========================================================================= */
#contentContainer .e-sidebar {
    z-index: var(--tv-z-sidebar) !important;
}

/* =========================================================================
   Modal dialogs must clear the app chrome. Syncfusion computes a dialog
   z-index of 1000 and writes it inline, which loses to the sidebar override
   directly above — so a modal renders behind the navigation menu.

   Only the container is lifted, never the overlay or the dialog itself:
   Syncfusion sets the overlay to exactly one below the dialog, and since
   both are children of the container, raising the container carries them up
   as a stacking context with that relative order intact. Overriding the
   inner two as well collapses the gap and the overlay covers the dialog,
   which presents as an unresponsive, greyed-out modal.
   !important is unavoidable here: nothing else outranks an inline style.
   ========================================================================= */
.e-dlg-container {
    z-index: var(--tv-z-dialog, 1100) !important;
}

/* The error dialog clears everything, including the toasts and any dialog that raised it — an
   exception must never be reported behind the screen that caused it. The selector targets the
   *container*, because the rule above is a blanket !important that a ZIndex on the SfDialog
   itself cannot beat. Same invariant as above: lift the container only. */
.e-dlg-container:has(.error-dialog) {
    z-index: var(--tv-z-error-dialog, 1400) !important;
}
