﻿/* Nityodaya ERP â€” Tabler shell (UI-CONVENTIONS.md) */

/* --- Mandatory fields ---
   Required fields are marked by the red asterisk on their label (.field-required-mark).
   The field border is no longer painted red just because a field is mandatory; the
   colour is now driven by live validation state (see field-validation-state.js):
   red while a required field is empty or its format is invalid, green once it is valid. */

/* Invalid: jQuery Validate error class + live "is-invalid" state -> thin red left edge */
.form-control.input-validation-error,
.form-select.input-validation-error,
.form-control.is-invalid,
.form-select.is-invalid,
textarea.is-invalid {
    border-left: 2px solid #d63939 !important;
}

/* Valid: filled and correctly formatted -> thin green left edge */
.form-control.is-valid,
.form-select.is-valid,
textarea.is-valid {
    border-left: 2px solid #2fb344 !important;
}

/* Keep the indicator to a slim left accent only: drop Bootstrap's full coloured
   border, the inline ✓/! icon, and the coloured focus glow so it doesn't look heavy. */
.form-control.is-valid,
.form-select.is-valid,
textarea.is-valid,
.form-control.is-invalid,
.form-select.is-invalid,
textarea.is-invalid {
    background-image: none !important;
    border-top-color: var(--tblr-border-color) !important;
    border-right-color: var(--tblr-border-color) !important;
    border-bottom-color: var(--tblr-border-color) !important;
    padding-right: 0.75rem;
}

.form-control.is-valid:focus,
.form-select.is-valid:focus,
textarea.is-valid:focus,
.form-control.is-invalid:focus,
.form-select.is-invalid:focus,
textarea.is-invalid:focus {
    box-shadow: none;
}

.form-label .field-required-mark {
    color: #d63939;
    margin-left: 0.15rem;
    font-weight: 600;
}

/* --- Responsive --- */
.table-responsive {
    -webkit-overflow-scrolling: touch;
}

