html, body {
    font-family: 'DM Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    height: 100%;
    margin: 0;
    padding: 0;
}

/* Ensure MudBlazor layout fills viewport height */
#app {
    height: 100%;
    display: flex;
    flex-direction: column;
}

/* Ensure MudLayout component fills available space */
.mud-layout {
    min-height: 100vh;
}

/* Hide the reCAPTCHA v3 badge. Google's terms permit hiding the badge
   provided the "protected by reCAPTCHA" attribution is shown in the user
   flow — which Register.razor already includes. */
.grecaptcha-badge {
    visibility: hidden !important;
}

/* Fix MudBlazor v9 popover positioning on mobile.
   The provider lives inside MudLayout's scroll container, so absolute-positioned
   popovers scroll off-screen. Pinning it to the viewport ensures popover coordinates
   (calculated via getBoundingClientRect) match the actual viewport position. */
.mud-popover-provider {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 0;
    z-index: 1500;
    pointer-events: none;
}

.mud-popover-provider > * {
    pointer-events: auto;
}

/* Google Places Autocomplete dropdown — must paint above MudDialog (z-index 1400+)
   and the MudPopoverProvider (1500). Default `.pac-container` z-index is 1000,
   which leaves it hidden behind any open dialog. */
.pac-container {
    z-index: 2000 !important;
}

a, .btn-link {
    color: #1B4D3E;
}

.btn-primary {
    color: #fff;
    background-color: #1B4D3E;
    border-color: #174537;
}

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

h1:focus {
    outline: none;
}

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

.invalid {
    outline: 1px solid #e50000;
}

.validation-message {
    color: #e50000;
}

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

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

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

/* Responsive company name in AppBar */
.company-name-mobile {
    font-size: 1.25rem !important; /* h6 size */
}

@media (min-width: 960px) {
    .company-name-mobile {
        font-size: 1.5rem !important; /* h5 size */
    }
}

/* Responsive tagline on homepage */
.tagline-mobile {
    font-size: 2rem !important; /* h4 size */
}

@media (min-width: 960px) {
    .tagline-mobile {
        font-size: 3rem !important; /* h3 size */
    }
}

/* ========================================
   Top Navigation Bar Styles
   ======================================== */
.top-nav-bar {
    background-color: #1B4332 !important;
    color: white !important;
}

