/* ============================================================
   Harmony Core — Brand Tokens (ERP green/lime family)
   Mirrors HarmonyHR's token approach (HARMONY_DESIGN.md §2.1/§2.4)
   but in Core's product palette: forest #2e7d32 -> lime #9ccc65,
   taken from the harmony-core brand mark.
   ============================================================ */
:root {
    --harmony-primary: #2e7d32;  /* Primary: buttons, links, header, spinners */
    --harmony-accent:  #9ccc65;  /* Accent: gradients, highlights */
    --harmony-mid:     #43a047;  /* Mid green: hovers, secondary fills */
    --harmony-deep:    #1b5e20;  /* Chrome: dense headings, dark green text */
    --harmony-ink:     #263238;  /* Body text */
    --harmony-surface: #f4f7f4;  /* App background (faint green-grey) */
    --harmony-border:  #e2e8e2;  /* Hairlines */
    --harmony-hero:    linear-gradient(135deg, #2e7d32 0%, #9ccc65 100%);

    /* Shadows (HarmonyPx DESIGN.md §2.4): "whisper" for cards/buttons, "lift" for dialogs/dropdowns. */
    --harmony-shadow:    0 1px 2px rgba(15, 23, 42, .04), 0 2px 4px rgba(15, 23, 42, .04);
    --harmony-shadow-lg: 0 4px 12px rgba(15, 23, 42, .08), 0 1px 2px rgba(15, 23, 42, .06);

    /* Gradients (HarmonyPx DESIGN.md §2.2): header bar, and the diagonal brand variant. */
    --harmony-gradient:       linear-gradient(90deg, var(--harmony-primary) 0%, var(--harmony-accent) 100%);
    --harmony-gradient-brand: linear-gradient(135deg, var(--harmony-deep) 0%, var(--harmony-primary) 55%, var(--harmony-accent) 100%);

    /* Bridge: map Radzen's primary token to the brand green so existing
       var(--rz-primary) references and Radzen components inherit the brand. */
    --rz-primary: var(--harmony-primary);
    --rz-primary-dark: var(--harmony-deep);
    --rz-primary-light: var(--harmony-mid);
    --rz-primary-lighter: rgba(46, 125, 50, 0.12);  /* selected nav item, pager, hover washes */
    --rz-on-primary-lighter: var(--harmony-primary); /* text/icon on those washes */
    --rz-primary-darker: var(--harmony-deep);
    --rz-success: var(--harmony-primary);

    /* Secondary (View buttons): Radzen's default is pink, which fights the green brand.
       Teal sits beside green on the wheel and stays distinct from the primary Add/Save green. */
    --harmony-secondary: #00838f;
    --rz-secondary: var(--harmony-secondary);
    --rz-secondary-light: #26a0ab;
    --rz-secondary-lighter: rgba(0, 131, 143, 0.12);
    --rz-secondary-dark: #006670;
    --rz-secondary-darker: #004d54;
    --rz-on-secondary-lighter: var(--harmony-secondary);

    /* Chart palette (DESIGN.md §2.6 / §10.17). Categorical series — pie slices, multi-series charts — take
       these in order. Anchored on the brand greens (primary, accent, deep) and extended with hues that sit
       with them (gold, teal, slate, taupe, blue); neighbours are deliberately far apart, and primary/deep
       are 6 slots apart so the two close greens never touch. */
    --harmony-chart-1: var(--harmony-primary); /* forest green */
    --harmony-chart-2: #f9a825;                /* gold */
    --harmony-chart-3: #00838f;                /* teal */
    --harmony-chart-4: var(--harmony-accent);  /* lime */
    --harmony-chart-5: #546e7a;                /* slate */
    --harmony-chart-6: #8d6e63;                /* taupe */
    --harmony-chart-7: var(--harmony-deep);    /* deep green */
    --harmony-chart-8: #0277bd;                /* blue */
    /* Colours that carry meaning — the same in every chart, and the same as the badges. */
    --harmony-chart-success: var(--rz-success);
    --harmony-chart-fail:    var(--rz-danger);

    /* Bridge: Radzen charts (default "pastel" scheme) colour series N / slice N with var(--rz-series-N),
       so pointing those at the palette re-themes every chart with no per-chart Fill/Stroke. Radzen
       defines 24 slots; the palette repeats every 8. */
    --rz-series-1:  var(--harmony-chart-1);
    --rz-series-2:  var(--harmony-chart-2);
    --rz-series-3:  var(--harmony-chart-3);
    --rz-series-4:  var(--harmony-chart-4);
    --rz-series-5:  var(--harmony-chart-5);
    --rz-series-6:  var(--harmony-chart-6);
    --rz-series-7:  var(--harmony-chart-7);
    --rz-series-8:  var(--harmony-chart-8);
    --rz-series-9:  var(--harmony-chart-1);
    --rz-series-10: var(--harmony-chart-2);
    --rz-series-11: var(--harmony-chart-3);
    --rz-series-12: var(--harmony-chart-4);
    --rz-series-13: var(--harmony-chart-5);
    --rz-series-14: var(--harmony-chart-6);
    --rz-series-15: var(--harmony-chart-7);
    --rz-series-16: var(--harmony-chart-8);
    --rz-series-17: var(--harmony-chart-1);
    --rz-series-18: var(--harmony-chart-2);
    --rz-series-19: var(--harmony-chart-3);
    --rz-series-20: var(--harmony-chart-4);
    --rz-series-21: var(--harmony-chart-5);
    --rz-series-22: var(--harmony-chart-6);
    --rz-series-23: var(--harmony-chart-7);
    --rz-series-24: var(--harmony-chart-8);
}

/* A chart whose series are Success then Fail (in that order): series 1/2 take the meaning colours. */
.hc-chart-outcome {
    --rz-series-1: var(--harmony-chart-success);
    --rz-series-2: var(--harmony-chart-fail);
}

/* Colour key beside a chart (e.g. the Actions Breakdown list under its pie): the swatch carries the
   same rz-series-item-N class as slice N, so it can never drift from the chart. */
.hc-chart-swatch {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    margin-right: 0.5rem;
    vertical-align: middle;
}

html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    color: var(--harmony-primary);
}

