﻿html, body {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    overflow: hidden;
    height: 100%;
}

#app {
    height: 100%;
}

/* Fill background during loader->layout transition based on theme preference */
    html[data-dark-mode="true"] body {
        background-color: #1f1f1f;
    }

html[data-dark-mode="false"] body {
    background-color: #f9f9f9;
}

/* Fallback only: index.html always sets data-dark-mode before the first paint (cached choice,
   else the OS/browser setting), so this applies only when that script could not run. */
html:not([data-dark-mode]) body {
    background-color: #f9f9f9;
}

h1:focus {
    outline: none;
}

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

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

.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;
}

/*  Error surfaces: the runtime strip and the boot-failure screen, both driven by
    js/bootRecovery.js. Colours are keyed to data-dark-mode rather than the MudBlazor palette --
    these show up when the app is broken or has not booted, so they cannot depend on anything the
    running app sets. Contrast is AA in both themes on the fixed colours below. */
#blazor-error-ui {
    display: none; /* the framework flips this to block */
    position: fixed;
    left: 50%;
    bottom: 1rem;
    transform: translateX(-50%);
    width: min(46rem, calc(100vw - 2rem));
    z-index: 2000; /* over MudBlazor dialogs (1300) and snackbars (1400) */
    /* MudBlazor.min.css also styles #blazor-error-ui (a red full-width strip) and its .reload /
       .dismiss children. It loads first, so the container has to be reset back to a bare box or its
       red background and padding frame the bar below. */
    padding: 0;
    background: none;
    box-shadow: none;
    color: inherit;
}

/* The boot-failure screen already states this, in full. */
html[data-anv-boot-failed] #blazor-error-ui {
    display: none !important;
}

#blazor-error-ui .anv-errbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.75rem 0.875rem;
    border-radius: 0.5rem;
    background-color: #2b2b30;
    box-shadow: 0 0.375rem 1.5rem rgba(0, 0, 0, 0.28);
    color: #f4f4f5;
    font-size: 0.9375rem;
    line-height: 1.35;
}

#blazor-error-ui .anv-errbar__icon {
    flex: 0 0 auto;
    width: 1.375rem;
    height: 1.375rem;
    fill: #ffb4a9;
}

#blazor-error-ui .anv-errbar__text {
    flex: 1 1 12rem;
}

#blazor-error-ui .anv-errbar__btn {
    flex: 0 0 auto;
    padding: 0.375rem 0.875rem;
    text-decoration: none; /* MudBlazor underlines #blazor-error-ui .reload */
    border: 0;
    border-radius: 0.375rem;
    background-color: #94bbf7;
    color: #10233f;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

    #blazor-error-ui .anv-errbar__btn:hover {
        background-color: #b8d1fa;
    }

#blazor-error-ui .anv-errbar__dismiss {
    flex: 0 0 auto;
    position: static; /* MudBlazor pins #blazor-error-ui .dismiss to the container corner */
    padding: 0.25rem 0.375rem;
    border: 0;
    border-radius: 0.25rem;
    background: none;
    color: #c9c9d1;
    font: inherit;
    line-height: 1;
    cursor: pointer;
}

    #blazor-error-ui .anv-errbar__dismiss:hover {
        background-color: rgba(255, 255, 255, 0.12);
        color: #ffffff;
    }

#blazor-error-ui .anv-errbar__btn:focus-visible,
#blazor-error-ui .anv-errbar__dismiss:focus-visible {
    outline: 0.125rem solid #94bbf7;
    outline-offset: 0.125rem;
}

/*  Boot-failure screen: replaces the frozen splash inside #app, so it inherits the same
    dependency-free rules the splash lives by (no MudBlazor, no web fonts). */
.anv-recovery {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100vh;
    padding: 1.5rem;
    background-color: #f9f9f9;
}

html[data-dark-mode="true"] .anv-recovery {
    background-color: #1f1f1f;
}

.anv-recovery__card {
    width: 100%;
    max-width: 30rem;
    padding: 1.75rem;
    border: 0.0625rem solid #e4e4e7;
    border-radius: 0.75rem;
    background-color: #ffffff;
    box-shadow: 0 0.5rem 1.875rem rgba(0, 0, 0, 0.08);
    text-align: center;
}

html[data-dark-mode="true"] .anv-recovery__card {
    border-color: #3f3f46;
    background-color: #2a2a2e;
    box-shadow: 0 0.5rem 1.875rem rgba(0, 0, 0, 0.45);
}

.anv-recovery__icon {
    width: 2.75rem;
    height: 2.75rem;
    fill: #c0392b;
}

html[data-dark-mode="true"] .anv-recovery__icon {
    fill: #ffb4a9;
}

.anv-recovery__title {
    margin: 0.75rem 0 0;
    font-size: 1.1875rem;
    font-weight: 600;
    color: #18181b;
}