.logo-avatar-nav {
    /* Recolored to the tenant's secondary brand color (CAP-48). TopBar injects
       --logo-color from tenant branding; the flat fallback below applies before
       branding loads and on browsers without color-mix support. */
    background: var(--logo-color, #D6336C) !important;
    background: linear-gradient(135deg,
        var(--logo-color, #D6336C) 0%,
        color-mix(in srgb, var(--logo-color, #D6336C) 70%, #000) 100%) !important;
    border-radius: 8px !important;
}

.brand-name-nav {
    font-family: 'Playfair Display', Georgia, serif !important;
    font-weight: 700 !important;
    color: white !important;
}

/* Navigation buttons */
.nav-btn {
    text-transform: none !important;
    font-weight: 500 !important;
    color: rgba(255, 255, 255, 0.9) !important;
    padding: 8px 16px !important;
    border-radius: 8px !important;
}

.nav-btn:hover {
    background-color: rgba(255, 255, 255, 0.1) !important;
    color: white !important;
}

/* Navigation menu (dropdown) */
.nav-menu {
    text-transform: none !important;
}

.nav-menu .mud-button-root {
    text-transform: none !important;
    font-weight: 500 !important;
    color: rgba(255, 255, 255, 0.9) !important;
    padding: 8px 16px !important;
    border-radius: 8px !important;
}

.nav-menu .mud-button-root:hover {
    background-color: rgba(255, 255, 255, 0.1) !important;
    color: white !important;
}

/* Admin navigation menu in dropdown */
.admin-nav-menu {
    min-width: 220px;
    overflow-x: hidden;
}

.admin-nav-menu .mud-nav-link {
    border-radius: 4px !important;
    margin: 1px 4px !important;
}

.admin-nav-menu .mud-nav-link:hover {
    background-color: rgba(214, 51, 108, 0.08) !important;
}

.admin-nav-menu .mud-navgroup-title {
    font-weight: 600 !important;
}

/* Click-away overlay for admin dropdown (below MudPopoverProvider z-index) */
.admin-click-away-overlay,
.click-away-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 1299;
    background: transparent;
}

/* Mobile navigation drawer */
.mobile-nav-drawer {
    width: 280px !important;
}

/* Hide mobile drawer on desktop screens (md and up = 960px+) */
@media (min-width: 960px) {
    .mobile-nav-drawer,
    .mobile-nav-drawer ~ .mud-overlay {
        display: none !important;
        visibility: hidden !important;
        width: 0 !important;
        height: 0 !important;
    }
}

/* Ensure drawer is fully hidden when closed on mobile */
.mud-drawer--closed.mobile-nav-drawer,
.mobile-nav-drawer:not(.mud-drawer--open) {
    visibility: hidden !important;
    transform: translateX(100%) !important;
    width: 0 !important;
    opacity: 0 !important;
    pointer-events: none !important;
}

/* Hide the drawer overlay when not open */
.mud-overlay:not(.mud-overlay-open) {
    display: none !important;
}

/* Fix any layout overflow issues */
.mud-layout {
    overflow-x: hidden;
}

html, body, #app {
    overflow-x: hidden;
    max-width: 100vw;
}

.mobile-nav-drawer .mud-nav-link {
    border-radius: 8px !important;
    margin: 2px 8px !important;
}

.mobile-nav-drawer .mud-nav-link:hover {
    background-color: rgba(214, 51, 108, 0.1) !important;
}

.mobile-nav-drawer .mud-navgroup-title {
    font-weight: 600 !important;
}

/* Main content area - account for top nav */
.main-content-area {
    padding-top: 64px !important;
    background-color: #F5F0E8;
    min-height: 100vh;
}

/* Pin temporary drawers to the viewport.
   MudDrawer (Variant="Temporary") is position: absolute unless MudLayout owns it as
   its drawer, and MudLayout is the page's scroll container — so a drawer opened after
   the user has scrolled renders that many pixels ABOVE the viewport and is invisible.
   The scrim is position: fixed and still covers the screen, so the symptom reads as
   "I tapped the menu and nothing opened" (most noticeable on mobile). Pinning to the
   viewport lets the drawer's own overflow-y: auto scroll long content internally.
   Any new Variant="Temporary" MudDrawer needs this class treatment.
   !important is used because MudBlazor.min.css loads after app.css and its
   .mud-drawer:not(.mud-drawer-fixed) rule has equal selector specificity to ours. */
.mobile-nav-drawer.mud-drawer,
.log-detail-drawer.mud-drawer {
    position: fixed !important;
    top: 0 !important;
    bottom: 0 !important;
    height: 100vh !important;
    /* dvh keeps the drawer bottom clear of mobile browser chrome; vh above is the
       fallback for browsers without dynamic viewport units. */
    height: 100dvh !important;
}

/* Platform "System Logs" detail drawer — body scrolls internally so the
   "Close / Find related / Copy" footer stays reachable from any scroll position. */
.log-detail-drawer.mud-drawer {
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden;
}

.log-detail-drawer .mud-drawer-content {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

.log-detail-drawer .log-detail-body {
    flex: 1 1 auto;
    overflow-y: auto;
    min-height: 0;
}

/* Footer pinned below the scrollable body so action buttons remain visible
   regardless of message length. */
.log-detail-drawer .log-detail-footer {
    flex: 0 0 auto;
    border-top: 1px solid var(--mud-palette-divider);
    background-color: var(--mud-palette-drawer-background);
}

/* CAP-18-BR-32 / CAP-09-BR-24: brief flash on the row the user just returned from.
   Fades to transparent within ~3s so it surfaces the row without lingering.
   Uses a literal amber tint (rather than a MudBlazor palette variable) because
   MudBlazor does not expose RGB-decomposed palette tokens for use in rgba(). */
@keyframes jobRowHighlightFade {
    0%   { background-color: rgba(255, 213, 79, 0.55); box-shadow: 0 0 0 2px rgba(255, 193, 7, 0.75); }
    60%  { background-color: rgba(255, 213, 79, 0.25); box-shadow: 0 0 0 2px rgba(255, 193, 7, 0.30); }
    100% { background-color: transparent; box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}

.job-row-highlight {
    animation: jobRowHighlightFade 3s ease-out;
    border-radius: 4px;
}
/* CAP-09-UC-05 (#2): hide MudTable's mobile "sort by" select on the dispatch list.
   In responsive (stacked-card) mode MudTable injects a sort MudSelect that renders
   empty/unlabelled because the list deliberately carries no default sort (the server
   order — today-first per CAP-09-BR-23 — is the intended order). The empty control
   reads as a bug on phones; the default order is the right one, so we suppress it. */
.dispatch-list .mud-table-smalldevices-sortselect {
    display: none !important;
}

/* ---------------------------------------------------------------------------
   CAP-92 impersonation banner (CAP-92-BR-11)

   Pinned to the bottom of the viewport rather than the top, deliberately. The
   top is taken by MudAppBar, and anything absolutely positioned inside
   MudLayout scrolls with the content — the same trap documented in CLAUDE.md
   for temporary drawers and popovers. Fixed to the bottom, it is visible on
   every page at every scroll position and collides with nothing.
   --------------------------------------------------------------------------- */
.impersonation-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 1600; /* above the popover provider (1500) and MudDialog (1401) */
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px;
    padding: 10px 16px;
    background: #b71c1c;
    color: #fff;
    font-size: 0.9rem;
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.3);
}

.impersonation-banner-text {
    line-height: 1.3;
}

/* The way out has to be readable on the red. Color.Default takes its fill and its text from the
   theme's surface and action tokens, which over #b71c1c came out dark grey on red — legible in the
   markup and invisible on the screen. Pinned here so a theme change cannot take the exit with it. */
.impersonation-banner .impersonation-banner-exit {
    white-space: nowrap;
    background-color: #fff !important;
    color: #b71c1c !important;
    font-weight: 600;
}

.impersonation-banner .impersonation-banner-exit:hover,
.impersonation-banner .impersonation-banner-exit:focus-visible {
    background-color: #ffe6e6 !important;
}

.impersonation-banner .impersonation-banner-exit .mud-icon-root {
    color: #b71c1c !important;
}

/* Keep the banner from sitting on top of the last row of whatever page is open. */
body:has(.impersonation-banner) .mud-main-content {
    padding-bottom: 72px;
}