@media (max-width: 767.98px) {
    .page-header .page-title {
        font-size: 1.25rem;
    }

    .btn-list {
        flex-direction: column;
        align-items: stretch;
    }

    .btn-list .btn {
        width: 100%;
    }

    .navbar-brand span.d-none.d-sm-inline {
        max-width: 12rem;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
}

/* Plan cards on wizard */
.plan-card {
    cursor: pointer;
    transition: border-color 0.15s ease;
}

.plan-card:has(input[type="radio"]:checked) {
    border-color: var(--tblr-primary) !important;
    box-shadow: 0 0 0 1px var(--tblr-primary);
}

.plan-card.field-required:not(:has(input:checked)) {
    border-left: 3px solid #d63939 !important;
}

/* Navbar active (legacy top menu â€” platform) */
.navbar-nav .nav-link.active {
    font-weight: 600;
    color: var(--tblr-primary);
    border-bottom: 2px solid var(--tblr-primary);
}

/* --- Admin left sidebar (Tabler tokens) --- */
.admin-layout-body {
    overflow-x: hidden;
}

.admin-shell {
    display: flex;
    min-height: 100vh;
    width: 100%;
    max-width: 100%;
}

.admin-sidebar {
    /* [2026-06-20] CHANGE: locked navy + lighter-navy hover/active band (shell redesign) | REASON:
       mockup uses a single navy #1A3A6B with a solid #244A82 hover/active band (no white-overlay
       shade drift across states). Accent stays orange #F97316. */
    --admin-sidebar-bg: #1A3A6B;
    --admin-sidebar-border: rgba(255, 255, 255, 0.08);
    --admin-sidebar-text: #DCE5F4;
    --admin-sidebar-muted: #9DB2D4;
    --admin-sidebar-hover: #244A82;
    --admin-sidebar-active: #244A82;
    --admin-sidebar-accent: #F97316;
    /* [2026-06-23 15:10] CHANGE: dedicated submenu (child-item) text color #C8D5EE, replacing the muted #9DB2D4 | REASON: child links rendered too faint/washed-out against navy #1A3A6B; #C8D5EE is a near-white light blue-grey (on-brand) with ~7.6:1 contrast on #1A3A6B (WCAG AAA, well past the 4.5:1 AA target). Active (#fff + orange bar) and hover (#fff) states are unaffected as they override this base color. Top-level item styling is untouched. */
    --admin-sidebar-submenu-text: #C8D5EE;
    /* [2026-06-23 14:30] CHANGE: sidebar width 16.75rem (~268px) -> 14.375rem (230px) | REASON: sidebar was too wide and crowding page content; target ~230px. Content area is a flex sibling of .admin-shell (display:flex) so it auto-reflows with no separate margin-left offset to update. Collapsed rail (4.25rem) and mobile drawer share .admin-sidebar but are unaffected by the expanded width. ASSUMPTION: 230px fits longest labels ("Onboarding checklist", "School profile") given ~0.875rem nav font; if any wrap, max 245px per spec. */
    width: 14.375rem;
    flex-shrink: 0;
    position: sticky;
    top: 0;
    align-self: flex-start;
    height: 100vh;
    height: 100dvh;
    max-height: 100vh;
    max-height: 100dvh;
    overflow: hidden;
    background: var(--admin-sidebar-bg);
    border-right: 1px solid var(--admin-sidebar-border);
    display: flex;
    flex-direction: column;
    z-index: 1040;
    color: var(--admin-sidebar-text);
}

.admin-sidebar-brand {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.85rem 1rem;
    border-bottom: 1px solid var(--admin-sidebar-border);
    flex-shrink: 0;
    background: transparent;
    color: #fff;
}

/* Nityodaya brand logo — orange square with white "R" initial */
.roshvik-brand-logo {
    width: 32px;
    height: 32px;
    border-radius: 7px;
    background: #F97316 !important;
    color: #fff !important;
    font-weight: 700;
    font-size: 0.95rem;
    line-height: 1;
    flex-shrink: 0;
}

.admin-sidebar-brand-logo {
    width: 32px;
    height: 32px;
    border-radius: 7px;
    flex-shrink: 0;
    display: block;
}

.admin-sidebar-brand-text .fw-semibold {
    font-size: 14px;
    font-weight: 500;
    color: #fff;
}

.admin-sidebar-brand-link {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    color: inherit;
    min-width: 0;
}

.admin-sidebar-brand-text {
    min-width: 0;
    line-height: 1.25;
}

.admin-sidebar-brand-text .small {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 10rem;
    font-size: 11px;
    color: rgba(255, 255, 255, 0.45) !important;
}

.admin-sidebar-brand .btn-ghost-secondary {
    color: #fff;
}

.admin-sidebar-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0.5rem 0 0.75rem;
    -webkit-overflow-scrolling: touch;
}

.admin-sidebar-footer {
    flex-shrink: 0;
    border-top: 1px solid var(--admin-sidebar-border);
    padding: 0.75rem 1rem;
    background: rgba(0, 0, 0, 0.12);
}

/* Sidebar plan badge */
.admin-sidebar-plan {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.65rem;
    border-radius: 999px;
    background: rgba(249, 115, 22, 0.15);
    border: 0.5px solid rgba(249, 115, 22, 0.3);
    color: #F97316;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
}

.admin-sidebar-plan .material-icons {
    font-size: 0.9rem;
}

/* Material Icons sizing/alignment shim (migrated from Tabler webfont).
   Material Icons default to 24px; scale down and baseline-align so they
   sit like the previous inline Tabler glyphs. */
.material-icons {
    font-size: 1.25rem;
    line-height: 1;
    vertical-align: -0.18em;
}

.admin-nav-icon.material-icons {
    font-size: 1.125rem;
}

.admin-nav-chevron.material-icons {
    font-size: 1.1rem;
}

/* Topbar user chip avatar */
.roshvik-user-avatar {
    background: #1A3A6B !important;
    color: #fff !important;
    border-radius: 50%;
}

.admin-sidebar-user-link {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    width: 100%;
    padding: 0.45rem 0.5rem;
    border-radius: var(--tblr-border-radius);
    text-decoration: none;
}

.admin-sidebar-user-link:hover,
.admin-sidebar-user-link:focus {
    color: inherit;
    background: var(--admin-sidebar-hover);
}

.admin-sidebar-user-text {
    flex: 1 1 auto;
    min-width: 0;
    line-height: 1.25;
}

.admin-sidebar-user-name {
    display: block;
    font-size: 0.8125rem;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: #fff;
}

