/* Plus Jakarta Sans — used by the merged-in modern UI below. @import MUST stay at the very
   top of this file (before any rule) or the browser ignores it. */
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,400;0,500;0,600;0,700;0,800;1,400;1,500&display=swap');

html:not([dir=rtl]) .app-brand-text {
    margin-left: 0.325rem !important;
}

.app-brand-logo.demo svg {
    width: 45px !important;
    height: 25px !important;
}

.app-brand-logo.demo {
    width: 45px !important;
    height: 25px !important;
}

.custom-option-icon .custom-option-body svg {
    all: revert !important;
}

.form-floating.input-group label {
    z-index: 10;
}

.light-style .form-floating > label {
    color: #004a80;
    opacity: 0.75;
    transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}

.light-style .select2-container--default .select2-selection--single .select2-selection__rendered {
    color: #6f6b7d;
    padding-left: 0.875rem;
    padding-top: 1.100rem;
    padding-bottom: 0.625rem;
}

.light-style .select2-container--default .select2-selection--single .select2-selection__arrow {
    height: calc(3.5rem + 2px);
    position: absolute;
    width: 2rem;
    right: 1px;
    top: 0;   /* full-height box -> caret sits at the TRUE vertical centre (top:10px pushed it low,
                 so it stuck to the field's bottom border line) */
}

.light-style .select2-results__option[role=option][aria-selected=true] {
    background-color: #004a80;
    color: #fff;
}

.light-style .select2-container--default .select2-results__option--highlighted:not([aria-selected=true]) {
    background-color: rgba(0, 74, 128, 0.08) !important;
    color: #004a80 !important;
}

.light-style .select2-container--default .select2-selection--single {
    height: calc(3.5rem + 2px);
}