html[data-dark-mode="true"] .anv-recovery__title {
    color: #f4f4f5;
}

.anv-recovery__text {
    margin: 0.625rem 0 0;
    font-size: 0.9375rem;
    line-height: 1.5;
    color: #52525b;
}

html[data-dark-mode="true"] .anv-recovery__text {
    color: #c9c9d1;
}

.anv-recovery__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.625rem;
    justify-content: center;
    margin-top: 1.375rem;
}

.anv-recovery__btn {
    padding: 0.5rem 1rem;
    border: 0.0625rem solid #c4c4c8;
    border-radius: 0.375rem;
    background: none;
    color: #3f3f46;
    font: inherit;
    font-size: 0.9375rem;
    cursor: pointer;
}

html[data-dark-mode="true"] .anv-recovery__btn {
    border-color: #5b5b63;
    color: #e4e4e7;
}

.anv-recovery__btn--primary {
    border-color: transparent;
    background-color: #1e5fd8;
    color: #ffffff;
    font-weight: 600;
}

html[data-dark-mode="true"] .anv-recovery__btn--primary {
    background-color: #94bbf7;
    color: #10233f;
}

.anv-recovery__btn:hover {
    background-color: rgba(0, 0, 0, 0.05);
}

html[data-dark-mode="true"] .anv-recovery__btn:hover {
    background-color: rgba(255, 255, 255, 0.08);
}

.anv-recovery__btn--primary:hover {
    background-color: #1a51b9;
}

html[data-dark-mode="true"] .anv-recovery__btn--primary:hover {
    background-color: #b8d1fa;
}

.anv-recovery__btn:focus-visible {
    outline: 0.125rem solid #1e5fd8;
    outline-offset: 0.125rem;
}

html[data-dark-mode="true"] .anv-recovery__btn:focus-visible {
    outline-color: #94bbf7;
}

/* Kept for whoever is asked "what did it say?" — collapsed, never the first thing read. */
.anv-recovery__details {
    margin-top: 1.25rem;
    text-align: left;
    font-size: 0.8125rem;
    color: #52525b;
}

html[data-dark-mode="true"] .anv-recovery__details {
    color: #c9c9d1;
}

    .anv-recovery__details summary {
        cursor: pointer;
    }

    .anv-recovery__details pre {
        max-height: 8rem;
        margin: 0.5rem 0 0;
        padding: 0.625rem;
        overflow: auto;
        border-radius: 0.375rem;
        background-color: #f4f4f5;
        font-size: 0.75rem;
        white-space: pre-wrap;
        overflow-wrap: anywhere;
    }

html[data-dark-mode="true"] .anv-recovery__details pre {
    background-color: #232327;
}