.admin-sidebar-user-role {
    display: block;
    font-size: 0.6875rem;
    color: var(--admin-sidebar-muted);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.admin-sidebar-user-menu-icon {
    flex-shrink: 0;
    font-size: 1rem;
    color: var(--admin-sidebar-muted);
    opacity: 0.85;
}

.admin-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.admin-topbar {
    z-index: 1030;
    background: var(--tblr-bg-surface) !important;
}

.admin-topbar-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    min-height: 3.25rem;
    flex-wrap: nowrap;
}

.admin-topbar-start {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1 1 auto;
    min-width: 0;
}

.admin-topbar-title-wrap {
    min-width: 0;
}

.admin-topbar-end {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.75rem;
    flex: 0 0 auto;
    flex-wrap: nowrap;
}

.admin-topbar-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    flex-wrap: nowrap;
}

.admin-topbar-actions .btn-list {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.5rem;
}

.admin-theme-toggle {
    flex-shrink: 0;
    display: flex;
    align-items: center;
}

.admin-theme-form {
    display: inline-flex;
    margin: 0;
}

.admin-topbar-title {
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.admin-content {
    flex: 1 1 auto;
    min-width: 0;
}

.admin-nav-link,
.admin-nav-toggle,
.admin-subnav-toggle {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.55rem 1rem;
    border: 0;
    background: transparent;
    color: var(--admin-sidebar-text);
    text-decoration: none;
    text-align: left;
    font-size: 0.875rem;
    line-height: 1.35;
    font-weight: 500;
}

.admin-nav-link:hover,
.admin-subnav-link:hover,
.admin-subsubnav-link:hover,
.admin-nav-toggle:hover,
.admin-subnav-toggle:hover {
    color: #fff;
    background: var(--admin-sidebar-hover);
}

/* [2026-06-20] CHANGE: nav icons are now outline SVGs (stroke 1.8), not the Material webfont
   (shell redesign) | REASON: standardise icon style per mockup. Active item icon turns orange. */
.admin-nav-icon {
    width: 1.125rem;
    height: 1.125rem;
    flex-shrink: 0;
    opacity: 0.9;
    color: inherit;
    stroke-width: 1.8;
}

/* [2026-06-23 15:45] CHANGE: icon style for submenu (child) nav items | REASON: child links now render an
   action icon (NavIcons "admin-subnav-icon"); slightly smaller than the 1.125rem top-level icon so the
   parent/child hierarchy stays visible. Inherits currentColor, so it follows the readable submenu text color
   and turns white on the active/hover state automatically. */
.admin-subnav-icon {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
    opacity: 0.85;
    color: inherit;
    stroke-width: 1.8;
}

/* Nav section labels */
.admin-nav-section {
    font-size: 10px;
    color: rgba(255, 255, 255, 0.3);
    text-transform: uppercase;
    letter-spacing: 0.8px;
    font-weight: 600;
    padding: 0.85rem 1rem 0.35rem;
    margin: 0;
    list-style: none;
}

.admin-nav-section:first-child {
    padding-top: 0.35rem;
}

.admin-nav-chevron {
    margin-left: auto;
    width: 0.9rem;
    height: 0.9rem;
    flex-shrink: 0;
    transition: transform 0.2s ease;
    opacity: 0.65;
    color: var(--admin-sidebar-muted);
}

.admin-nav-toggle:not(.collapsed) .admin-nav-chevron,
.admin-subnav-toggle:not(.collapsed) .admin-nav-chevron {
    transform: rotate(180deg);
}

.admin-nav-link.active,
.admin-subnav-link.active,
.admin-subsubnav-link.active {
    color: #fff;
    font-weight: 600;
    background: var(--admin-sidebar-active);
    border-left: 3px solid var(--admin-sidebar-accent);
    padding-left: calc(1rem - 3px);
}

.admin-subnav {
    padding-left: 0;
    margin: 0;
}

.admin-subnav-link,
.admin-subnav-toggle {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    width: 100%;
    padding: 0.45rem 1rem 0.45rem 2.35rem;
    border: 0;
    background: transparent;
    /* [2026-06-23 15:10] CHANGE: submenu link text var(--admin-sidebar-muted) -> var(--admin-sidebar-submenu-text) | REASON: ISSUE 1 — muted #9DB2D4 read as faded/blurry against navy; switch to the readable #C8D5EE token. .admin-subnav-toggle re-overrides to --admin-sidebar-text below, so this only affects leaf child links. */
    color: var(--admin-sidebar-submenu-text);
    text-decoration: none;
    text-align: left;
    font-size: 0.8125rem;
}

.admin-subnav-toggle {
    color: var(--admin-sidebar-text);
    font-weight: 500;
}

.admin-subsubnav {
    padding-left: 0;
    margin: 0;
}

.admin-subsubnav-link {
    display: block;
    padding: 0.4rem 1rem 0.4rem 3.15rem;
    /* [2026-06-23 15:10] CHANGE: third-level submenu link text var(--admin-sidebar-muted) -> var(--admin-sidebar-submenu-text) | REASON: ISSUE 1 — same low-contrast fix applied to the deeper child level for consistency; active dot still uses the orange accent. */
    color: var(--admin-sidebar-submenu-text);
    text-decoration: none;
    font-size: 0.8125rem;
    position: relative;
}

.admin-subsubnav-link::before {
    content: "";
    position: absolute;
    left: 2.35rem;
    top: 50%;
    width: 0.35rem;
    height: 0.35rem;
    margin-top: -0.175rem;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
}

.admin-subsubnav-link.active::before {
    background: var(--admin-sidebar-accent);
}

.admin-sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    z-index: 1035;
}