.btn-primary {
    color: #fff;
    background-color: var(--harmony-primary);
    border-color: var(--harmony-deep);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

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

.invalid {
    outline: 1px solid red;
}

.validation-message {
    color: red;
}

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

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

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

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

.loading-progress {
    position: relative;
    display: block;
    width: 8rem;
    height: 8rem;
    margin: 20vh auto 1rem auto;
}

    .loading-progress circle {
        fill: none;
        stroke: #e0e0e0;
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: var(--harmony-primary);
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Loading");
    }

code {
    color: #c02d76;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ============================================================
   App shell header — brand green gradient (indigo->teal in HR
   becomes forest->lime here). White content on the bar.
   ============================================================ */
.rz-header {
    background: linear-gradient(90deg, var(--harmony-primary) 0%, var(--harmony-accent) 100%);
    color: #fff;
}
.rz-header .rz-label,
.rz-header .rz-text,
.rz-header a {
    color: #fff;
}

/* =====================================================================
   Auth pages (login / forgot-password / select-organization) — ported
   from HarmonyHR's .hr-auth-* (HARMONY_DESIGN.md §8.1). The soft-oval
   card shell holds the brand half + form half; recolored to Core green
   via the inline hero gradient on each page.
   ===================================================================== */
.core-auth-shell {
    width: 100%;
    max-width: 60rem;
    min-height: 33rem;
    border-radius: 2.75rem;
    overflow: hidden;
}

/* Zero the auth layout's RadzenBody padding so the 100vh wrapper centers. */
.core-auth-layout .rz-body {
    padding: 0;
}

/* Vertically + horizontally center the oval card in the viewport. */
.core-auth-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    width: 100%;
    padding: 1.5rem 0;
    box-sizing: border-box;
}

/* Vertically center each half's content against the oval's full height. */
.core-auth-shell > [class*="rz-col"] > .rz-card {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* Stretch form controls + submit button to the form width. */
.core-auth-form .rz-form-field,
.core-auth-form .rz-textbox,
.core-auth-form .rz-password,
.core-auth-form .rz-login {
    width: 100%;
}
.core-auth-form .rz-button.core-auth-submit {
    width: 100%;
}

/* Brand-green the auth text/link buttons. Radzen's text-variant primary keeps
   its built-in indigo (#4340d2) and RadzenLogin's reset link renders pink — both
   reference Radzen's own color, not var(--rz-primary), so override them here.
   Filled buttons (Sign In / Reset Password) are excluded and stay green-filled. */
.core-auth-shell .rz-button:not(.rz-variant-filled) {
    color: var(--harmony-primary) !important;
}
.core-auth-shell .rz-button:not(.rz-variant-filled):hover {
    background-color: rgba(46, 125, 50, 0.10) !important;
}

/* In-app loader (Security/data pages) */
.hc-loader {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 3rem 1rem;
}
.hc-loader-text {
    color: var(--harmony-primary);
    font-weight: 600;
}

/* Expandable-row detail tables (Users_View etc.) */
table.hc-detail {
    width: 100%;
    border-collapse: collapse;
}
table.hc-detail th {
    text-align: left;
    font-weight: 600;
    color: var(--harmony-deep, #1b5e20);
    padding: 0.25rem 1rem 0.25rem 0;
    white-space: nowrap;
    vertical-align: top;
    width: 12rem;
}
table.hc-detail td {
    padding: 0.25rem 0;
}

/* DESIGN.md §9.5 detail template inside a grid whose table is wider than its scroll viewport (the user
   has picked extra columns, or a narrow window): without this the expanded row's content is laid out at
   the full TABLE width, so its right half (form fields, the nested grid's column picker) runs past the
   grid's right border until the user scrolls. The scroll viewport becomes a size container and the
   template is sized to it (100cqw = the visible width, minus the cell padding) and pinned to its left
   edge, so the detail reads at the grid's visible width wherever the columns are scrolled to.
   Opt in per expandable grid with class="hc-fit-detail". Ported from HarmonyPx px-fit-detail. */
.hc-fit-detail .rz-data-grid-data {
    container-type: inline-size;
}
/* Radzen clips every cell (overflow: hidden); on the expanded row's cell that would make the CELL the
   sticky element's scroll container, so the template could never follow the grid's horizontal scroll. */
.hc-fit-detail .rz-expanded-row-content > td {
    overflow: visible;
}
/* Radzen also sets white-space: nowrap on every grid td, which the template inherits: a long field label
   ("Change Password upon Login") then cannot wrap and runs under the control beside it. The detail is a
   form, not a cell — let its text wrap (nested grids set nowrap on their own cells again). */
.hc-fit-detail .rz-expanded-row-content > td > .rz-expanded-row-template {
    white-space: normal;
    position: sticky;
    left: 0;
    width: calc(100cqw - 16px);
    max-width: calc(100cqw - 16px);
    box-sizing: border-box;
}

/* DESIGN.md §10.2 validator placement: dialog validators are INLINE (no Popup="true"). Radzen positions the
   inline message absolutely, so it would sit on top of the next form row; in flow it takes its own line
   under the input, inside the input's column — it cannot be clipped by the dialog edge, cannot cover a
   neighbouring label, and disappears as soon as the field is valid (validated text inputs set Immediate). */
.rz-dialog .rz-messages-error:not(.rz-message-popup) {
    position: static;
    display: block;
}

/* Account Policy parameter rows (HarmonyHR-style: name left, value right, separated). */
.hc-param-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.55rem 0.25rem;
    border-bottom: 1px solid var(--rz-base-300, #e5e7eb);
}
.hc-param-row:last-child {
    border-bottom: none;
}
.hc-param-row > span {
    color: var(--rz-text-color, #374151);
}

/* Collapse to a single rounded card once the columns stack (md = 768px). */
@media (max-width: 767px) {
    .core-auth-shell {
        max-width: 26rem;
        min-height: 0;
        border-radius: 2rem;
    }
    .core-auth-page {
        min-height: 0;
        padding: 2rem 0;
    }
}

/* Respect the OS "reduce motion" setting (HarmonyPx DESIGN.md §7). */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}