.anv-recovery .lds-ellipsis {
    height: 3rem;
}

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

    /* Localized by js/bootRecovery.js, which sets --anv-error-boundary-text on <html>. */
    .blazor-error-boundary::after {
        content: var(--anv-error-boundary-text, "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: #1b6ec2;
            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;
}

/*  Loader / splash
    Shown by index.html until Blazor renders. Must stay self-contained (no MudBlazor / font
    dependencies) so it paints immediately on a slow first connection to a remote server. */
.loader {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 1.25rem;
    width: 100%;
    height: 100vh;
    background-color: #f9f9f9;
}

html[data-dark-mode="true"] .loader {
    background-color: #1f1f1f;
}

.splash-logo {
    width: 9rem;
    height: 9rem;
    object-fit: contain;
    /* Softens the box edge of tenant logos uploaded without a transparent background. */
    border-radius: 7px;
    animation: splash-breathe 2.4s ease-in-out infinite;
}

/* The ellipsis dots sit ~2rem down inside a 5rem box; trim the dead space below them. */
.splash .lds-ellipsis {
    height: 3rem;
}

/* Thin progress track fed by Blazor's boot loader (--blazor-load-percentage on <html>). */
.splash-progress {
    width: 12rem;
    height: 0.25rem;
    border-radius: 999px;
    overflow: hidden;
    background-color: rgba(148, 187, 247, 0.25);
}

.splash-progress-bar {
    height: 100%;
    width: var(--blazor-load-percentage, 0%);
    border-radius: inherit;
    background-color: #94bbf7;
    transition: width 0.15s ease-out;
}

.splash-progress-text {
    font-size: 0.8125rem;
    letter-spacing: 0.02em;
    color: #6b7280;
}

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

html[data-dark-mode="true"] .splash-progress-text {
    color: #a3a3a3;
}

@keyframes splash-breathe {
    0%, 100% {
        transform: scale(1);
        opacity: 1;
    }

    50% {
        transform: scale(0.94);
        opacity: 0.85;
    }
}

@media (prefers-reduced-motion: reduce) {
    .splash-logo,
    .lds-ellipsis div {
        animation: none;
    }
}

.lds-ellipsis {
    display: inline-block;
    position: relative;
    width: 5rem;
    height: 5rem;
}

    .lds-ellipsis div {
        position: absolute;
        top: 2.0625rem;
        width: 0.8125rem;
        height: 0.8125rem;
        border-radius: 50%;
        background: #94bbf7;
        animation-timing-function: cubic-bezier(0, 1, 1, 0);
    }

        .lds-ellipsis div:nth-child(1) {
            left: 0.5rem;
            animation: lds-ellipsis1 0.6s infinite;
        }

        .lds-ellipsis div:nth-child(2) {
            left: 0.5rem;
            animation: lds-ellipsis2 0.6s infinite;
        }

        .lds-ellipsis div:nth-child(3) {
            left: 2rem;
            animation: lds-ellipsis2 0.6s infinite;
        }

        .lds-ellipsis div:nth-child(4) {
            left: 3.5rem;
            animation: lds-ellipsis3 0.6s infinite;
        }

@keyframes lds-ellipsis1 {
    0% {
        transform: scale(0);
    }

    100% {
        transform: scale(1);
    }
}

@keyframes lds-ellipsis3 {
    0% {
        transform: scale(1);
    }

    100% {
        transform: scale(0);
    }
}

@keyframes lds-ellipsis2 {
    0% {
        transform: translate(0, 0);
    }

    100% {
        transform: translate(1.5rem, 0);
    }
}
/* END Loader ellipsis */

.center-content {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
}

/* Empty card styles for CustomerView */
.empty-card {
    max-height: 4.5rem !important;
    overflow: hidden !important;
}

.empty-card .mud-card-header {
    padding: 12px 20px !important;
    margin: 0 !important;
}

.empty-card .mud-card-content {
    display: none !important;
    padding: 0 !important;
}

.anv-navlink-tooltip {
    display: contents !important;
}

/* App-bar project picker (Layout/ActiveProjectIndicator). The popover is teleported to
   MudPopoverProvider at the layout root, so scoped CSS cannot reach it — these rules are global
   and matched via the component's PopoverClass/ListClass. */
.project-picker__popover {
    min-width: 17rem;
    /* MudMenu writes an inline "max-width: none" on the popover, so this has to outrank it —
       without it a long project name stretches the menu off the side of the screen. */
    max-width: 24rem !important;
}

/* Let the item shrink so the name can ellipsize instead of widening the menu. */
.project-picker__popover .mud-menu-item {
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
}

.project-picker__head {
    padding: 0.5rem 1rem 0.25rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

/* The active project stated in full, where the user is actually looking. This replaces the
   activator's old hover tooltip, which made the control read as status rather than a selector.
   Wraps instead of ellipsizing — carrying the whole label is the entire point of it. */
.project-picker__active {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem 0.375rem 1rem;
}

/* The label/name column yields to the action button instead of pushing it out of the popover. */
.project-picker__active-text {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}

/* Nudged up to sit against the name rather than centred on the two-line block. */
.project-picker__active-edit {
    flex: 0 0 auto;
    align-self: flex-start;
    margin-top: 0.125rem;
}

.project-picker__active-label {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.project-picker__active-name {
    font-size: 0.875rem;
    font-weight: 600;
    overflow-wrap: anywhere;
    color: color-mix(in srgb, var(--mud-palette-primary) 60%, var(--mud-palette-text-primary));
}

.project-picker__search {
    padding: 0.25rem 0.75rem 0.5rem;
}

.project-picker__status {
    padding: 0.75rem 1rem;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

.project-picker__status--error {
    /* Darkened toward the text color so it stays legible on the popover surface in both themes. */
    color: color-mix(in srgb, var(--mud-palette-error) 60%, var(--mud-palette-text-primary));
}

/* Long project lists scroll inside the popover instead of pushing the actions off screen. */
.project-picker__results {
    max-height: 15rem;
    overflow-y: auto;
    overflow-x: hidden;
}

/* Section heading inside the results list (Active project / Recent projects / Projects), matching the
   ordering every other project picker uses. The top border doubles as the divider between sections;
   the first one in the list drops it since the search box already separates it. */
.project-picker__section {
    padding: 0.5rem 1rem 0.25rem;
    border-top: 1px solid var(--mud-palette-lines-default);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary);
}

.project-picker__section:first-child {
    border-top: none;
    padding-top: 0.25rem;
}

.project-picker__item {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
}

.project-picker__item-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The project already in use, so reopening the picker shows where you are. */
.project-picker__item--active .project-picker__item-name {
    font-weight: 600;
    color: color-mix(in srgb, var(--mud-palette-primary) 60%, var(--mud-palette-text-primary));
}

.project-picker__item-number {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}