.admin-sidebar-scroll-lock {
    overflow: hidden;
}

@media (max-width: 991.98px) {
    .admin-topbar-row {
        flex-wrap: wrap;
    }

    .admin-topbar-end {
        width: 100%;
        justify-content: space-between;
    }

    .admin-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        /* [2026-06-25] CHANGE: explicit 100vh/100dvh height instead of height:auto | REASON: the mobile
           menu list (.admin-sidebar-scroll) would not scroll. As a flex-column container whose height was
           derived only from top:0/bottom:0 offsets (height:auto), mobile browsers (notably iOS Safari) fail
           to resolve a definite height for the flex:1 + overflow-y:auto child, so it grew to fit every menu
           item and clipped below the viewport with no scroll. A definite viewport height fixes the scroll. */
        height: 100vh;
        height: 100dvh;
        max-height: none;
        transform: translateX(-100%);
        transition: transform 0.25s ease;
        box-shadow: 0 0.5rem 2rem rgba(0, 0, 0, 0.15);
    }

    .admin-shell.admin-sidebar-open .admin-sidebar {
        transform: translateX(0);
    }

    .admin-shell.admin-sidebar-open .admin-sidebar-backdrop {
        display: block;
    }
}

@media (min-width: 992px) {
    .admin-sidebar-backdrop {
        display: none !important;
    }

    /* Animate width changes when collapsing/expanding the rail. */
    .admin-sidebar {
        transition: width 0.2s ease;
    }

    /* Collapsed icon-only rail (desktop). State lives on <html> so it can be
       applied before paint to avoid a flash of the full-width sidebar. */
    html.sidebar-collapsed .admin-sidebar {
        width: 4.25rem;
    }

    /* Hide all text, keep icons. */
    html.sidebar-collapsed .admin-sidebar-brand-text,
    html.sidebar-collapsed .admin-nav-chevron,
    html.sidebar-collapsed .admin-nav-link span,
    html.sidebar-collapsed .admin-nav-toggle span,
    html.sidebar-collapsed .admin-subnav,
    html.sidebar-collapsed .admin-sidebar-footer {
        display: none;
    }

    /* Section labels collapse to a thin divider so icon groups stay separated. */
    html.sidebar-collapsed .admin-nav-section {
        height: 1px;
        padding: 0;
        margin: 0.5rem 0.85rem;
        overflow: hidden;
        color: transparent;
        background: var(--admin-sidebar-border);
    }

    html.sidebar-collapsed .admin-nav-section:first-child {
        margin-top: 0.25rem;
    }

    /* Collapsed rail brand: hide the logo/text, leave only the toggle, centered. */
    html.sidebar-collapsed .admin-sidebar-brand-link {
        display: none;
    }

    html.sidebar-collapsed .admin-sidebar-brand {
        padding-left: 0;
        padding-right: 0;
    }

    /* Chevron points left to collapse; flip it to point right to expand. */
    html.sidebar-collapsed .admin-sidebar-collapse-btn .material-icons {
        transform: rotate(180deg);
    }

    /* Center the remaining icons in the rail. */
    html.sidebar-collapsed .admin-sidebar-brand,
    html.sidebar-collapsed .admin-nav-link,
    html.sidebar-collapsed .admin-nav-toggle {
        justify-content: center;
        gap: 0;
    }

    html.sidebar-collapsed .admin-nav-link,
    html.sidebar-collapsed .admin-nav-toggle {
        padding-left: 0;
        padding-right: 0;
    }

    /* Keep the active accent readable when centered. */
    html.sidebar-collapsed .admin-nav-link.active {
        border-left-width: 3px;
        padding-left: 0;
    }

    /* Hover flyout: a grouped menu's submenu, positioned (via JS, fixed) to the
       right of the rail so it escapes the sidebar's overflow clipping. */
    html.sidebar-collapsed .admin-subnav.admin-flyout {
        display: block;
        position: fixed;
        min-width: 13rem;
        max-height: 80vh;
        overflow-y: auto;
        background: var(--admin-sidebar-bg);
        border: 1px solid var(--admin-sidebar-border);
        border-radius: 0.5rem;
        box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.35);
        padding: 0.35rem 0;
        z-index: 1060;
    }

    html.sidebar-collapsed .admin-subnav.admin-flyout::before {
        content: attr(data-group-label);
        display: block;
        padding: 0.4rem 1rem 0.45rem;
        margin-bottom: 0.25rem;
        font-size: 10px;
        text-transform: uppercase;
        letter-spacing: 0.8px;
        font-weight: 600;
        color: rgba(255, 255, 255, 0.4);
        border-bottom: 1px solid var(--admin-sidebar-border);
    }

    /* Flyout items use normal padding (no rail indentation). */
    html.sidebar-collapsed .admin-subnav.admin-flyout .admin-subnav-link {
        padding-left: 1rem;
    }
}