.light-style .input-group .select2-selection.select2-selection--single {
    border-right: none;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.dark-style .form-floating > label {
    color: #56b6f5;   /* brighter blue + higher opacity — the old #1da1f2 @0.75 was too faint on dark cards */
    opacity: 0.95;
    transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}

.dark-style .select2-container--default .select2-selection--single .select2-selection__rendered {
    color: #cbcbe2;
    padding-left: 0.875rem;
    padding-top: 1.100rem;
    padding-bottom: 0.625rem;
}
/* select2 "Select value" placeholder — the default #5e6692 is near-invisible on dark cards */
.dark-style .select2-selection__placeholder {
    color: #9aa6bf !important;
}

.dark-style .select2-container--default .select2-selection--single .select2-selection__arrow {
    height: calc(3.5rem + 2px);
    position: absolute;
    width: 2rem;
    right: 1px;
    top: 0;   /* full-height box -> caret centred vertically (top:10px pushed it low / onto the border) */
}

.dark-style .select2-results__option[role=option][aria-selected=true] {
    background-color: #004a80;
    color: #fff;
}

.dark-style .select2-container--default .select2-results__option--highlighted:not([aria-selected=true]) {
    background-color: rgba(115, 103, 240, 0.08) !important;
    color: #1da1f2 !important;
}

.dark-style .select2-container--default .select2-selection--single {
    height: calc(3.5rem + 2px);
}

.dark-style .input-group .select2-selection.select2-selection--single {
    border-right: none;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.form-control.typeahead.tt-input, .form-control.typeahead.tt-hint {
    height: calc(3.5rem + 2px);
    line-height: 1.25;
    padding: 1rem 0.875rem;
}
  
.form-control.typeahead.tt-input::placeholder {
    color: transparent;
}

.form-control.typeahead.tt-input:focus, .form-control.typeahead.tt-input:not(:placeholder-shown),
.form-control.typeahead.tt-hint:focus, .form-control.typeahead.tt-hint:not(:placeholder-shown) {
    padding-top: 1.625rem;
    padding-bottom: 0.625rem;
}

.form-control.typeahead.tt-input:focus ~ label,
.form-control.typeahead.tt-input:not(:placeholder-shown) ~ label {
    opacity: 0.75;
    transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}

.light-style .twitter-typeahead .tt-suggestion:hover, .light-style .twitter-typeahead .tt-suggestion:focus {
    text-decoration: none;
    color: #004a80;
    background-color: rgba(0, 74, 128, 0.08);
}

.dark-style .twitter-typeahead .tt-suggestion:hover, .light-style .twitter-typeahead .tt-suggestion:focus {
    text-decoration: none;
    background-color: rgba(115, 103, 240, 0.08) !important;
    color: #1da1f2 !important;
}

/* Edit Stock dialog: wider than the default modal-xl so the two tall Packed With / Remarks textareas
   (which hold large amounts of data) have room side by side. Only widens on >=lg so small screens keep
   the Bootstrap default. #editModal .modal-dialog beats .modal-xl on specificity (id + class). */
@media (min-width: 992px) {
  #editModal .modal-dialog { max-width: min(1380px, 94vw); }
}

.sticky-actions {
    /* MUST stay sticky: the glass `.ui-glass .card{position:relative}` rule (added for the card
       light-edge) is more specific and would otherwise demote this to relative — which both breaks
       the pin-on-scroll AND lets the JS-set `top` (navbar.bottom + 1.5rem) shove the card down,
       misaligning it from the form. `!important` keeps it sticky; at rest it sits at the column top
       (aligned with the form), and on scroll it pins just below the fixed navbar. */
    position: sticky !important;
    top: 10px; /* fallback; loan_create.js / loan_edit.js set the real offset = navbar.bottom + 1.5rem */
    align-self: flex-start;  /* don't stretch to the row height (the col is a flex item) */
}

.swal2-modal.swal2-popup .swal2-title {
    margin: 0 0 0 0 !important;
}

.tooltip-inner {
    white-space: pre-wrap;
}


.light-style .bootstrap-select .dropdown-menu a:not([href]):not(.active):not(:active):not(.selected):hover {
    color: #004a80 !important;
}
.dark-style .bootstrap-select .dropdown-menu a:not([href]):not(.active):not(:active):not(.selected):hover {
    color: #1da1f2 !important;
}

/* Stat-circle cards (Stock / Loan / Training summaries) — enlarge the circle and
   shrink the count so 4-digit numbers (e.g. 2049) fit inside. Applies app-wide. */
.avatar.avatar-xl {
    width: 5rem;
    height: 5rem;
}
.avatar.avatar-xl .avatar-initial {
    font-size: 1.15rem;
    font-weight: 600;
}

/* ---- Dark-mode contrast fixes for custom-styled pages ----
   Some pages (e.g. the loan "invoice" create form) and inputs render with
   muted/light-assuming colours. Lift their text to a readable tone in dark mode. */
.dark-style .invoice-preview-card,
.dark-style .invoice-preview-card p,
.dark-style .invoice-preview-card h1,
.dark-style .invoice-preview-card h2,
.dark-style .invoice-preview-card h3,
.dark-style .invoice-preview-card h4,
.dark-style .invoice-preview-card h5,
.dark-style .invoice-preview-card h6,
.dark-style .invoice-preview-card td,
.dark-style .invoice-preview-card th {
    color: #cbcbe2;
}
/* Crestron logo on the loan create/edit "invoice" card: its SVG paths are navy (#2e5786),
   nearly invisible on the dark card — recolour them white in dark mode (matches the nav-bar
   logo). Targets the swirl + wordmark inside the invoice card's .app-brand. */
.dark-style .invoice-preview-card .app-brand svg path[fill] {
    fill: #ffffff !important;
}
/* Readable input / date-picker text */
.dark-style input.form-control,
.dark-style textarea.form-control,
.dark-style .flatpickr-input,
.dark-style .dataTable td,
.dark-style .dataTable th {
    color: #cbcbe2;
}
/* Switch/toggle that was near-white on the dark card */
.dark-style .form-check-input {
    background-color: #2b2c40;
    border-color: #56577a;
}
.dark-style .form-check-input:checked {
    background-color: #004a80;
    border-color: #004a80;
}

/* FullCalendar event text — the theme renders event links in blue, which is
   unreadable on the coloured fills. Force white on the month/week event blocks
   (these always have a coloured background). The list view is left alone so its
   row text stays theme-correct in light mode. */
.fc-daygrid-event .fc-event-title,
.fc-daygrid-event .fc-event-time,
.fc-daygrid-block-event .fc-event-title,
.fc-timegrid-event .fc-event-title,
.fc-timegrid-event .fc-event-time,
.fc-daygrid-event .fc-event-title sup,
.fc-timegrid-event .fc-event-title sup {
    color: #fff !important;
}

/* Dark-mode FullCalendar grid lines — the day-cell borders wash out against the dark/glass
   backdrop, so the grid is invisible. Set the FC border variable AND force the colour directly
   on the cells/scrollgrid (the glass skin's translucent cells were blending the default away).
   Light mode is left to the theme default. */
.dark-style .fc {
    --fc-border-color: rgba(255, 255, 255, 0.18);
    --fc-today-bg-color: rgba(255, 255, 255, 0.05);
}
.dark-style .fc-theme-standard td,
.dark-style .fc-theme-standard th,
.dark-style .fc-theme-standard .fc-scrollgrid,
.dark-style .fc-scrollgrid-section > * {
    border-color: rgba(255, 255, 255, 0.18) !important;
}

/* ---- Global navbar search (cassets/js/common.js) ---- */
.gs-wrap { position: relative; min-width: 260px; }
.gs-input {
    border: 0;
    box-shadow: none;
    background: transparent;
    padding-left: 0;
    height: 38px;
}
.gs-input:focus { border: 0; box-shadow: none; background: transparent; }
.global-search-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    min-width: 340px;
    background: #fff;
    border: 1px solid #d9dee3;
    border-top: none;
    border-radius: 0 0 0.375rem 0.375rem;
    box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.18);
    max-height: 60vh;
    overflow-y: auto;
    overflow-x: hidden;
    z-index: 1090;
    padding-bottom: 0.25rem;
}
.dark-style .global-search-results { background: #2b2c40; border-color: #444564; }
.gsr-group-title {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: #a1acb8;
    padding: 0.55rem 0.95rem 0.2rem;
    font-weight: 600;
}
.gsr-item {
    display: flex;
    align-items: center;
    padding: 0.5rem 0.95rem;
    color: #566a7f;
    text-decoration: none;
    line-height: 1.2;
    overflow: hidden;               /* a single row never causes horizontal scroll */
}
.gsr-item > i { flex: 0 0 auto; }   /* icon keeps its size */
.dark-style .gsr-item { color: #cbcbe2; }
.gsr-item:hover { background: #f5f5f9; color: #566a7f; }
.dark-style .gsr-item:hover { background: #383a5c; color: #fff; }
.gsr-label {
    font-weight: 500;
    flex: 1 1 auto;
    min-width: 0;                   /* allow the label to shrink + ellipsize */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.gsr-sub {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 50%;                 /* never let the sub crowd out the label */
    margin-left: auto;
    padding-left: 1rem;
    font-size: 0.8rem;
    color: #a1acb8;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: right;
}
.gsr-empty { padding: 0.75rem 0.95rem; color: #a1acb8; }

/* Floating hover-preview card for a search result (appended to <body>, position:fixed). */
.gsr-preview {
    position: fixed;
    z-index: 1095;                  /* above .global-search-results (1090) */
    width: 260px;
    max-width: 80vw;
    background: #fff;
    border: 1px solid #d9dee3;
    border-radius: 0.375rem;
    box-shadow: 0 0.5rem 1.25rem rgba(0, 0, 0, 0.22);
    padding: 0.55rem 0.7rem;
    font-size: 0.82rem;
    color: #566a7f;
    pointer-events: none;           /* never steal hover/clicks from the result list */
}
.gsr-prev-head {
    display: flex;
    align-items: center;
    font-weight: 600;
    color: #384551;
    padding-bottom: 0.4rem;
    margin-bottom: 0.4rem;
    border-bottom: 1px solid #eceef1;
    white-space: nowrap;
    overflow: hidden;
}
.gsr-prev-head > span { overflow: hidden; text-overflow: ellipsis; }
.gsr-prev-row { display: flex; gap: 0.75rem; padding: 0.12rem 0; }
.gsr-prev-k { flex: 0 0 38%; color: #a1acb8; }
.gsr-prev-v {
    flex: 1 1 auto;
    min-width: 0;
    text-align: right;
    word-break: break-word;
    font-weight: 500;
}
/* Muted second line under a value — mirrors the datatable's stacked cell (e.g. model / part_no). */
.gsr-prev-sub { display: block; font-weight: 400; font-size: 0.76rem; color: #a1acb8; line-height: 1.25; }
.dark-style .gsr-prev-sub { color: #7e7f96; }
.ui-modern .gsr-prev-sub { color: var(--m-text-muted, #a1acb8) !important; }
.dark-style .gsr-preview { background: #2b2c40; border-color: #444564; color: #cbcbe2; }
.dark-style .gsr-prev-head { color: #fff; border-bottom-color: #444564; }
.dark-style .gsr-prev-k { color: #7e7f96; }
.ui-modern .gsr-preview {
    background: var(--m-surface) !important;
    border-color: var(--m-border) !important;
    color: var(--m-text) !important;
    border-radius: var(--m-radius, 0.5rem) !important;
}
.ui-modern .gsr-prev-head { color: var(--m-text) !important; border-bottom-color: var(--m-border) !important; }
.ui-modern .gsr-prev-k { color: var(--m-text-muted, #a1acb8) !important; }

/* ============================================================================
   Sidebar collapse/pin toggle + brand alignment + collapsed-rail centering.
   Theme-level (not .ui-modern-scoped) so it holds regardless; the modern look's
   navy-sidebar toggle hover colour is in the MODERN UI block further below.
   (2026-06-22)
   ============================================================================ */

/* 1) Pin/collapse control — replace the theme's stray radio-dot with a clear
      directional chevron + a real button affordance (hover background). */
.layout-menu-toggle .menu-toggle-icon::before { content: "\ea60"; }                       /* chevron-left  = collapse */
.layout-menu-collapsed .layout-menu-toggle .menu-toggle-icon::before { content: "\ea61"; } /* chevron-right = expand   */
/* Scope the 30x30 rounded box ONLY to the SIDEBAR toggle (#layout-menu). The navbar
   hamburger in nav_bar.php is ALSO a `.layout-menu-toggle` (a <div> wrapping an
   <a class="nav-link"> + ti-menu-2 icon); the forced 30x30 box clipped that larger
   link and left the hover background off-centre from the icon. */
#layout-menu .layout-menu-toggle {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    transition: background-color .15s ease, color .15s ease;
}
#layout-menu .layout-menu-toggle .menu-toggle-icon { font-size: 1.125rem !important; }
.light-style #layout-menu .layout-menu-toggle:hover { background-color: rgba(67, 89, 113, 0.08); }
.dark-style #layout-menu .layout-menu-toggle:hover  { background-color: rgba(255, 255, 255, 0.08); }

/* Navbar hamburger (mobile/tablet, .navbar .layout-menu-toggle) — give it its OWN
   centred hover affordance on the link, so the rounded box is aligned around the icon. */
.navbar .layout-menu-toggle { display: flex; align-items: center; }
.navbar .layout-menu-toggle .nav-link {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0 !important;
    border-radius: 8px;
    line-height: 1;
    transition: background-color .15s ease, color .15s ease;
}
.light-style .navbar .layout-menu-toggle .nav-link:hover { background-color: rgba(67, 89, 113, 0.08); }
.dark-style .navbar .layout-menu-toggle .nav-link:hover  { background-color: rgba(255, 255, 255, 0.08); }

/* 2) Line the brand (logo + pin) up with the detached navbar's search bar. Move the
      WHOLE brand block down ~15px (margin-top) rather than just the logo, so the menu
      shifts with it and the spacing below the logo stays even. */
#layout-menu .app-brand { margin-top: 15px; }

/* 3) Collapsed (icon-only) rail — center each item as a fixed-size pill so the
      active highlight and icons sit dead-centre. The theme otherwise anchors the
      pill to the right (tiny right gap, heavy left gap). Turned off while hovering,
      when the collapsed menu temporarily expands to show its labels. */
.layout-menu-collapsed:not(.layout-menu-hover) #layout-menu .menu-inner > .menu-item {
    margin-left: 0 !important;
    margin-right: 0 !important;
}
.layout-menu-collapsed:not(.layout-menu-hover) #layout-menu .menu-inner > .menu-item > .menu-link {
    width: 2.625rem !important;
    height: 2.625rem !important;
    margin: 0.15rem auto !important;
    padding: 0 !important;
    justify-content: center !important;
}
.layout-menu-collapsed:not(.layout-menu-hover) #layout-menu .menu-inner > .menu-item > .menu-link > div { display: none !important; }
.layout-menu-collapsed:not(.layout-menu-hover) #layout-menu .menu-inner .menu-icon { margin-right: 0 !important; }
/* ...and center the brand logo (hide the wordmark) so the swirl sits dead-centre too. */
.layout-menu-collapsed:not(.layout-menu-hover) #layout-menu .app-brand {
    justify-content: center !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    /* The theme gives collapsed .app-brand a FIXED `width:5.25rem` (core.css) AND an asymmetric
       1rem-left margin, so the box (the modern divider is a border-bottom on it) overflowed the
       narrow rail to the RIGHT. Drop the fixed width to auto so the brand fills the rail, then
       equal margins centre the divider line. */
    width: auto !important;
    margin-left: 0.6rem !important;
    margin-right: 0.6rem !important;
}
.layout-menu-collapsed:not(.layout-menu-hover) #layout-menu .app-brand-text { display: none !important; }
/* Hide the collapse/expand toggle in the collapsed rail. The theme only sets it to opacity:0,
   but our modern skin gives it a fixed 30px width, so it still takes flex space — and with
   justify-content:center on .app-brand that pushes the centred swirl logo off to the LEFT.
   display:none removes it from the layout so the logo sits dead-centre. Scoped to
   :not(.layout-menu-hover), so the toggle returns when the menu is hovered/expanded. */
.layout-menu-collapsed:not(.layout-menu-hover) #layout-menu .app-brand .layout-menu-toggle { display: none !important; }

/* ============================================================================
   Responsive / mobile fixes (theme-level, not skin-scoped). 2026-06-22.
   ============================================================================ */

/* (a) Off-canvas menu backdrop: the theme can leave `.layout-overlay` stuck as a
       ~30px, 0.5-opacity grey strip down the left edge on narrow screens. Force it
       fully hidden when the menu is closed, and full-screen when it's open. */
html:not(.layout-menu-expanded) .layout-overlay {
    opacity: 0 !important;
    width: 0 !important;
    pointer-events: none !important;
}
html.layout-menu-expanded .layout-overlay {
    display: block !important;
    width: 100% !important;
    height: 100% !important;
    opacity: 1 !important;
}

/* Dashboard "My Loans" cards are clickable links to the pre-filtered loan list — give them a
   pointer + subtle hover lift so it's obvious they're tappable (same intent as the statCard links). */
.dash-card-link { display: block; cursor: pointer; transition: transform .15s ease, box-shadow .15s ease; }
.dash-card-link:hover { transform: translateY(-2px); box-shadow: 0 0.5rem 1.25rem rgba(0,0,0,0.12); }

/* (a2) Off-screen `.offcanvas-end` panels (e.g. the mgmt_accounts add/edit forms) sit
        translated past the right edge and cause a horizontal scrollbar on phones. Clip the
        page horizontally — scoped to mobile so desktop `position: sticky` is unaffected.
        (`overflow-x: clip` and html-only don't clip the fixed panel; html+body hidden does.) */
@media (max-width: 767.98px) {
    html, body { overflow-x: hidden; }
}

/* (b) Compact KPI/stat tiles on phones: the full-width "big circle centred over a
       label" cards are far too tall stacked on mobile. Reflow them to a short
       horizontal row (circle left, label right). Targets any card-body holding an
       avatar-xl stat circle (dashboard, stock, loan, cti summary tiles). */
@media (max-width: 767.98px) {
    .card-body:has(.avatar-xl) {
        display: flex;
        align-items: center;
        gap: 1rem;
        padding: 1rem 1.25rem;
    }
    .card-body:has(.avatar-xl) > .d-flex {
        margin-bottom: 0 !important;
        justify-content: flex-start !important;
        flex: 0 0 auto;
    }
    .card-body:has(.avatar-xl) > .text-center { text-align: left !important; }
    .card-body:has(.avatar-xl) h5 { margin-bottom: 0; }
    .avatar.avatar-xl { width: 3.25rem !important; height: 3.25rem !important; }
    .avatar.avatar-xl .avatar-initial { font-size: 0.95rem !important; }
}

/* (c) DataTables top controls (length / search / Export / Add) misalign below the theme's xl
       breakpoint: they live in a nested grid (`.col-md-2` length + `.col-md-10 > .dt-action-buttons`,
       the latter `flex-direction:column`), so items in different containers never line up. FLATTEN
       the whole thing into ONE flex row with `display:contents` — length/search/buttons become
       siblings of the row and align uniformly; the search grows, and it all wraps into clean,
       aligned rows when it can't fit on one line. Covers everything below xl (the theme only goes
       inline at >=1200). */
@media (max-width: 1199.98px) {
    .dataTables_wrapper .row:has(.dataTables_length, .dt-action-buttons) {
        display: flex !important;
        flex-wrap: wrap !important;
        align-items: center !important;
        gap: .5rem !important;
        margin: 0 !important;
        padding: .6rem .25rem .8rem !important;   /* vertical breathing room */
    }
    /* dissolve the grid/wrapper layers so their children join the row's flex context */
    .dataTables_wrapper .row:has(.dataTables_length, .dt-action-buttons) > [class*="col-"],
    .dataTables_wrapper .col-md-2 .me-3,
    .dt-action-buttons { display: contents !important; }
    .dataTables_length { display: flex !important; align-items: center; margin: 0 !important; }
    .dataTables_length label { margin: 0; display: flex; align-items: center; }
    .dataTables_length select { width: auto; min-width: 52px; }
    .dataTables_filter { flex: 1 1 140px !important; min-width: 130px; margin: 0 !important; }
    .dataTables_filter label { width: 100%; margin: 0; }
    .dataTables_filter input { width: 100% !important; margin: 0 !important; }
    /* buttons must NOT grow (display:contents lets the theme's flex:1 1 auto make "Add" stretch
       to fill the row) — keep them compact so they sit inline / wrap as tidy chips */
    .dataTables_wrapper .dt-buttons,
    .dataTables_wrapper .add-new,
    .dataTables_wrapper .btn { flex: 0 0 auto !important; white-space: nowrap; }
}

/* (c2) Navbar global-search: its `.gs-wrap{min-width:260px}` is too wide on phones — it pushes the
        right-side icons (incl. the profile avatar) off the edge. Let it shrink on small screens. */
@media (max-width: 575.98px) {
    .gs-wrap { min-width: 0 !important; }
}

/* (d) Admin merge tools (mgmt_companies/contacts/models) — the two card-header action
       buttons ("Merge Selected into Main" btn-danger + "Suggest Duplicates"
       btn-outline-info) are inline-flex of different widths, so they wrap awkwardly on
       phones. Match them: both full-width, stacked, on mobile. The :has() combo is unique
       to those merge headers, so it won't touch ordinary card-header buttons. */
@media (max-width: 767.98px) {
    .card-header:has(.btn-danger):has(.btn-outline-info) > .btn {
        display: flex !important;
        width: 100% !important;
        margin-left: 0 !important;
        justify-content: center;
    }
    .card-header:has(.btn-danger):has(.btn-outline-info) > .btn + .btn { margin-top: .5rem !important; }
}

/* ============================================================================
   MODERN UI (merged in 2026-06-22, now the DEFAULT look — formerly the opt-in
   redesign/redesign.css skin). main.php / login.php hard-add the `.ui-modern`
   class to <html> (login also `page-login`), so every rule below always applies.
   Enterprise "Trust & Authority": deep-navy sidebar, brand-blue (#004a80)
   actions, Plus Jakarta Sans, soft radii, refined elevation, light + dark.
   To extend: add rules under `.ui-modern[.light-style|.dark-style]` using the
   tokens defined just below.
   ============================================================================ */

/* ---- 1. Design tokens (per theme) ---- */
.ui-modern.light-style {
  --m-bg:            #eef2f7;
  --m-surface:       #ffffff;
  --m-surface-2:     #f8fafc;
  --m-border:        #e2e8f0;
  --m-border-strong: #cbd5e1;
  --m-text:          #1e293b;
  --m-text-muted:    #64748b;
  --m-heading:       #0f172a;
  --m-primary:       #004a80;
  --m-primary-rgb:   0, 74, 128;
  --m-primary-hover: #013a64;
  --m-accent:        #0ea5e9;
  --m-sidebar-bg:    #0b1f33;
  --m-sidebar-grad:  linear-gradient(180deg, #0d2540 0%, #0a1a2c 100%);
  --m-sidebar-text:  #dbe5f1;   /* non-active item label — brightened for legibility on navy */
  --m-sidebar-mut:   #9aadc4;   /* icons / submenu / toggle — brightened (was too dim) */
  --m-sidebar-hover: rgba(255, 255, 255, 0.06);
  --m-sidebar-active:#1b78c9;
  --m-shadow-sm:     0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.05);
  --m-shadow-md:     0 4px 12px rgba(15, 23, 42, 0.08), 0 2px 4px rgba(15, 23, 42, 0.04);
  --m-shadow-lg:     0 12px 32px rgba(15, 23, 42, 0.14);
  --m-radius:        0.75rem;
  --m-radius-sm:     0.5rem;
  --m-ring:          rgba(0, 74, 128, 0.25);
}
.ui-modern.dark-style {
  --m-bg:            #0a111e;
  --m-surface:       #131c2e;
  --m-surface-2:     #1a2436;
  --m-border:        #25324a;
  --m-border-strong: #33425e;
  --m-text:          #e2e8f0;
  --m-text-muted:    #94a3b8;
  --m-heading:       #f1f5f9;
  --m-primary:       #2f80c2;
  --m-primary-rgb:   47, 128, 194;
  --m-primary-hover: #3a93da;
  --m-accent:        #38bdf8;
  --m-sidebar-bg:    #0a1422;
  --m-sidebar-grad:  linear-gradient(180deg, #0c1828 0%, #080f1b 100%);
  --m-sidebar-text:  #d6dfec;   /* non-active item label — brightened for legibility on navy */
  --m-sidebar-mut:   #90a2ba;   /* icons / submenu / toggle — brightened (was too dim) */
  --m-sidebar-hover: rgba(255, 255, 255, 0.05);
  --m-sidebar-active:#3a93da;
  --m-shadow-sm:     0 1px 2px rgba(0, 0, 0, 0.4);
  --m-shadow-md:     0 4px 14px rgba(0, 0, 0, 0.45);
  --m-shadow-lg:     0 16px 40px rgba(0, 0, 0, 0.6);
  --m-radius:        0.75rem;
  --m-radius-sm:     0.5rem;
  --m-ring:          rgba(58, 147, 218, 0.35);
}

/* ---- 2. Typography + canvas ---- */
.ui-modern,
.ui-modern body,
.ui-modern .menu,
.ui-modern .btn,
.ui-modern .form-control,
.ui-modern .form-select {
  font-family: 'Plus Jakarta Sans', -apple-system, 'Segoe UI', Roboto, system-ui, sans-serif;
}
.ui-modern body { background: var(--m-bg) !important; color: var(--m-text); letter-spacing: -0.002em; }
.ui-modern h1, .ui-modern h2, .ui-modern h3,
.ui-modern h4, .ui-modern h5, .ui-modern h6 { color: var(--m-heading); font-weight: 700; letter-spacing: -0.01em; }
.ui-modern .text-muted { color: var(--m-text-muted) !important; }
.ui-modern .table td,
.ui-modern .table th,
.ui-modern .avatar-initial,
.ui-modern .card .display-6,
.ui-modern .card h3 { font-variant-numeric: tabular-nums; }

/* ---- 3. Sidebar (deep navy, both modes) ---- */
.ui-modern #layout-menu.layout-menu,
.ui-modern .bg-menu-theme {
  background: var(--m-sidebar-grad) !important;
  border-right: 1px solid rgba(255, 255, 255, 0.04) !important;
  box-shadow: 0 0 24px rgba(0, 0, 0, 0.18);
}
.ui-modern #layout-menu .menu-inner-shadow { display: none; }
.ui-modern #layout-menu .app-brand {
  padding-block: 1.1rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  margin-bottom: 0.35rem;
}
.ui-modern #layout-menu .app-brand svg path[fill] { fill: #ffffff !important; }
.ui-modern #layout-menu .menu-toggle-icon,
.ui-modern #layout-menu .layout-menu-toggle i { color: var(--m-sidebar-mut) !important; }
.ui-modern #layout-menu .layout-menu-toggle:hover { background: var(--m-sidebar-hover) !important; color: #fff !important; }
.ui-modern #layout-menu .menu-inner > .menu-item { margin: 0.1rem 0.65rem; }
.ui-modern #layout-menu .menu-link {
  color: var(--m-sidebar-text) !important;
  border-radius: var(--m-radius-sm);
  font-weight: 500;
  transition: background-color .18s ease, color .18s ease;
}
.ui-modern #layout-menu .menu-inner > .menu-item > .menu-link { padding: 0.6rem 0.85rem; }
.ui-modern #layout-menu .menu-link .menu-icon { color: var(--m-sidebar-mut) !important; }
.ui-modern #layout-menu .menu-item:not(.active) > .menu-link:hover { background: var(--m-sidebar-hover) !important; color: #ffffff !important; }
.ui-modern #layout-menu .menu-item:not(.active) > .menu-link:hover .menu-icon { color: #fff !important; }
.ui-modern #layout-menu .menu-item.active > .menu-link {
  background: var(--m-sidebar-active) !important;
  color: #ffffff !important;
  font-weight: 600;
  box-shadow: 0 4px 12px rgba(27, 120, 201, 0.35);
}
.ui-modern #layout-menu .menu-item.active > .menu-link::before { display: none; }
.ui-modern.light-style #layout-menu .menu-item.active > .menu-link { background: var(--m-sidebar-active) !important; }
.ui-modern #layout-menu .menu-item.active > .menu-link .menu-icon { color: #fff !important; }
.ui-modern #layout-menu .menu-sub .menu-link { color: var(--m-sidebar-mut) !important; padding-block: 0.45rem; }
/* sub-item bullet = outline circle (active = filled brand dot) */
.ui-modern #layout-menu .menu-sub .menu-link::before {
  content: "" !important;
  width: 7px !important;
  height: 7px !important;
  border-radius: 50% !important;
  background: transparent !important;
  border: 1.5px solid var(--m-sidebar-mut) !important;
  top: 50% !important;
  left: 1.35rem !important;
  transform: translateY(-50%) !important;
}
.ui-modern #layout-menu .menu-sub .menu-link:hover::before { border-color: #fff !important; }
/* Active SUB-item (under an open parent): a SUBTLE highlight + the filled dot — NOT the
   full active pill/glow (that heavy treatment is for top-level items; on an indented
   sub-item it read as a weird floating glow). Kill the box-shadow explicitly. */
.ui-modern #layout-menu .menu-item.active .menu-sub .menu-item.active > .menu-link { color: #ffffff !important; background: var(--m-sidebar-hover) !important; box-shadow: none !important; }
.ui-modern #layout-menu .menu-sub .menu-item.active > .menu-link::before { display: inline-block !important; background: var(--m-sidebar-active) !important; border-color: var(--m-sidebar-active) !important; }
.ui-modern #layout-menu .menu-sub .menu-link:hover { color: #fff !important; }
.ui-modern #layout-menu .menu-item.open:not(.active) > .menu-toggle { background: var(--m-sidebar-hover) !important; color: #fff !important; }

/* ---- 4. Navbar ---- */
.ui-modern .layout-navbar .navbar-detached,
.ui-modern .navbar-detached {
  background: var(--m-surface) !important;
  border: 1px solid var(--m-border);
  border-radius: var(--m-radius);
  box-shadow: var(--m-shadow-sm);
  backdrop-filter: saturate(140%) blur(6px);
}
.ui-modern .layout-navbar { box-shadow: none !important; }
.ui-modern .navbar .nav-item .nav-link,
.ui-modern .navbar .search-toggler { color: var(--m-text-muted) !important; }
.ui-modern .navbar .nav-item .nav-link:hover { color: var(--m-primary) !important; }
.ui-modern #gsInput,
.ui-modern .gs-input {
  background: var(--m-surface-2) !important;
  border: 1px solid var(--m-border) !important;
  border-radius: 999px !important;
  height: 40px;
  padding-left: 0.95rem !important;
  color: var(--m-text);
}
.ui-modern #gsInput:focus,
.ui-modern .gs-input:focus { border-color: var(--m-primary) !important; box-shadow: 0 0 0 3px var(--m-ring) !important; background: var(--m-surface) !important; }
.ui-modern .global-search-results {
  background: var(--m-surface) !important;
  border-color: var(--m-border) !important;
  border-radius: var(--m-radius) !important;
  box-shadow: var(--m-shadow-lg) !important;
  margin-top: 0.4rem;
}
.ui-modern .gsr-item { color: var(--m-text) !important; }
.ui-modern .gsr-item:hover { background: var(--m-surface-2) !important; color: var(--m-primary) !important; }
.ui-modern .avatar-online::after { box-shadow: 0 0 0 2px var(--m-surface); }

/* ---- 5. Cards ---- */
.ui-modern .card {
  background: var(--m-surface) !important;
  border: 1px solid var(--m-border) !important;
  border-radius: var(--m-radius) !important;
  box-shadow: var(--m-shadow-sm) !important;
  transition: box-shadow .2s ease, transform .2s ease;
}
.ui-modern .card .card-header {
  background: transparent !important;
  border-bottom: 1px solid var(--m-border);
  font-weight: 600;
  color: var(--m-heading);
  padding: 1.1rem 1.25rem;
}
/* A card-body directly under a card-header was rendering with padding-top:0 (its bottom padding stayed
   1.5rem — asymmetric), so the first form field sat right ON the header's border line. Restore the top
   padding so content clears the header separator. */
.ui-modern .card .card-header + .card-body { padding-top: 1.5rem !important; }
.ui-modern .card .card-title { color: var(--m-heading); font-weight: 700; }
.ui-modern a.card:hover,
.ui-modern .card.cursor-pointer:hover,
.ui-modern .card-hover:hover { box-shadow: var(--m-shadow-md) !important; transform: translateY(-2px); }
.ui-modern .avatar .avatar-initial { border-radius: var(--m-radius-sm); font-weight: 700; }

/* ---- 6. Tables (incl. DataTables) ---- */
.ui-modern .table { color: var(--m-text); }
.ui-modern .table > :not(caption) > * > * { background: transparent; }
.ui-modern .table thead th,
.ui-modern table.dataTable thead th,
.ui-modern table.dataTable thead td {
  text-transform: uppercase;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  font-weight: 700;
  color: var(--m-text-muted) !important;
  border-bottom: 1px solid var(--m-border-strong) !important;
  background: var(--m-surface-2) !important;
  padding-top: 0.85rem;
  padding-bottom: 0.85rem;
}
.ui-modern .table tbody td { border-bottom: 1px solid var(--m-border); padding-top: 0.8rem; padding-bottom: 0.8rem; vertical-align: middle; }
.ui-modern .table-hover tbody tr:hover > *,
.ui-modern table.dataTable.table-hover tbody tr:hover > * { background: rgba(var(--m-primary-rgb), 0.05) !important; }
.ui-modern table.dataTable td { color: var(--m-text); }
.ui-modern .dataTables_wrapper .form-control,
.ui-modern .dataTables_wrapper .form-select { border-radius: 999px; }
.ui-modern .dataTables_wrapper .pagination .page-link { border-radius: var(--m-radius-sm); margin: 0 2px; border: 1px solid var(--m-border); color: var(--m-text-muted); }
.ui-modern .dataTables_wrapper .pagination .page-item.active .page-link { background: var(--m-primary); border-color: var(--m-primary); color: #fff; }

/* ---- 7. Buttons ---- */
.ui-modern .btn { border-radius: var(--m-radius-sm); font-weight: 600; letter-spacing: 0.01em; transition: transform .12s ease, box-shadow .15s ease, background-color .15s ease, border-color .15s ease; }
.ui-modern .btn:active { transform: translateY(0); }
.ui-modern .btn:not(.btn-link):hover { transform: translateY(-1px); }
.ui-modern .btn:focus-visible { box-shadow: 0 0 0 3px var(--m-ring) !important; outline: none; }
.ui-modern .btn-primary { background: var(--m-primary); border-color: var(--m-primary); box-shadow: 0 2px 8px rgba(var(--m-primary-rgb), 0.3); }
.ui-modern .btn-primary:hover,
.ui-modern .btn-primary:focus { background: var(--m-primary-hover); border-color: var(--m-primary-hover); box-shadow: 0 6px 18px rgba(var(--m-primary-rgb), 0.4); }
.ui-modern .btn-outline-primary { color: var(--m-primary); border-color: var(--m-primary); }
.ui-modern .btn-outline-primary:hover { background: var(--m-primary); border-color: var(--m-primary); }

/* ---- 8. Forms / inputs / select2 ---- */
.ui-modern .form-control,
.ui-modern .form-select,
.ui-modern .select2-container--default .select2-selection--single,
.ui-modern .input-group-text {
  border-radius: var(--m-radius-sm) !important;
  border-color: var(--m-border-strong);
  background-color: var(--m-surface);
  color: var(--m-text);
}
.ui-modern .form-control:focus,
.ui-modern .form-select:focus { border-color: var(--m-primary); box-shadow: 0 0 0 3px var(--m-ring); }
.ui-modern.dark-style .form-control,
.ui-modern.dark-style .form-select { background-color: var(--m-surface-2); }
.ui-modern .form-control::placeholder { color: var(--m-text-muted); }
/* floating-label inputs need a transparent placeholder (the label doubles as it) */
.ui-modern .form-floating > .form-control::placeholder { color: transparent; }
.ui-modern .form-label,
.ui-modern .col-form-label { color: var(--m-text); font-weight: 600; }
.ui-modern .select2-container--default.select2-container--focus .select2-selection--single,
.ui-modern .select2-container--default.select2-container--open .select2-selection--single { border-color: var(--m-primary) !important; box-shadow: 0 0 0 3px var(--m-ring); }
.ui-modern .select2-dropdown { border-color: var(--m-border-strong); border-radius: var(--m-radius-sm); box-shadow: var(--m-shadow-md); }
/* Input-group seam: the radius above re-rounds ALL corners of select2 selections / form-controls
   (and buttons via `.ui-modern .btn`), which breaks the square INNER corners an input-group needs —
   so a field and its trailing "New" button join with mismatched sharp-vs-round edges (edit-stock
   modal). Re-square the inner corners: the field's RIGHT side, the trailing button's LEFT side. */
.ui-modern .input-group > .select2-container:not(:last-child) .select2-selection--single,
.ui-modern .input-group > .form-control:not(:last-child),
.ui-modern .input-group > .form-select:not(:last-child) {
  border-top-right-radius: 0 !important;
  border-bottom-right-radius: 0 !important;
}
.ui-modern .input-group > .btn:last-child,
.ui-modern .input-group > .input-group-text:last-child {
  border-top-left-radius: 0 !important;
  border-bottom-left-radius: 0 !important;
}
/* LEADING-addon case (the trailing rules above only handle a trailing button/addon): e.g. the
   loan-edit "Loan #" field = a `#` `.input-group-text` BEFORE the value `.form-control`. Square the
   addon's RIGHT corners and the following field's LEFT corners so the badge and the box meet flush
   instead of each keeping the modern full radius. */
.ui-modern .input-group > .input-group-text:not(:last-child) {
  border-top-right-radius: 0 !important;
  border-bottom-right-radius: 0 !important;
}
.ui-modern .input-group > .form-control:not(:first-child),
.ui-modern .input-group > .form-select:not(:first-child) {
  border-top-left-radius: 0 !important;
  border-bottom-left-radius: 0 !important;
}
/* select2 inside an input-group (e.g. the Add/Link-Participant modal's contact picker + "New
   Participant" button) must STRETCH to meet the trailing button. KEY GOTCHA: common.js wraps the
   <select> in a `<div class="position-relative">` BEFORE calling .select2(), so the input-group's
   flex child is that WRAPPER — not the `.select2-container`/`.form-select` — which is why the
   direct-child seam rules (and an earlier `.select2-container` width fix) never reached it and the
   field sat narrow with a gap before the button. Target the wrapper: make it the growing flex item,
   the select2 fill it, and square the wrapper's inner (right) corners so the edges sit flush. Theme-
   level (not skin-scoped) so it holds under modern + glass; the button's left corner is squared by
   the `.ui-modern .input-group > .btn:last-child` rule above. */
.input-group > .position-relative {
  flex: 1 1 auto;
  width: 1%;
  min-width: 0;
}
.input-group > .position-relative > .select2-container { width: 100% !important; }
.input-group > .position-relative:not(:last-child) .select2-selection--single {
  border-top-right-radius: 0 !important;
  border-bottom-right-radius: 0 !important;
}
/* Fallback for a select2 that is a DIRECT input-group child (not wrapped). */
.input-group > .select2-container { flex: 1 1 auto; width: auto !important; }
.ui-modern .form-check-input:checked { background-color: var(--m-primary); border-color: var(--m-primary); }
.ui-modern .form-check-input:focus { box-shadow: 0 0 0 3px var(--m-ring); }

/* ---- 9. Badges ---- */
.ui-modern .badge { border-radius: 0.4rem; font-weight: 600; letter-spacing: 0.01em; }
.ui-modern .badge.rounded-pill { border-radius: 999px; }

/* DARK-MODE label contrast: the theme's tinted "label" buttons + badges (btn-label-* /
   bg-label-*) put a saturated text colour on a very dark tinted fill (~3:1 — below AA).
   Brighten the text per variant so it reads (e.g. dashboard quick-actions, overdue badges). */
.ui-modern.dark-style .btn-label-primary,   .ui-modern.dark-style .badge.bg-label-primary   { color: #6cc4ff !important; }
.ui-modern.dark-style .btn-label-secondary, .ui-modern.dark-style .badge.bg-label-secondary { color: #b9c0cc !important; }
.ui-modern.dark-style .btn-label-success,   .ui-modern.dark-style .badge.bg-label-success   { color: #5ddf96 !important; }
.ui-modern.dark-style .btn-label-danger,    .ui-modern.dark-style .badge.bg-label-danger    { color: #ff7b7c !important; }
.ui-modern.dark-style .btn-label-warning,   .ui-modern.dark-style .badge.bg-label-warning   { color: #ffc065 !important; }
.ui-modern.dark-style .btn-label-info,      .ui-modern.dark-style .badge.bg-label-info      { color: #4ad6e6 !important; }
.ui-modern.dark-style .btn-label-dark,      .ui-modern.dark-style .badge.bg-label-dark      { color: #c5cad6 !important; }

/* ---- 10. Dropdowns / modals / alerts (incl. SweetAlert) ---- */
.ui-modern .dropdown-menu { background: var(--m-surface) !important; border: 1px solid var(--m-border); border-radius: var(--m-radius); box-shadow: var(--m-shadow-lg); padding: 0.4rem; }
.ui-modern .dropdown-item { border-radius: var(--m-radius-sm); color: var(--m-text); padding: 0.5rem 0.75rem; }
.ui-modern .dropdown-item:hover { background: var(--m-surface-2); color: var(--m-primary); }
.ui-modern .dropdown-divider { border-color: var(--m-border); }
.ui-modern .modal-content { background: var(--m-surface); border: 1px solid var(--m-border); border-radius: calc(var(--m-radius) + 0.25rem); box-shadow: var(--m-shadow-lg); }
.ui-modern .modal-header,
.ui-modern .modal-footer { border-color: var(--m-border); }
.ui-modern .modal-backdrop.show { -webkit-backdrop-filter: blur(6px) saturate(120%); backdrop-filter: blur(6px) saturate(120%); opacity: 0.55; }
.ui-modern .swal2-popup { border-radius: var(--m-radius) !important; background: var(--m-surface) !important; box-shadow: var(--m-shadow-lg) !important; }
.ui-modern .swal2-popup .swal2-title,
.ui-modern .swal2-popup .swal2-html-container { color: var(--m-text) !important; }
.ui-modern .swal2-styled.swal2-confirm { border-radius: var(--m-radius-sm) !important; background: var(--m-primary) !important; }
.ui-modern .alert { border-radius: var(--m-radius-sm); }
.ui-modern hr,
.ui-modern .border,
.ui-modern .border-top,
.ui-modern .border-bottom { border-color: var(--m-border) !important; }

/* ---- 11. Busy overlay (inline-styled in main.php) ---- */
.ui-modern #appBusyOverlay { background: rgba(7, 13, 24, 0.62) !important; backdrop-filter: blur(4px) saturate(120%); }
.ui-modern #appBusyMsg { font-family: 'Plus Jakarta Sans', system-ui, sans-serif; font-weight: 600 !important; letter-spacing: 0.01em; }

/* ---- 12. Login page (page-login, always light-style) ---- */
.ui-modern.page-login,
.ui-modern.page-login body { background: radial-gradient(1200px 600px at 50% -10%, #0d2540 0%, #08111d 60%) fixed !important; min-height: 100vh; }
.ui-modern.page-login .authentication-wrapper.authentication-basic { min-height: 100vh; }
.ui-modern.page-login .authentication-inner { width: 100%; max-width: 420px; }
.ui-modern.page-login .card { background: #ffffff !important; border: 1px solid var(--m-border) !important; border-radius: 1.1rem !important; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45) !important; }
.ui-modern.page-login .card-body { padding: 2.25rem 2rem; }
.ui-modern.page-login .app-brand svg { max-width: 100%; height: auto; }
.ui-modern.page-login .divider-text { color: #94a3b8; font-size: 0.72rem; letter-spacing: 0.06em; }
.ui-modern.page-login .btn-primary { background: var(--m-primary); border-color: var(--m-primary); padding-block: 0.7rem; font-size: 1rem; }

/* ---- 13. Accessibility — respect reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
  .ui-modern *,
  .ui-modern *::before,
  .ui-modern *::after { transition-duration: 0.001ms !important; animation-duration: 0.001ms !important; }
}

/* ============================================================================
   APPLE GLASSMORPHISM (merged as DEFAULT 2026-06-22; formerly the opt-in
   glass/ skin). main.php/login.php hard-add the .ui-glass class, so every rule
   below always applies, layered on top of the modern look. Translucent
   backdrop-filter panels + hairline borders over a vibrant ambient body gradient.
   Extend under .ui-glass[.light-style|.dark-style] using the --g-* tokens.
   ============================================================================ */
/* ---- tokens ---- */
.ui-glass.light-style {
  --g-blur: 22px;
  --g-radius: 20px;
  --g-panel:        rgba(255, 255, 255, 0.55);
  --g-panel-2:      rgba(255, 255, 255, 0.42);   /* slightly clearer (nested) */
  --g-border:       rgba(255, 255, 255, 0.65);
  --g-border-soft:  rgba(255, 255, 255, 0.35);
  --g-shadow:       0 10px 34px rgba(31, 41, 90, 0.14);
  --g-shadow-lg:    0 20px 60px rgba(31, 41, 90, 0.22);
  --g-text:         #1d2433;
  --g-text-muted:   #5a6478;
  --g-sidebar:      rgba(14, 28, 50, 0.55);
  --g-sidebar-text: #e7eefb;
  --g-sidebar-mut:  #b6c4dc;
}
.ui-glass.dark-style {
  --g-blur: 26px;
  --g-radius: 20px;
  --g-panel:        rgba(255, 255, 255, 0.09);
  --g-panel-2:      rgba(255, 255, 255, 0.06);
  --g-border:       rgba(255, 255, 255, 0.18);
  --g-border-soft:  rgba(255, 255, 255, 0.10);
  --g-shadow:       0 10px 34px rgba(0, 0, 0, 0.45);
  --g-shadow-lg:    0 22px 60px rgba(0, 0, 0, 0.6);
  --g-text:         #eaf0fb;
  --g-text-muted:   #aab6cc;
  --g-sidebar:      rgba(10, 18, 32, 0.50);
  --g-sidebar-text: #e7eefb;
  --g-sidebar-mut:  #9fb0c9;
}

/* ---- 1. Ambient backdrop (the vibrant surface the glass blurs) ---- */
.ui-glass.light-style body {
  background:
    radial-gradient(900px 520px at 12% -8%, rgba(56, 132, 255, 0.30), transparent 60%),
    radial-gradient(820px 520px at 92% 4%, rgba(168, 85, 247, 0.24), transparent 60%),
    radial-gradient(900px 600px at 70% 108%, rgba(20, 184, 166, 0.22), transparent 60%),
    linear-gradient(160deg, #eef3fc 0%, #e7ecf7 100%) !important;
  background-attachment: fixed !important;
}
.ui-glass.dark-style body {
  background:
    radial-gradient(820px 480px at 8% -6%, rgba(59, 130, 246, 0.40), transparent 58%),
    radial-gradient(760px 480px at 96% 0%, rgba(147, 90, 246, 0.36), transparent 58%),
    radial-gradient(900px 600px at 74% 112%, rgba(20, 184, 166, 0.30), transparent 58%),
    linear-gradient(160deg, #0c1426 0%, #080d18 100%) !important;
  background-attachment: fixed !important;
}

/* ---- 2. Sidebar — frosted glass ---- */
.ui-glass #layout-menu.layout-menu,
.ui-glass .bg-menu-theme {
  background: var(--g-sidebar) !important;
  -webkit-backdrop-filter: blur(var(--g-blur)) saturate(160%);
  backdrop-filter: blur(var(--g-blur)) saturate(160%);
  border-right: 1px solid var(--g-border-soft) !important;
  box-shadow: var(--g-shadow);
}
.ui-glass #layout-menu .menu-link { color: var(--g-sidebar-text) !important; }
.ui-glass #layout-menu .menu-link .menu-icon,
.ui-glass #layout-menu .menu-sub .menu-link { color: var(--g-sidebar-mut) !important; }
.ui-glass #layout-menu .app-brand { border-bottom-color: var(--g-border-soft) !important; }
/* active item — luminous glass pill */
.ui-glass #layout-menu .menu-item.active > .menu-link {
  background: linear-gradient(135deg, rgba(56,132,255,0.9), rgba(99,102,241,0.85)) !important;
  box-shadow: 0 6px 20px rgba(56, 120, 255, 0.4) !important;
  color: #fff !important;
}
/* But an active SUB-item (menu-sub) must NOT get that luminous gradient pill + glow — on an
   indented sub-row it reads as a weird floating glow. Give it a subtle highlight instead (the
   filled brand dot from the modern ::before still marks it active). */
.ui-glass #layout-menu .menu-item.active .menu-sub .menu-item.active > .menu-link {
  background: rgba(255, 255, 255, 0.08) !important;
  box-shadow: none !important;
  color: #fff !important;
}

/* ---- 3. Navbar — frosted ---- */
.ui-glass .layout-navbar .navbar-detached,
.ui-glass .navbar-detached {
  background: var(--g-panel) !important;
  -webkit-backdrop-filter: blur(var(--g-blur)) saturate(180%);
  backdrop-filter: blur(var(--g-blur)) saturate(180%);
  border: 1px solid var(--g-border) !important;
  border-radius: var(--g-radius) !important;
  box-shadow: var(--g-shadow) !important;
}
.ui-glass #gsInput,
.ui-glass .gs-input {
  background: var(--g-panel-2) !important;
  border: 1px solid var(--g-border-soft) !important;
}

/* ---- 4. Cards / panels — the headline frosted-glass surface ---- */
.ui-glass .card {
  background: var(--g-panel) !important;
  -webkit-backdrop-filter: blur(var(--g-blur)) saturate(180%);
  backdrop-filter: blur(var(--g-blur)) saturate(180%);
  border: 1px solid var(--g-border) !important;
  border-radius: var(--g-radius) !important;
  box-shadow: var(--g-shadow) !important;
  color: var(--g-text);
  transition: transform .25s cubic-bezier(0.16,1,0.3,1), box-shadow .25s ease;
}
.ui-glass .card .card-header { border-bottom-color: var(--g-border-soft) !important; color: var(--g-text); }
.ui-glass a.card:hover,
.ui-glass .card.cursor-pointer:hover,
.ui-glass .card-hover:hover {
  transform: translateY(-3px) scale(1.01);
  box-shadow: var(--g-shadow-lg) !important;
}
/* a subtle top "light reflection" edge on cards */
.ui-glass .card::before {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  padding-top: 1px;
  background: linear-gradient(180deg, rgba(255,255,255,0.5), transparent 28%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  pointer-events: none; opacity: 0.6;
}
.ui-glass .card { position: relative; }
.ui-glass.dark-style .card::before { background: linear-gradient(180deg, rgba(255,255,255,0.18), transparent 26%); }

/* readable text on the glass */
.ui-glass .card, .ui-glass .card p, .ui-glass .card small,
.ui-glass .table { color: var(--g-text); }
.ui-glass .text-muted { color: var(--g-text-muted) !important; }

/* ---- 5. Tables: let the card glass show through ---- */
.ui-glass .table,
.ui-glass table.dataTable { background: transparent !important; }
.ui-glass .table thead th,
.ui-glass table.dataTable thead th {
  background: var(--g-panel-2) !important;
  border-bottom-color: var(--g-border-soft) !important;
  color: var(--g-text-muted) !important;
}
.ui-glass .table tbody td { border-bottom-color: var(--g-border-soft) !important; }
.ui-glass .table-hover tbody tr:hover > *,
.ui-glass table.dataTable.table-hover tbody tr:hover > * {
  background: rgba(120, 150, 255, 0.10) !important;
}

/* ---- 6. Buttons ---- */
.ui-glass .btn { border-radius: 12px; }
.ui-glass .btn-primary {
  background: linear-gradient(135deg, #3884ff, #6366f1) !important;
  border: 0 !important;
  box-shadow: 0 6px 18px rgba(56, 120, 255, 0.4) !important;
}
.ui-glass .btn-primary:hover { box-shadow: 0 10px 26px rgba(56, 120, 255, 0.5) !important; transform: translateY(-1px); }
/* tinted "label" buttons (e.g. the Cancel buttons) — give them the VISIBLE `--m-border-strong` border
   APP-WIDE, not just on opaque surfaces. The faint `--g-border-soft` was invisible on both light glass
   cards (the Class Details form's Cancel) AND the opaque white modal/popup, so a `btn-label-secondary`
   Cancel read as plain borderless text everywhere. One global rule keeps every Cancel/secondary button
   clearly bordered and consistent (cards + modals + swal popups). */
.ui-glass [class*="btn-label-"] {
  background: var(--g-panel-2) !important;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--m-border-strong) !important;
}

/* ---- 7. Inputs / selects ----
   ALL form fields follow the change-password / opaque-modal field style APP-WIDE (decided 2026-06-23):
   the original glass field used a translucent bg + faint `--g-border-soft` border that, on light glass
   CARDS (e.g. the Class Details form), was barely visible ("can't see the fields"). Route every field
   to the visible modern tokens — solid `--m-surface-2` bg + `--m-border-strong` border + `--m-text` —
   exactly like `.ui-glass .modal-content .form-control`. This makes the `.modal-content`/`.swal2-popup`
   field overrides redundant (kept, harmless) and means NEW fields get a visible border automatically. */
.ui-glass .form-control,
.ui-glass .form-select,
.ui-glass .select2-container--default .select2-selection--single,
.ui-glass .input-group-text {
  background-color: var(--m-surface-2) !important;
  border: 1px solid var(--m-border-strong) !important;
  color: var(--m-text) !important;
  border-radius: 12px !important;
}
.ui-glass .form-control:focus,
.ui-glass .form-select:focus,
.ui-glass .select2-container--default.select2-container--focus .select2-selection--single,
.ui-glass .select2-container--default.select2-container--open .select2-selection--single {
  border-color: var(--m-primary, #004a80) !important;
  box-shadow: 0 0 0 3px var(--m-ring, rgba(0, 74, 128, 0.25)) !important;
}
/* `input-group-merge` ("#" addon + value rendered as ONE merged field, e.g. the loan-edit "Loan #"):
   drop the INNER border between adjacent items so there's no divider line. The global field/addon
   `--m-border-strong` border above draws a seam otherwise. More specific than the base field rule
   (`.ui-glass .input-group-merge .…` = 3 classes) so it wins; the OUTER border is kept. */
.ui-glass .input-group-merge > .input-group-text:not(:last-child),
.ui-glass .input-group-merge > .form-control:not(:last-child) {
  border-right: 0 !important;
}
.ui-glass .input-group-merge > .input-group-text:not(:first-child),
.ui-glass .input-group-merge > .form-control:not(:first-child) {
  border-left: 0 !important;
}

/* Uniform badge height + vertically-centered content so text badges, icon-only badges, and the
   capacity badges all line up (avoids the status / bed-icon / capacity height mismatch). A FIXED height
   (not min-height) is required: an icon like ti-bed has a larger font-size than the badge text, so with
   min-height the icon badge ends up a hair taller. Vertical padding is zeroed (height + centering owns
   the box); horizontal padding is kept. Applies app-wide; badge content is short/single-line. */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 1.5rem;
  padding-top: 0;
  padding-bottom: 0;
  line-height: 1;
  vertical-align: middle;
}
.badge > .ti { font-size: 0.95rem; }

/* ---- 8. Badges ---- */
.ui-glass .badge[class*="bg-label-"] {
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  border: 1px solid var(--g-border-soft);
}
/* The pale bg-label-* tint "flushes" into the page because --g-border-soft is a translucent WHITE edge
   (invisible on the light panel). Give the badge a CONTRASTING edge per theme so it's clearly delineated
   from the background in both light and dark mode. */
.ui-glass.light-style .badge[class*="bg-label-"] { border-color: rgba(15, 23, 42, 0.16); }
.ui-glass.dark-style  .badge[class*="bg-label-"] { border-color: rgba(255, 255, 255, 0.22); }

/* ---- 9. Dropdowns / modals — heavy frosted glass ---- */
.ui-glass .dropdown-menu {
  /* dropdown MENUS carry readable content, so they must be near-opaque — the translucent
     --g-panel let them blend into the page behind. Keep a light frost + the shadow. */
  -webkit-backdrop-filter: blur(12px) saturate(160%);
  backdrop-filter: blur(12px) saturate(160%);
  border: 1px solid var(--g-border) !important;
  border-radius: 16px !important;
  box-shadow: var(--g-shadow-lg) !important;
}
.ui-glass.light-style .dropdown-menu { background: rgba(255, 255, 255, 0.97) !important; }
.ui-glass.dark-style  .dropdown-menu { background: rgba(19, 27, 44, 0.97) !important; }
.ui-glass .dropdown-item { color: var(--g-text); border-radius: 10px; }
.ui-glass .modal-content {
  /* Modals are CONTENT surfaces (edit forms) — they must be OPAQUE, same rule as the
     swal2 popup + dropdown menu below. A translucent panel + backdrop-filter:blur made every
     edit modal look frosted/washed-out ("all edit modals blurry"). Keep the glass border/radius/
     shadow, but a solid background and NO backdrop-filter so the form is crisp and readable. */
  background: #ffffff !important;
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  border: 1px solid var(--g-border) !important;
  border-radius: 24px !important;
  box-shadow: var(--g-shadow-lg) !important;
  color: var(--g-text);
}
.ui-glass.light-style .modal-content { background: #ffffff !important; }
.ui-glass.dark-style  .modal-content { background: #161f33 !important; }
/* Inputs INSIDE the now-opaque modal: the glass skin gives form fields a translucent-WHITE
   background + border (fine over a frosted panel) — but on the solid modal they're white-on-white
   and the field looks borderless. Force a solid background + a visible border (modern tokens). More
   specific than `.ui-glass .form-control`, so it wins. */
.ui-glass .modal-content .form-control,
.ui-glass .modal-content .form-select,
.ui-glass .modal-content .select2-container--default .select2-selection--single,
.ui-glass .modal-content .input-group-text {
  background-color: var(--m-surface-2) !important;
  border: 1px solid var(--m-border-strong) !important;
  color: var(--m-text) !important;
}
.ui-glass .modal-content .form-control:focus,
.ui-glass .modal-content .form-select:focus,
.ui-glass .modal-content .select2-container--default.select2-container--focus .select2-selection--single,
.ui-glass .modal-content .select2-container--default.select2-container--open .select2-selection--single {
  border-color: var(--m-primary, #004a80) !important;
}
.ui-glass .modal-header, .ui-glass .modal-footer { border-color: var(--g-border-soft) !important; }
/* Frosted blur behind modals (re-enabled 2026-06-23 by request). The earlier "edit modal is blurry"
   bug was NOT this blur per se — it was modals TRAPPED in a card's stacking context so they got blurred
   too; that's fixed by the move-to-body `show.bs.modal` handler (common.js), so the modal now paints
   ABOVE the backdrop and stays crisp while only the page behind is frosted. Keep the dim scrim + blur. */
.ui-glass .modal-backdrop.show { background: rgba(10, 16, 30, 0.45); -webkit-backdrop-filter: blur(6px) saturate(120%); backdrop-filter: blur(6px) saturate(120%); opacity: 1; }

/* SweetAlert backdrop — match the Bootstrap .modal-backdrop frosted scrim above so EVERY dialog
   (Swal alerts + confirms like "Mark as collected?") blurs the page behind it, consistent with the
   Bootstrap modals (e.g. Add New CTI Class). The swal2 popup itself stays fully opaque (below).
   Global (not skin-scoped) so it applies to every page; the body always carries ui-glass anyway. */
.swal2-container.swal2-backdrop-show {
  background: rgba(10, 16, 30, 0.45) !important;
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
}

.ui-glass .swal2-popup {
  /* Alerts must be FULLY OPAQUE: a translucent popup (a) lets the page bleed through and
     (b) makes the SweetAlert success-icon mask pieces translucent too, so the green ring
     shows through as a "line cutting across the circle". Solid bg = clean icon + readable. */
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  border: 1px solid var(--g-border) !important;
  border-radius: 22px !important;
}
.ui-glass.light-style .swal2-popup { background: #ffffff !important; }
.ui-glass.dark-style  .swal2-popup { background: #161f33 !important; }

/* SweetAlert auto-dismiss countdown bar (every ShowAlert sets timerProgressBar:true). SweetAlert's
   default rgba(0,0,0,.2) strip is ~invisible on the white/glass popup, so theme it: a clearly-visible
   primary-coloured bar, a touch taller, with its ends tucked into the popup's rounded bottom corners. */
.swal2-timer-progress-bar {
  height: 0.35em !important;
  background: var(--bs-primary, #696cff) !important;
  border-bottom-left-radius: 22px;
  border-bottom-right-radius: 22px;
}
/* Bootstrap form fields injected into a custom-`html` SweetAlert (e.g. the Reservation reserve
   dialog's seats + Remarks inputs) need the SAME visible-border treatment as MODAL fields: the
   swal2 popup is opaque (above), but the glass skin's `.form-control` uses a translucent-white bg +
   border that is invisible white-on-white on the solid popup -> the field looks "flushed out"
   (borderless). Mirror the `.ui-glass .modal-content .form-control` fix for `.swal2-popup`. */
.ui-glass .swal2-popup .form-control,
.ui-glass .swal2-popup .form-select,
.ui-glass .swal2-popup .input-group-text {
  background-color: var(--m-surface-2) !important;
  border: 1px solid var(--m-border-strong) !important;
  color: var(--m-text) !important;
}
.ui-glass .swal2-popup .form-control:focus,
.ui-glass .swal2-popup .form-select:focus {
  border-color: var(--m-primary, #004a80) !important;
}
/* belt-and-braces: pin the success-icon mask pieces to the popup colour (they normally track
   it, but make sure so no ring-line shows through) */
.ui-glass.light-style .swal2-success-circular-line-left,
.ui-glass.light-style .swal2-success-circular-line-right,
.ui-glass.light-style .swal2-success-fix { background-color: #ffffff !important; }
.ui-glass.dark-style .swal2-success-circular-line-left,
.ui-glass.dark-style .swal2-success-circular-line-right,
.ui-glass.dark-style .swal2-success-fix { background-color: #161f33 !important; }

/* ---- 10. KPI stat circles get a soft glow ---- */
.ui-glass .avatar.avatar-xl .avatar-initial,
.ui-glass .avatar .avatar-initial { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18); }

/* ---- 11. Busy overlay — frosted ---- */
.ui-glass #appBusyOverlay {
  background: rgba(10, 16, 30, 0.45) !important;
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  backdrop-filter: blur(10px) saturate(140%);
}

/* ---- 12. Login page — single floating glass card on the ambient backdrop ---- */
.ui-glass.page-login .card {
  background: var(--g-panel) !important;
  -webkit-backdrop-filter: blur(30px) saturate(180%);
  backdrop-filter: blur(30px) saturate(180%);
  border: 1px solid var(--g-border) !important;
  border-radius: 26px !important;
  box-shadow: var(--g-shadow-lg) !important;
}

/* ---- 13. Accessibility: drop blur where motion/transparency is unwanted ---- */
@media (prefers-reduced-transparency: reduce) {
  .ui-glass .card,
  .ui-glass .navbar-detached,
  .ui-glass .dropdown-menu,
  .ui-glass .modal-content { -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ui-glass .card { transition: none; }
}