/* Icon tooltip for collapsed direct links (single shared element on <body>,
   positioned via JS so it is never clipped by the sidebar overflow). */
.admin-nav-tooltip {
    position: fixed;
    transform: translateY(-50%);
    background: #1f2937;
    color: #fff;
    padding: 0.25rem 0.55rem;
    border-radius: 0.3rem;
    font-size: 0.75rem;
    line-height: 1.2;
    white-space: nowrap;
    z-index: 1070;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.12s ease;
}

.admin-nav-tooltip.show {
    opacity: 1;
}

.navbar-brand-autodark .navbar-brand-image {
    height: 2rem;
}

/* Platform dashboard chart */
.chart-lg {
    position: relative;
    height: 220px;
}

/* Dropdown sign-out as button */
.dropdown-item.btn {
    text-align: left;
    border: none;
    width: 100%;
}

.page-header .page-pretitle {
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.625rem;
    font-weight: 600;
}

.form-hint.text-green { color: var(--tblr-success); }
.form-hint.text-red { color: var(--tblr-danger); }

/* =====================================================================
   [2026-06-20] Shell redesign (roshvik-shell-redesign mockup)
   Sidebar active-icon tint, page surface, header global search + bell,
   focus-visibility and reduced-motion. UI only — no logic changes.
   ===================================================================== */

/* Active item icon turns orange (mockup). Direct top-level links only carry .active;
   grouped parents stay neutral, the active child shows the orange left bar. */
.admin-nav-link.active .admin-nav-icon {
    color: var(--admin-sidebar-accent);
    opacity: 1;
}

/* Page surface so white cards lift (light theme only; dark theme keeps Tabler's bg). */
html[data-bs-theme="light"] body.admin-layout-body {
    background-color: #F1F5F9;
}

/* Orange text on white must use the higher-contrast tint (#C2410C); orange fills/bars stay #F97316. */
.text-orange-contrast { color: #C2410C !important; }

/* ---- Sidebar: module quick-jump search (eSkooly style, navy theme) ---- */
.admin-sidebar-search {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.25rem 0.75rem 0.5rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 0.5rem;
    background: rgba(255, 255, 255, 0.06);
}

.admin-sidebar-search:focus-within {
    border-color: #F97316;
    background: rgba(255, 255, 255, 0.10);
}

.admin-sidebar-search-icon {
    width: 1rem;
    height: 1rem;
    flex-shrink: 0;
    color: var(--admin-sidebar-muted);
}

.admin-sidebar-search-input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    background: transparent;
    outline: 0;
    font-size: 0.8125rem;
    color: #fff;
}

.admin-sidebar-search-input::placeholder {
    color: var(--admin-sidebar-muted);
    opacity: 1;
}

.admin-sidebar-search-kbd {
    flex-shrink: 0;
    font-size: 0.625rem;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 0.3rem;
    padding: 0.05rem 0.3rem;
    color: var(--admin-sidebar-muted);
}

/* Hide the search when the desktop rail is collapsed to icons. */
html.sidebar-collapsed .admin-sidebar-search {
    display: none;
}

/* ---- Header: notifications bell ---- */
/* Shared chrome for every topbar control (language, bell, theme toggle).
   One square box style so the header reads as a single consistent group;
   the user avatar stays a circle as the only "account" affordance. */
.admin-topbar-icon,
.admin-topbar-bell {
    position: relative;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border-radius: 0.5rem;
    border: 1px solid var(--tblr-border-color);
    background: var(--tblr-bg-surface);
    color: var(--tblr-secondary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    padding: 0;
    cursor: pointer;
}

.admin-topbar-icon:hover,
.admin-topbar-bell:hover {
    color: var(--tblr-body-color);
    border-color: var(--tblr-secondary);
}

.admin-topbar-icon .material-icons {
    font-size: 1.25rem;
}

.admin-topbar-bell-icon {
    width: 1.125rem;
    height: 1.125rem;
}

.admin-topbar-bell-badge {
    position: absolute;
    top: -0.35rem;
    right: -0.35rem;
    min-width: 1.05rem;
    height: 1.05rem;
    padding: 0 0.2rem;
    border-radius: 999px;
    background: #DC2626;
    color: #fff;
    font-size: 0.625rem;
    font-weight: 700;
    line-height: 1.05rem;
    text-align: center;
}

/* ---- Keyboard focus visibility (a11y quality floor) ---- */
.admin-nav-link:focus-visible,
.admin-nav-toggle:focus-visible,
.admin-subnav-link:focus-visible,
.admin-subnav-toggle:focus-visible {
    outline: 2px solid #F97316;
    outline-offset: -2px;
}

.admin-topbar-icon:focus-visible,
.admin-topbar-bell:focus-visible,
.admin-sidebar-search-input:focus-visible {
    outline: 2px solid #F97316;
    outline-offset: 2px;
}

/* ---- Respect reduced-motion ---- */
@media (prefers-reduced-motion: reduce) {
    .admin-sidebar,
    .admin-nav-chevron,
    .admin-nav-link,
    .admin-nav-toggle,
    .admin-sidebar-search {
        transition: none !important;
    }
}

@media (max-width: 575.98px) {
    /* On the smallest screens shrink every control + tighten the gaps so the
       icon cluster never overflows or crowds out the page title. */
    .admin-topbar-icon,
    .admin-topbar-bell { width: 2rem; height: 2rem; }
    .admin-topbar-icon .material-icons { font-size: 1.125rem; }
    .admin-topbar-end { gap: 0.4rem; }
    .admin-topbar-actions { gap: 0.35rem; }
}

/* ── MOD-22 Gate Passes: passport-size photo-capture widget ── */
.photo-capture-stage {
    position: relative;
    width: 175px;            /* 35:45 portrait frame */
    height: 225px;
    border: 2px dashed var(--tblr-border-color, #ced4da);
    border-radius: 6px;
    background: #f6f7f9;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}
.photo-capture-stage.has-photo { border-style: solid; border-color: #2fb344; }
.photo-capture-video,
.photo-capture-preview {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.photo-capture-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .25rem;
    color: #9aa0a6;
    text-align: center;
    padding: .5rem;
}
.photo-capture-empty .material-icons { font-size: 2.5rem; }
.photo-capture-stage.has-photo ~ * .photo-capture-empty,
.photo-capture-stage:not(.has-photo) .photo-capture-empty { display: flex; }
.photo-capture-stage.has-photo .photo-capture-empty,
.photo-capture-video:not(.d-none) ~ .photo-capture-empty,
.photo-capture-preview:not(.d-none) ~ .photo-capture-empty { display: none; }
.photo-capture-hint { font-size: .75rem; }
.visitor-photo-thumb { width: 28px; height: 36px; object-fit: cover; border-radius: 3px; }

/* =====================================================================
   [2026-06-20] Status badge contrast fix
   The Tabler CDN's `bg-*-lt` light badge variants were rendering as a
   saturated fill with low-contrast same-hue text (e.g. green "Active"
   text on a green pill), illegible across ~150 status badges app-wide.
   These overrides force a genuine pale tint + a dark, readable text
   colour for every `-lt` colour the app uses. Scoped to `.badge` so the
   same `-lt` utility classes on cards / avatars / status dots are left
   untouched. Loaded after tabler.min.css, so these win without per-view
   edits. Keep the `.badge` selector — do NOT broaden to bare `.bg-*-lt`. */
.badge.bg-green-lt,
.badge.bg-success-lt   { background-color: #e3faec !important; color: #0f7c3a !important; }
.badge.bg-teal-lt      { background-color: #dff7f1 !important; color: #0a7d5e !important; }
.badge.bg-lime-lt      { background-color: #eef7df !important; color: #54810f !important; }
.badge.bg-red-lt,
.badge.bg-danger-lt    { background-color: #fbe4e6 !important; color: #b02a37 !important; }
.badge.bg-pink-lt      { background-color: #fce4ee !important; color: #a61e4d !important; }
.badge.bg-yellow-lt,
.badge.bg-warning-lt   { background-color: #fcf3d9 !important; color: #8a6400 !important; }
.badge.bg-orange-lt    { background-color: #fdebd9 !important; color: #b45309 !important; }
.badge.bg-blue-lt,
.badge.bg-primary-lt   { background-color: #e6effb !important; color: #1a4f8a !important; }
.badge.bg-azure-lt,
.badge.bg-info-lt      { background-color: #e7f3fb !important; color: #1c5a86 !important; }
.badge.bg-indigo-lt    { background-color: #e9ecfd !important; color: #39449e !important; }
.badge.bg-purple-lt    { background-color: #f6e9fa !important; color: #7c2a91 !important; }
.badge.bg-secondary-lt { background-color: #eceef1 !important; color: #4b5563 !important; }

/* =====================================================================
   [2026-06-21] Solid status-badge contrast fix (3rd iteration)
   The Tabler CDN + Bootstrap leave the SOLID `.badge.bg-*` variants with
   an unreliable text colour, so status pills (e.g. PENDING/APPROVED on
   the leave "Request history") rendered as an empty grey pill with no
   readable text across ~64 views app-wide. The `-lt` light block above
   only covers the pale variants. These rules force a solid fill + a
   high-contrast text colour for every solid variant the app uses.
   Scoped to `.badge`, loaded after tabler.min.css, so they win without
   per-view edits. Keep the `.badge` selector — do NOT broaden. */
.badge.bg-primary,
.badge.bg-blue         { background-color: #206bc4 !important; color: #fff !important; }
.badge.bg-secondary    { background-color: #5b6776 !important; color: #fff !important; }
.badge.bg-success,
.badge.bg-green        { background-color: #2fb344 !important; color: #fff !important; }
.badge.bg-danger,
.badge.bg-red          { background-color: #d63939 !important; color: #fff !important; }
.badge.bg-warning,
.badge.bg-yellow       { background-color: #f59f00 !important; color: #1a2230 !important; }
.badge.bg-info,
.badge.bg-azure        { background-color: #4299e1 !important; color: #fff !important; }
.badge.bg-teal         { background-color: #0ca678 !important; color: #fff !important; }
.badge.bg-purple       { background-color: #ae3ec9 !important; color: #fff !important; }
.badge.bg-orange       { background-color: #f76707 !important; color: #fff !important; }
.badge.bg-dark         { background-color: #182433 !important; color: #fff !important; }
.badge.bg-light        { background-color: #f1f3f5 !important; color: #1a2230 !important; }
