/* School MIS - admin theme overrides */
body { font-variant-ligatures: none; }
#sidebar, #sidebar .nav-pills .nav-link { font-family: inherit; font-size: inherit; }

/* Sidebar: fixed width, strictly ONE vertical column of links */
#sidebar {
    width: 240px;
    min-width: 240px;
    max-width: 240px;
}
#sidebar .nav-pills {
    display: block;
}
#sidebar .nav-pills .nav-link {
    display: block;
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    padding: .55rem .9rem;
    color: #495057;
    border-left: 3px solid transparent;
    transition: background-color .18s ease, color .18s ease,
                border-color .18s ease, padding-left .18s ease,
                transform .18s ease;
}
#sidebar .nav-pills .nav-link:hover {
    background-color: rgba(114, 47, 56, 0.08);
    color: #722f38;
    border-left-color: #722f38;
    padding-left: 1.15rem;
}
#sidebar .nav-pills .nav-link:hover i {
    transform: translateX(2px);
}
#sidebar .nav-pills .nav-link i {
    transition: transform .18s ease;
}

/* Sidebar sticks to the viewport on desktop and scrolls independently;
   the page content scrolls with normal document flow. */
@media (min-width: 768px) {
    #sidebar {
        position: sticky;
        top: 0;
        align-self: flex-start;
        height: 100vh;
        overflow-y: auto;
    }
}
#sidebar .nav-pills .nav-link.active {
    background-color: transparent;
    color: #212529;
    font-weight: 500;
    border-left: 3px solid #adb5bd;
}
#sidebar .nav-pills .nav-link[aria-expanded="true"] {
    background-color: transparent;
    color: #212529;
    font-weight: 500;
}

/* Sidebar sub-menu (collapsible groups) */
#sidebar .nav-pills .nav-link[data-bs-toggle="collapse"] {
    cursor: pointer;
    user-select: none;
}
#sidebar .nav-pills .nav-link[data-bs-toggle="collapse"] .bi-chevron-down {
    transition: transform .2s ease;
    font-size: .75rem;
    margin-left: auto;
    opacity: .7;
}
#sidebar .nav-pills .nav-link[aria-expanded="true"] .bi-chevron-down {
    transform: rotate(180deg);
}
#sidebar .nav-pills .collapse.show,
#sidebar .nav-pills .collapse.collapsing {
    background-color: transparent;
    border-left: 3px solid #e9ecef;
}
#sidebar .nav-pills .sub-link {
    padding-left: 2.2rem !important;
    font-size: .875rem;
    color: #6c757d;
    border-left: 3px solid transparent;
}
#sidebar .nav-pills .sub-link:hover {
    color: #722f38;
    padding-left: 2.4rem !important;
}
#sidebar .nav-pills .nav-link.sub-link.active,
#sidebar .nav-pills .nav-link.sub-link.active:hover,
#sidebar .nav-pills .nav-link.sub-link.active:focus,
#sidebar .nav-pills a.sub-link.active,
#sidebar .nav-pills a.sub-link.active:hover,
#sidebar .nav-pills a.sub-link.active:focus,
#sidebar .nav-pills .show > .nav-link.sub-link,
#sidebar .nav-pills .show > a.nav-link.sub-link,
#sidebar .nav-pills .collapsing > .nav-link.sub-link {
    background-color: transparent !important;
    background: none !important;
    color: #6c757d !important;
    font-weight: 400;
    border-left: 3px solid transparent !important;
    box-shadow: none !important;
}
#sidebar .nav-pills .show > .nav-link.sub-link:hover,
#sidebar .nav-pills .show > a.nav-link.sub-link:hover {
    color: #722f38 !important;
}
#sidebar .nav-pills .show > .nav-link.sub-link.active,
#sidebar .nav-pills .show > a.nav-link.sub-link.active {
    color: #212529 !important;
    font-weight: 500;
    border-left: 3px solid #adb5bd !important;
}
#sidebar .nav-pills .sub-link i.bi {
    font-size: .85rem;
    width: 1rem;
    text-align: center;
}
.nav-pills .nav-link { border-radius: 0; }
.form-label { font-weight: 600; margin-bottom: .35rem; }

/* ---------- Global smooth hover (whole app) ---------- */
table tbody tr {
    transition: background-color .15s ease;
}
table tbody tr:hover td {
    background-color: rgba(114,47,56,.055);
}
.table-hover > tbody > tr {
    transition: background-color .15s ease, box-shadow .15s ease;
}

/* Cards gently lift and gain a subtle shadow on hover */
.card {
    border: none;
    transition: transform .18s ease, box-shadow .18s ease;
}
.card:hover {
    transform: translateY(-3px);
    box-shadow: 0 .5rem 1rem rgba(0,0,0,.10);
}

/* Buttons: subtle lift + fade of background/shadow */
.btn {
    transition: transform .15s ease, box-shadow .15s ease,
                background-color .15s ease, color .15s ease,
                border-color .15s ease;
}
.btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 .25rem .5rem rgba(114,47,56,.22);
}
.btn:active {
    transform: translateY(0);
}

/* Inline links & nav links: smooth color fade */
a {
    transition: color .15s ease, background-color .15s ease;
}

/* Badges / progress cells relax smoothly */
.badge {
    transition: transform .15s ease, box-shadow .15s ease;
}
.badge:hover {
    transform: scale(1.08);
}

/* Dropdown items */
.dropdown-item {
    transition: background-color .15s ease, color .15s ease, padding-left .15s ease;
}
.dropdown-item:hover {
    padding-left: 1.2rem;
}

/* ---- Student overview (portal) filter bar ----
   Stays pinned below the top of the viewport while the operator scrolls a long
   list of wards, so the bucket counts and the order control stay reachable. */
.portal-filter-bar {
    position: sticky;
    top: 0;
    z-index: 1020;
    background-color: #f8f9fa;            /* matches <body class="bg-light"> */
    padding: .85rem 1rem .55rem;
    margin: -.25rem -1rem .75rem;
    border-bottom: 1px solid rgba(0, 0, 0, .08);
    border-radius: 0 0 .5rem .5rem;
}
/* Keep the labels readable when the bar overlaps content while scrolling. */
.portal-filter-bar .form-label {
    font-size: .8rem;
    color: #6c757d;
}
@media (max-width: 575.98px) {
    /* On phones the bar is taller; let it scroll with the page instead. */
    .portal-filter-bar {
        position: static;
        margin: -.25rem 0 .75rem;
        padding: .5rem 0;
    }
}

/* =====================================================================
   APP SHELL  (redesigned dashboard: navy sidebar + top header)
   Added after the original theme rules on purpose, so the overrides below
   win. Every existing route/markup keeps working; only presentation changed.
   ===================================================================== */
:root {
    /* ---- Brand palette ----
       Maroon #722f38 carries the structure (sidebar, top bar, primary
       actions); orange #ff7e00 is the accent (focus rings, active
       indicators, highlights). `--bs-primary-rgb` is overridden here too:
       Bootstrap paints .bg-primary / .text-primary / .text-bg-primary from
       that one variable, so the whole utility system follows the brand
       without touching a single view. */
    --app-navy:        #722f38;
    --app-navy-2:      #5e262e;
    --app-navy-soft:   #8f434d;
    --app-navy-hover:  #7d3741;
    --app-primary:     #722f38;
    --app-accent:      #ff7e00;
    --app-accent-ink:  #5c242c;
    --bs-primary-rgb:  114, 47, 56;
    --app-success:     #16a34a;
    --app-warning:     #f59e0b;
    --app-danger:      #e11d48;
    --app-info:        #0891b2;
    --app-purple:      #7c3aed;
    --app-bg:          #f7f4f3;
    --app-border:      #ece5e5;
    --app-text:        #1e293b;
    --app-muted:       #64748b;
    --app-radius:      14px;
    --app-radius-sm:   10px;
    --app-shadow:      0 1px 2px rgba(15, 23, 42, .04), 0 4px 14px rgba(15, 23, 42, .05);
    --app-shadow-lg:   0 8px 28px rgba(15, 23, 42, .10);
    --app-sidebar-w:   262px;
    --app-sidebar-mini: 76px;
    --app-topbar-h:    64px;

    /* ---- Typography scale (shared by the shell, the dashboard and every
       form/list screen so the whole app reads as one system) ---- */
    --app-font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
               "Noto Sans", "Liberation Sans", Arial, sans-serif,
               "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    --app-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas,
                     "Liberation Mono", monospace;
    --app-fs-base:   .9375rem;   /* 15px - the app's base body size        */
    --app-fs-sm:     .8125rem;   /* 13px - controls, table cells, meta     */
    --app-fs-xs:     .75rem;     /* 12px - labels, hints, badges           */
    --app-fw:        400;
    --app-fw-mid:    500;
    --app-fw-semi:   600;
    --app-fw-bold:   700;
    --app-focus-ring: 0 0 0 3px rgba(255, 126, 0, .32);
    --app-control-h:  38px;

    /* ---- Soft stat-tile palette ----
       Defaults for the legacy `.card.text-bg-*` tiles. Each variant overrides
       these three on itself (see the Cards section); they live here as well so
       every var() resolves from a top-level :root. */
    --tile-bg:    #f1f5f9;
    --tile-fg:    #0f172a;
    --tile-muted: #475569;
}

body.app-body {
    background-color: var(--app-bg);
    color: var(--app-text);
    margin: 0;
    -webkit-font-smoothing: antialiased;
}

/* Grid keeps the sidebar a real column: header on top, nav beside content. */
.app-shell {
    display: grid;
    grid-template-columns: var(--app-sidebar-w) minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas: "topbar topbar" "sidebar main";
    min-height: 100vh;
}

/* ---------------- Top header ---------------- */
.app-topbar {
    grid-area: topbar;
    position: sticky;
    top: 0;
    z-index: 1045;
    display: flex;
    align-items: center;
    gap: .6rem;
    height: var(--app-topbar-h);
    padding: 0 1rem;
    background: linear-gradient(90deg, var(--app-navy) 0%, var(--app-navy-2) 100%);
    color: #fff;
    box-shadow: 0 1px 0 rgba(255, 126, 0, .55), 0 2px 12px rgba(15, 23, 42, .18);
}
.app-topbar__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: 0 0 38px;
    border: 0;
    border-radius: var(--app-radius-sm);
    background: rgba(255, 255, 255, .10);
    color: #fff;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color .18s ease;
}
.app-topbar__toggle:hover { background: rgba(255, 255, 255, .20); }
.app-topbar__toggle:focus-visible { outline: 2px solid #ffb366; outline-offset: 2px; }

.app-brand {
    display: flex;
    align-items: center;
    gap: .65rem;
    color: #fff;
    text-decoration: none;
    min-width: 0;
}
.app-brand:hover { color: #fff; }
.app-brand__logo {
    width: 38px;
    height: 38px;
    flex: 0 0 38px;
    object-fit: contain;
    border-radius: 9px;
    background: rgba(255, 255, 255, .95);
    padding: 3px;
}
.app-brand__logo--fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.15rem;
    color: var(--app-navy);
}
.app-brand__text { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.app-brand__text strong {
    font-size: .95rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 46vw;
}
.app-brand__text small {
    font-size: .7rem;
    color: rgba(255, 255, 255, .68);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 46vw;
}
.app-topbar__spacer { flex: 1 1 auto; }

.app-topbar__meta { align-items: center; gap: .4rem; }
.app-chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .34rem .7rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .16);
    color: #fff;
    font-size: .78rem;
    font-weight: 500;
    white-space: nowrap;
}
.app-chip i { opacity: .8; }

.app-iconbtn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: 0 0 38px;
    border-radius: var(--app-radius-sm);
    background: rgba(255, 255, 255, .10);
    color: #fff;
    font-size: 1.05rem;
    text-decoration: none;
    transition: background-color .18s ease;
}
.app-iconbtn:hover { background: rgba(255, 255, 255, .20); color: #fff; }
.app-iconbtn__badge {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 18px;
    height: 18px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--app-danger);
    color: #fff;
    font-size: .66rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

/* ---------------- Sidebar ---------------- */
/* The original theme styled #sidebar as a fixed 240px light column; these rules
   replace it with the navy panel. Selectors match the originals' specificity
   (or beat them) so they win by order. */
#sidebar.app-sidebar {
    grid-area: sidebar;
    width: auto;
    min-width: 0;
    max-width: none;
    background: var(--app-navy);
    border-right: 0;
    box-shadow: none;
    position: sticky;
    top: var(--app-topbar-h);
    /* align-self:start is required for position:sticky to have any effect on a
       grid item - without it the item stretches to the row height and never
       actually sticks while the page scrolls. */
    align-self: start;
    height: calc(100vh - var(--app-topbar-h));
    /* A flex column is what makes the nav below a real scroll container.
       Without it the nav is a plain block that grows to its content height,
       and this element's overflow:hidden just clips the extra links with no
       way to reach them (no scrollbar). */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* CRITICAL: on phones this element becomes a fixed drawer (transform:
       translateX(-100%)) that slides over the page. It must stack ABOVE both
       the .app-backdrop (1040) and the sticky topbar (1045): while it sat at
       1035 the dim backdrop covered the open drawer itself, so every menu link
       looked faded AND was unclickable - taps landed on the backdrop, whose
       only job is to close the drawer again. */
    z-index: 1060;
}
#sidebar .app-sidebar__nav {
    display: flex;
    flex-direction: column;
    /* CRITICAL: Bootstrap's .nav sets `flex-wrap: wrap`. On a COLUMN flex
       container that wraps on the cross (horizontal) axis, so the nav links
       were being packed into several side-by-side columns instead of one
       vertical list. The extra columns overflowed horizontally (clipped by
       overflow-x:hidden, so those links were unreachable) while the block
       still fitted vertically - which is why no scrollbar ever appeared.
       nowrap restores a single vertical column that overflows vertically
       and therefore scrolls. */
    flex-wrap: nowrap;
    padding: .85rem .6rem 1.5rem;
    background: var(--app-navy);
    gap: 2px;
    /* flex:1 + min-height:0 lets the nav shrink below its content height so
       overflow-y:auto engages; min-height:0 is required inside a flex column
       (flex items default to min-height:auto and refuse to shrink). */
    flex: 1 1 auto;
    min-height: 0;
    /* Vertical scrolling ONLY. Note: Bootstrap's .overflow-auto utility is
       `overflow:auto !important` and would beat this, so the layout must not
       put that class on the nav (see layouts/app.php). */
    overflow-y: auto;
    overflow-x: hidden;
    max-width: 100%;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, .25) transparent;
}
#sidebar .app-sidebar__nav > * {
    /* CRITICAL: direct children are flex items of the column above and
       default to flex-shrink:1, so on a short viewport they were being
       SQUASHED to fit instead of overflowing. Because nothing overflowed,
       overflow-y:auto never engaged and no scrollbar appeared, while the
       group headers ("Students", "Academics"...) were crushed to a few
       pixels and the lower links were cut off with no way to reach them.
       Pinning each child to its natural height is what makes the nav
       overflow - and therefore scroll - instead of collapsing. */
    flex: 0 0 auto;
}
#sidebar .app-sidebar__nav::-webkit-scrollbar { width: 6px; }
#sidebar .app-sidebar__nav::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, .22);
    border-radius: 999px;
}

/* Group labels ("PEOPLE", "ACADEMICS"...) that break the flat list of nav
   links into scannable sections. Direct children of the column flex
   container, so they need the same flex:0 0 auto pinning as the links -
   without it they get squashed on a short viewport. */
#sidebar .app-sidebar__section {
    flex: 0 0 auto;
    margin: 1rem .75rem .3rem;
    font-size: .64rem;
    font-weight: 700;
    line-height: 1.4;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .42);
    pointer-events: none;
    user-select: none;
}
/* No label is ever the first child (Dashboard/portal lead the nav), but keep
   the top spacing tight if that ever changes. */
#sidebar .app-sidebar__section:first-child { margin-top: .2rem; }
/* Collapsed (mini) mode blanks out link text via font-size:0 on .nav-link;
   these are not .nav-link, so hide them outright or "PEOPLE" would wrap in a
   76px rail. */
body.sidebar-collapsed #sidebar .app-sidebar__section { display: none; }

#sidebar .nav-pills .nav-link,
#sidebar .nav-link {
    display: flex;
    align-items: center;
    gap: .55rem;
    width: 100%;
    padding: .58rem .7rem;
    margin: 0;
    border: 0;
    border-radius: var(--app-radius-sm);
    background: transparent;
    color: rgba(226, 232, 240, .82);
    font-size: .875rem;
    font-weight: 500;
    line-height: 1.35;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-decoration: none;
    transition: background-color .16s ease, color .16s ease;
}
#sidebar .nav-link i,
#sidebar .nav-link .bi {

    width: 1.15rem;
    text-align: center;
    font-size: .95rem;
    transition: none;
}
/* The original theme declared these with an extra ".nav-pills" in the
   selector, e.g. #sidebar .nav-pills .nav-link[aria-expanded="true"] which
   is specificity (1,3,0). A shorter selector like
   #sidebar .nav-link[aria-expanded="true"] is only (1,2,0) and LOSES, so
   the original's near-black `color: #212529` won and the group headers
   rendered dark-on-navy, i.e. effectively invisible. Both spellings are
   listed so these always win. */
#sidebar .nav-pills .nav-link:hover,
#sidebar .nav-link:hover,
#sidebar .nav-pills .nav-link:hover i,
#sidebar .nav-link:hover i {
    background-color: var(--app-navy-hover);
    color: #fff;
    border-left: 0;
    padding-left: .7rem;
    transform: none;
}
#sidebar .nav-pills .nav-link.active,
#sidebar .nav-pills .nav-link.active:hover,
#sidebar .nav-link.active,
#sidebar .nav-link.active:hover {
    /* Lifted maroon + inset orange rail: white text must stay legible on
       the maroon rail (WCAG), so the accent marks selection with an edge
       indicator and a warm glow instead of an orange fill. */
    background: var(--app-navy-soft) !important;
    color: #fff !important;
    font-weight: 600;
    border-left: 0 !important;
    box-shadow: inset 3px 0 0 var(--app-accent),
                0 4px 12px rgba(255, 126, 0, .22);
}
#sidebar .nav-link[aria-expanded="true"] {
    background: rgba(255, 255, 255, .06);
    color: #fff;
    font-weight: 600;
}
/* The chevron is taken out of flow so a long label can never push it
   (and the link) past the sidebar's width. */
#sidebar .nav-link[data-bs-toggle="collapse"] {
    position: relative;
    padding-right: 1.8rem;
}
#sidebar .nav-link .bi-chevron-down {
    position: absolute;
    right: .7rem;
    top: 50%;
    margin-left: 0;
    float: none !important;
    font-size: .7rem;
    opacity: .65;
    transform: translateY(-50%);
    transition: transform .2s ease;
}
#sidebar .nav-link[aria-expanded="true"] .bi-chevron-down {
    transform: translateY(-50%) rotate(180deg);
    color: var(--app-accent);
    opacity: .95;
}

/* Sub-links sit under their group, slightly indented and lighter. */
#sidebar .nav-pills .sub-link,
#sidebar .nav-link.sub-link {
    padding-left: 1.5rem !important;
    font-size: .82rem;
    color: rgba(203, 213, 225, .72) !important;
    background: transparent !important;
    font-weight: 400;
    border-left: 0 !important;
    box-shadow: none !important;
}
#sidebar .nav-pills .sub-link:hover,
#sidebar .nav-link.sub-link:hover {
    background: var(--app-navy-hover) !important;
    color: #fff !important;
    padding-left: 1.6rem !important;
}
#sidebar .nav-pills .sub-link.active,
#sidebar .nav-pills .sub-link.active:hover,
#sidebar .nav-pills a.sub-link.active,
#sidebar .nav-pills .show > a.nav-link.sub-link,
#sidebar .nav-pills .collapsing > a.nav-link.sub-link {
    background: rgba(255, 126, 0, .16) !important;
    color: #fff !important;
    font-weight: 600;
    border-left: 0 !important;
    box-shadow: none !important;
}
/* The ACTIVE sub-link ("All Students" while on /students) must out-rank the
   original theme's
       #sidebar .nav-pills .show > a.nav-link.sub-link.active
           { color: #212529 !important; border-left: 3px solid #adb5bd !important; }
   That selector is specificity (1,5,0). Because BOTH declarations are
   !important, CSS falls back to specificity - so a shorter override such as
   #sidebar .nav-pills .sub-link.active, at (1,3,0), LOSES and the active link
   rendered near-black on the blue pill. The selectors below deliberately
   match (1,5,0) and appear later, so they win. */
#sidebar .nav-pills .show > a.nav-link.sub-link.active,
#sidebar .nav-pills .show > .nav-link.sub-link.active,
#sidebar .nav-pills .nav-link.sub-link.active,
#sidebar .nav-pills a.nav-link.sub-link.active,
#sidebar .nav-pills .sub-link.active {
    background: var(--app-navy-soft) !important;
    color: #fff !important;
    font-weight: 600;
    border-left: 0 !important;
    box-shadow: inset 3px 0 0 var(--app-accent),
                0 2px 10px rgba(255, 126, 0, .22) !important;
}
#sidebar .nav-pills .collapse.show,
#sidebar .nav-pills .collapse.collapsing {
    background: transparent;
    border-left: 0;
}
#sidebar .nav-pills .sub-link i.bi { font-size: .8rem; width: 1rem; }

/* Collapsed (desktop) — icons only.
   The existing nav labels are bare text nodes (not wrapped in spans), so the
   text is collapsed via font-size:0 on the link while the icon keeps its own
   size. That avoids editing every nav link in the layout. */
body.sidebar-collapsed { --app-sidebar-w: var(--app-sidebar-mini); }
body.sidebar-collapsed #sidebar .nav-link {
    justify-content: center;
    padding-left: .7rem;
    padding-right: .7rem;
    font-size: 0;
    gap: 0;
}
body.sidebar-collapsed #sidebar .nav-link i,
body.sidebar-collapsed #sidebar .nav-link .bi {
    font-size: 1.05rem;
    width: auto;
}
body.sidebar-collapsed #sidebar .nav-link .bi-chevron-down { display: none; }

/* ---------------- Content area ---------------- */
.app-main { grid-area: main; min-width: 0; }
.app-content { padding: 1.1rem 1.25rem 2.5rem; }
@media (max-width: 575.98px) {
    .app-content { padding: .85rem .75rem 2rem; }
}

/* ---------------- Cards ---------------- */
.app-body .card {
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius);
    background: #fff;
    box-shadow: var(--app-shadow);
    transition: box-shadow .18s ease, transform .18s ease;
}
.app-body .card:hover { box-shadow: var(--app-shadow-lg); }
.app-body .card-header {
    background: #fff;
    border-bottom: 1px solid var(--app-border);
    padding: .8rem 1.05rem;
    font-weight: 600;
    color: var(--app-text);
}
/* Plain colour blocks (legacy stat cards) become soft tinted tiles.

   Bootstrap's .text-bg-* utilities set BOTH `color` and `background-color`
   with `!important`, so a plain override here silently loses: the card kept
   the saturated Bootstrap background (blue/green/cyan/near-black) while the
   <h4>/<small> inside it took their colours from the global heading and muted
   rules, which beat inheritance. That produced dark text on a dark fill - the
   colour mismatch on Performance Analytics and the other legacy stat-card
   pages. The `!important` flags are therefore required, not defensive. */
.app-body .card[class*="text-bg-"] {
    --tile-bg: #f1f5f9;
    --tile-fg: #0f172a;
    --tile-muted: #475569;
    border: 1px solid var(--app-border);
    box-shadow: var(--app-shadow);
    background-image: none !important;
    background-color: var(--tile-bg) !important;
    color: var(--tile-fg) !important;
}
.app-body .card.text-bg-primary   { --tile-bg: #fbeff1; --tile-fg: #722f38; --tile-muted: #8b676c; }
.app-body .card.text-bg-success   { --tile-bg: #ecfdf5; --tile-fg: #047857; --tile-muted: #3f6b5c; }
.app-body .card.text-bg-info      { --tile-bg: #ecfeff; --tile-fg: #0e7490; --tile-muted: #3f6670; }
.app-body .card.text-bg-warning   { --tile-bg: #fffbeb; --tile-fg: #b45309; --tile-muted: #6b5a3a; }
.app-body .card.text-bg-danger    { --tile-bg: #fff1f2; --tile-fg: #be123c; --tile-muted: #7a4351; }
.app-body .card.text-bg-dark      { --tile-bg: #f1f5f9; --tile-fg: #0f172a; --tile-muted: #475569; }
.app-body .card.text-bg-light     { --tile-bg: #f8fafc; --tile-fg: #0f172a; --tile-muted: #475569; }
.app-body .card.text-bg-secondary { --tile-bg: #f0ebec; --tile-fg: #334155; --tile-muted: #4b5a6e; }

/* The value and its label must follow the tile, not the global text scale. */
.app-body .card[class*="text-bg-"] :is(h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6) {
    color: var(--tile-fg) !important;
}
.app-body .card[class*="text-bg-"] :is(small, .small, .text-muted) {
    color: var(--tile-muted) !important;
}

.app-body table thead th {
    background: #f8fafc;
    color: var(--app-muted);
    font-size: .74rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    border-bottom: 1px solid var(--app-border);
    white-space: nowrap;
}
.app-body table tbody td { font-size: .875rem; }

/* ---------------- Dashboard: greeting ---------------- */
.dash-greet { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .75rem; }
.dash-greet h1 { font-size: 1.4rem; font-weight: 700; margin: 0; letter-spacing: -.2px; }
.dash-greet p  { margin: .15rem 0 0; color: var(--app-muted); font-size: .9rem; }
/* .dash-tip (the lightbulb nudge banner) was removed from the dashboard. */

/* ---------------- Dashboard: stat cards ---------------- */
.stat-card {
    display: block;
    height: 100%;
    padding: 1rem 1.05rem;
    background: #fff;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius);
    box-shadow: var(--app-shadow);
    text-decoration: none;
    color: inherit;
    transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}
a.stat-card:hover {
    color: inherit;
    transform: translateY(-2px);
    border-color: #e7dada;
    box-shadow: var(--app-shadow-lg);
}
.stat-card__top {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: .7rem;
    /* A flex row will not shrink below its content unless it is allowed to.
       On the narrowest phones this row used to push past the tile and widen
       the whole page; the label rule below is what actually gives way. */
    min-width: 0;
}
.stat-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    flex: 0 0 38px;
    border-radius: 11px;
    font-size: 1.05rem;
    color: #fff;
}
.stat-card__title {
    font-size: .82rem;
    font-weight: 600;
    color: var(--app-muted);
    margin: 0;
    /* Let the label be the part that gives way. With min-width:0 it may wrap
       instead of holding the row open, and overflow-wrap breaks a long word
       ("Outstanding") rather than letting it spill past the card and widen the
       page. Measured 0 horizontal overflow from 280px to 414px. */
    min-width: 0;
    overflow-wrap: anywhere;
}
.stat-card__go { margin-left: auto; color: #cbd5e1; font-size: .8rem; }
a.stat-card:hover .stat-card__go { color: var(--app-primary); }

/* ---------------- Dashboard: panels, charts, tables ---------------- */
.dash-card .card-body { padding: 1.05rem; }
.dash-card__head {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .85rem 1.05rem;
    border-bottom: 1px solid var(--app-border);
    background: #fff;
    border-radius: var(--app-radius) var(--app-radius) 0 0;
}
.dash-card__head h2 {
    font-size: .95rem;
    font-weight: 700;
    margin: 0;
    letter-spacing: -.1px;
}
.dash-card__head .bi { color: var(--app-primary); font-size: 1.05rem; }
.dash-card__head .dash-link { margin-left: auto; }
.dash-link {
    font-size: .8rem;
    font-weight: 600;
    color: var(--app-primary);
    text-decoration: none;
    white-space: nowrap;
}
.dash-link:hover { color: #5e262e; text-decoration: underline; }

.chart-box { position: relative; width: 100%; }
.chart-box--donut { height: 190px; }
.chart-box--bars  { height: 230px; }
.donut-center {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    text-align: center;
}
.donut-center strong { font-size: 1.5rem; font-weight: 700; line-height: 1.1; }
.donut-center small  { font-size: .72rem; color: var(--app-muted); }

/* Horizontal progress used for the collection split. */
.split-bar {
    display: flex;
    height: 9px;
    border-radius: 999px;
    overflow: hidden;
    background: #ece5e5;
}
.split-bar span { display: block; height: 100%; }
.split-bar .collected    { background: var(--app-success); }
.split-bar .outstanding { background: #cbd5e1; }

.legend { display: flex; flex-wrap: wrap; gap: 1.1rem; margin-top: .85rem; }
.legend div { display: flex; align-items: center; gap: .4rem; font-size: .8rem; }
.legend .dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 9px; }
.legend small { color: var(--app-muted); }

.mini-stat {
    display: flex;
    align-items: center;
    gap: .5rem;
    padding: .65rem .8rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    background: #fbfcfe;
    height: 100%;
}
.mini-stat .bi { font-size: 1rem; }
.mini-stat strong { display: block; font-size: 1.05rem; line-height: 1.2; }
.mini-stat span   { font-size: .74rem; color: var(--app-muted); }

.alert-strip {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    padding: .7rem .8rem;
    border-radius: var(--app-radius-sm);
    background: #fff1f2;
    border: 1px solid #fecdd3;
    color: #9f1239;
    font-size: .82rem;
    height: 100%;
}

/* Quick actions */
.quick-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .6rem; }
.quick-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    padding: .9rem .5rem;
    border: 1px solid var(--app-border);
    border-radius: var(--app-radius-sm);
    background: #fbfcfe;
    color: var(--app-text);
    text-align: center;
    text-decoration: none;
    font-size: .78rem;
    font-weight: 600;
    height: 100%;
    transition: background-color .16s ease, border-color .16s ease, transform .16s ease;
}
.quick-btn .bi { font-size: 1.25rem; color: var(--app-primary); }
.quick-btn:hover {
    background: #fdf6f0;
    border-color: #f3cdaa;
    color: var(--app-text);
    transform: translateY(-2px);
    text-decoration: none;
}
.quick-btn--green .bi  { color: var(--app-success); }
.quick-btn--amber .bi  { color: var(--app-warning); }
.quick-btn--purple .bi { color: var(--app-purple); }
.quick-btn--cyan .bi   { color: var(--app-info); }
.quick-btn--rose .bi   { color: var(--app-danger); }

/* Recent activity feed */
.activity-item {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .7rem .2rem;
    border-bottom: 1px dashed var(--app-border);
    text-decoration: none;
    color: inherit;
}
.activity-item:last-child { border-bottom: 0; }
.activity-item:hover { color: inherit; }
.activity-item__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
    border-radius: 50%;
    background: #fbeff1;
    color: var(--app-primary);
    font-size: .9rem;
}
.activity-item__text { min-width: 0; }
.activity-item__text strong { display: block; font-size: .84rem; font-weight: 600; }
.activity-item__text small { display: block; font-size: .76rem; color: var(--app-muted); }
.activity-item__time { margin-left: auto; font-size: .72rem; color: #94a3b8; white-space: nowrap; }

/* Backdrop for the mobile drawer */
.app-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, .5);
    z-index: 1040;
    border: 0;
}

/* One-time-code field (auth/verify-otp): spread the digits for legibility.
   Lives here rather than inline so the narrow-screen rule below can tighten it. */
.otp-code-input { letter-spacing: .5rem; }

/* ---------------- Responsive ---------------- */
/* Tablet & below: sidebar becomes a slide-out drawer. */
@media (max-width: 991.98px) {
    .app-shell { grid-template-columns: minmax(0, 1fr); grid-template-areas: "topbar" "main"; }
    #sidebar.app-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        width: var(--app-sidebar-w);
        /* Never let the drawer cover the whole screen on a small phone: leave a
           strip of the dimmed backdrop visible (and tappable) so the drawer still
           reads as an overlay that can be dismissed. */
        max-width: 85vw;
        height: 100vh;
        transform: translateX(-100%);
        transition: transform .25s ease;
        box-shadow: 0 0 40px rgba(15, 23, 42, .35);
    }
    body.sidebar-open #sidebar.app-sidebar { transform: translateX(0); }
    body.sidebar-collapsed #sidebar.app-sidebar { width: var(--app-sidebar-w); }
    body.sidebar-collapsed #sidebar .nav-link { justify-content: flex-start; font-size: .875rem; gap: .55rem; }
    body.sidebar-collapsed #sidebar .nav-link i { font-size: .95rem; width: 1.15rem; }
    body.sidebar-collapsed #sidebar .nav-link .bi-chevron-down { display: block; }
}
@media (max-width: 767.98px) {
    .app-brand__text small { display: none; }
    .quick-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .dash-greet h1 { font-size: 1.2rem; }
    .chart-box--bars { height: 210px; }

    /* Wide data tables stay inside their Bootstrap .table-responsive wrapper,
       which scrolls horizontally. Tighten the type and cell padding so more of
       each row is visible before the user has to swipe, and give iOS momentum
       scrolling so the swipe feels native. */
    .table-responsive { -webkit-overflow-scrolling: touch; max-width: 100%; }
    .table { font-size: .78rem; }
    .table > thead th { padding: .5rem .55rem; }
    .table > tbody > tr > td,
    .table > tbody > tr > th { padding: .45rem .55rem; }

    /* The six-digit code is spaced out for legibility; on a narrow screen the
       wide tracking eats the field, so pull it in a little. */
    .otp-code-input { letter-spacing: .3rem; }
}
@media (max-width: 400px) {
    .app-user__text { display: none !important; }
}

/* The portal filter bar is sticky and used to match <body class="bg-light">,
   which the new shell replaced. Keep it aligned with the new page background. */
.portal-filter-bar { background-color: var(--app-bg, #f7f4f3); }

.alert-strip .bi { font-size: 1rem; flex: 0 0 auto; }
.alert-strip a { color: #9f1239; font-weight: 700; }

.empty-note {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: 2.2rem 1rem;
    text-align: center;
    color: var(--app-muted);
    font-size: .85rem;
}
.empty-note .bi { font-size: 1.6rem; color: #cbd5e1; }

.avatar-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex: 0 0 30px;
    border-radius: 50%;
    background: var(--app-primary);
    color: #fff;
    font-size: .7rem;
    font-weight: 700;
}
.avatar-chip--purple { background: var(--app-purple); }
.avatar-chip--green  { background: var(--app-success); }
.avatar-chip--info   { background: var(--app-info); }
.avatar-chip--amber  { background: var(--app-warning); }
.avatar-chip--rose   { background: var(--app-danger); }

.row-avatar { display: flex; align-items: center; gap: .55rem; min-width: 0; }
.row-avatar span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.badge-soft {
    display: inline-block;
    padding: .2rem .55rem;
    border-radius: 999px;
    font-size: .72rem;
    font-weight: 600;
}
.badge-soft--success { background: #ecfdf5; color: #047857; }
.badge-soft--warning { background: #fffbeb; color: #b45309; }
.badge-soft--danger  { background: #fff1f2; color: #be123c; }
.badge-soft--info    { background: #ecfeff; color: #0e7490; }
.badge-soft--muted   { background: #f1f5f9; color: #475569; }

.stat-card__value {
    font-size: 1.55rem;
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -.4px;
    margin: 0 0 .2rem;
    word-break: break-word;
}
.stat-card__meta { font-size: .76rem; color: var(--app-muted); margin: 0; }
.stat-card__meta .up   { color: var(--app-success); font-weight: 600; }
.stat-card__meta .down { color: var(--app-danger);  font-weight: 600; }
.stat-card .progress { height: 5px; margin-top: .5rem; background: #efe9e9; }

body.sidebar-collapsed #sidebar .nav-pills .sub-link { padding-left: .7rem !important; }

.app-user {
    display: flex;
    align-items: center;
    gap: .55rem;
    padding: .3rem .5rem .3rem .3rem;
    border: 0;
    border-radius: 999px;
    background: rgba(255, 255, 255, .10);
    color: #fff;
    cursor: pointer;
    transition: background-color .18s ease;
}
.app-user:hover { background: rgba(255, 255, 255, .20); }
.app-user__avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex: 0 0 32px;
    border-radius: 50%;
    background: var(--app-accent);
    color: var(--app-accent-ink);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .3px;
}
.app-user__text { flex-direction: column; line-height: 1.15; text-align: left; min-width: 0; }
.app-user__text strong {
    font-size: .82rem;
    font-weight: 600;
    max-width: 160px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.app-user__text small {
    font-size: .68rem;
    color: rgba(255, 255, 255, .7);
    max-width: 160px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.app-user__caret { font-size: .7rem; opacity: .7; }
.app-topbar .dropdown-menu { min-width: 230px; border: 0; border-radius: var(--app-radius-sm); }

/* List-group items (e.g. announcements) */
.list-group-item {
    transition: background-color .15s ease, transform .15s ease;
}
.list-group-item:hover {
    background-color: rgba(114,47,56,.055);
    transform: translateX(3px);
}

/* =====================================================================
   GLOBAL TYPE + FORM SYSTEM
   Applies to every screen, not just the dashboard, so forms, lists and
   detail pages match the shell. Declared last so it wins on order over
   both Bootstrap and the original theme rules above.
   ===================================================================== */

/* ---------- Base typography ---------- */
body,
button,
input,
select,
textarea,
.form-control,
.form-select,
.form-check-input,
.btn,
.dropdown-menu,
.modal-content,
.table,
.nav-link,
.badge,
.alert,
.card,
.list-group-item {
    font-family: var(--app-font);
}

body {
    font-size: var(--app-fs-base);
    font-weight: var(--app-fw);
    line-height: 1.55;
    color: var(--app-text, #1e293b);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-variant-ligatures: none;
}

/* One consistent heading scale across the whole app. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-weight: var(--app-fw-bold);
    color: var(--app-text, #1e293b);
    letter-spacing: -.2px;
    line-height: 1.3;
    margin-top: 0;
}
h1, .h1 { font-size: 1.5rem;    letter-spacing: -.4px; }
h2, .h2 { font-size: 1.1875rem; letter-spacing: -.3px; }
h3, .h3 { font-size: 1.0625rem; }
h4, .h4 { font-size: .9375rem; }
h5, .h5 { font-size: .875rem;  }
h6, .h6 { font-size: .8125rem; color: var(--app-muted, #64748b); }

/* Secondary/meta copy shares the dashboard's muted grey.
   No !important here on purpose: an explicit .text-success/.text-danger on
   the same element is specificity (0,1,0) and must still win. */
.text-muted,
.form-text,
.form-hint,
small,
.small { color: var(--app-muted, #64748b); }

a { color: var(--app-primary, #722f38); text-decoration: none; }
a:hover { color: #5e262e; text-decoration: underline; }

code, kbd, pre, samp { font-family: var(--app-font-mono); }
hr { border-color: var(--app-border, #ece5e5); opacity: 1; }

/* ---------- Form controls ---------- */
.form-label {
    font-size: var(--app-fs-xs);
    font-weight: var(--app-fw-semi);
    color: var(--app-text, #1e293b);
    margin-bottom: .3rem;
    letter-spacing: .01em;
}
/* Unlabelled/required asterisk text that sits outside a .form-label. */
label { font-weight: var(--app-fw-mid); }

.form-control,
.form-select,
.input-group-text,
textarea.form-control {
    font-size: var(--app-fs-sm);
    font-weight: var(--app-fw);
    line-height: 1.45;
    color: var(--app-text, #1e293b);
    /* background-COLOR only: a `background` shorthand would wipe out the
       select arrow / file button that Bootstrap draws with background-image. */
    background-color: #fff;
    border: 1px solid var(--app-border, #ece5e5);
    border-radius: var(--app-radius-sm, 10px);
    box-shadow: none;
    min-height: var(--app-control-h, 38px);
    padding: .45rem .7rem;
    transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}

.form-control::placeholder,
.form-control::-webkit-input-placeholder,
textarea::placeholder { color: #94a3b8; opacity: 1; }

.form-control:hover:not(:disabled):not([readonly]),
.form-select:hover:not(:disabled) { border-color: #e4d9d9; }

.form-control:focus,
.form-select:focus {
    background-color: #fff;
    color: var(--app-text, #1e293b);
    border-color: var(--app-primary, #722f38);
    box-shadow: var(--app-focus-ring, 0 0 0 3px rgba(255, 126, 0, .32));
    outline: 0;
}

.form-control:disabled,
.form-select:disabled,
.form-control[readonly] {
    background-color: #f8fafc;
    color: var(--app-muted, #64748b);
    border-color: var(--app-border, #ece5e5);
    cursor: not-allowed;
}

.form-control.is-invalid,
.form-select.is-invalid { border-color: var(--app-danger, #e11d48); }
.invalid-feedback,
.form-control.is-invalid ~ .invalid-feedback,
.was-validated :invalid ~ .invalid-feedback {
    font-size: var(--app-fs-xs);
    font-weight: var(--app-fw-mid);
}

/* Bare inputs/selects that predate .form-control still get the same look. */
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="file"]):not([type="hidden"]):not([type="range"]):not([type="color"]),
select:not([multiple]):not([size]) {
    font-family: var(--app-font);
    font-size: var(--app-fs-sm);
    color: var(--app-text, #1e293b);
    background-color: #fff;
    border: 1px solid var(--app-border, #ece5e5);
    border-radius: var(--app-radius-sm, 10px);
    padding: .45rem .7rem;
    min-height: var(--app-control-h, 38px);
}
input:not([type="checkbox"]):not([type="radio"]):focus,
select:not([multiple]):not([size]):focus {
    border-color: var(--app-primary, #722f38);
    box-shadow: var(--app-focus-ring, 0 0 0 3px rgba(255, 126, 0, .32));
    outline: 0;
}

.input-group-text {
    background-color: #f8fafc;
    color: var(--app-muted, #64748b);
    font-weight: var(--app-fw-mid);
}
/* Keep the control's radius from poking outside the group on the first/last child. */
.input-group > :not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.input-group > :not(:last-child)  { border-top-right-radius: 0; border-bottom-right-radius: 0; }

/* Checkboxes / radios */
.form-check-input {
    border: 1.5px solid #cbd5e1;
    background-color: #fff;
    box-shadow: none;
    transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.form-check-input:checked {
    background-color: var(--app-primary, #722f38);
    border-color: var(--app-primary, #722f38);
}
.form-check-input:focus {
    border-color: var(--app-primary, #722f38);
    box-shadow: var(--app-focus-ring, 0 0 0 3px rgba(255, 126, 0, .32));
    outline: 0;
}
.form-check-label { font-size: var(--app-fs-sm); }

.form-select[multiple] { min-height: auto; padding: .35rem; }
.form-select[multiple] option { padding: .3rem .5rem; border-radius: 4px; }

.form-text,
.form-hint { font-size: var(--app-fs-xs); }

fieldset { min-width: 0; }
legend { font-size: .9375rem; font-weight: var(--app-fw-bold); }

/* ---------- Buttons ---------- */
.btn {
    font-size: var(--app-fs-sm);
    font-weight: var(--app-fw-semi);
    line-height: 1.4;
    border-radius: var(--app-radius-sm, 10px);
    padding: .45rem .85rem;
    min-height: var(--app-control-h, 38px);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    box-shadow: none;
    transition: background-color .15s ease, border-color .15s ease,
                color .15s ease, box-shadow .15s ease, transform .12s ease;
}
.btn:hover { transform: translateY(-1px); text-decoration: none; }
.btn:active { transform: translateY(0); }
.btn:focus-visible {
    box-shadow: var(--app-focus-ring, 0 0 0 3px rgba(255, 126, 0, .32));
    outline: 0;
}
.btn-sm { font-size: var(--app-fs-xs); padding: .28rem .6rem; min-height: 30px; border-radius: 8px; }
.btn-lg { font-size: 1rem; padding: .6rem 1.1rem; min-height: 44px; }

.btn-primary {
    background-color: var(--app-primary, #722f38);
    border-color: var(--app-primary, #722f38);
    color: #fff;
    /* Bootstrap's .btn renders from --bs-btn-* variables; declare them here
       so hover / active / disabled follow the brand as well. */
    --bs-btn-bg: #722f38;
    --bs-btn-border-color: #722f38;
    --bs-btn-hover-bg: #5e262e;
    --bs-btn-hover-border-color: #5e262e;
    --bs-btn-active-bg: #52212a;
    --bs-btn-active-border-color: #52212a;
    --bs-btn-disabled-bg: #722f38;
    --bs-btn-disabled-border-color: #722f38;
    --bs-btn-focus-shadow-rgb: 255, 126, 0;
}
.btn-primary:hover, .btn-primary:focus { background-color: #5e262e; border-color: #5e262e; color: #fff; }
.btn-success { background-color: var(--app-success, #16a34a); border-color: var(--app-success, #16a34a); color: #fff; }
.btn-danger  { background-color: var(--app-danger, #e11d48);  border-color: var(--app-danger, #e11d48);  color: #fff; }
.btn-warning { background-color: var(--app-warning, #f59e0b); border-color: var(--app-warning, #f59e0b); color: #1e293b; }
.btn-info    { background-color: var(--app-info, #0891b2);    border-color: var(--app-info, #0891b2);    color: #fff; }
.btn-light   { background-color: #fff; border-color: var(--app-border, #ece5e5); color: var(--app-text, #1e293b); }
.btn-light:hover { background-color: #f8fafc; }
.btn-outline-secondary { border-color: #cbd5e1; color: var(--app-text, #1e293b); }
.btn-outline-secondary:hover { background-color: #f1f5f9; color: var(--app-text, #1e293b); }
.btn-link { text-decoration: none; font-weight: var(--app-fw-semi); }
.btn:disabled, .btn.disabled { opacity: .6; transform: none; cursor: not-allowed; }

/* ---------- Brand utilities ----------
   Bootstrap derives .bg-primary / .text-primary / .text-bg-primary from
   --bs-primary-rgb (redefined in :root above) and paints buttons from
   --bs-btn-* variables. This block completes the set for every "primary"
   surface the views actually use - outline buttons (the list screens),
   nav pills, dropdown states and the sign-in screen. app.css loads after
   bootstrap.min.css, so these equal-specificity rules win on order; the
   .card.text-bg-primary soft tile further outranks .text-bg-primary on
   specificity, so stat tiles keep their tinted treatment. */
.btn-outline-primary {
    --bs-btn-color: #722f38;
    --bs-btn-border-color: #722f38;
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #722f38;
    --bs-btn-hover-border-color: #722f38;
    --bs-btn-focus-color: #fff;
    --bs-btn-focus-bg: #722f38;
    --bs-btn-focus-border-color: #722f38;
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: #5e262e;
    --bs-btn-active-border-color: #5e262e;
    --bs-btn-disabled-color: #722f38;
    --bs-btn-disabled-border-color: #722f38;
    --bs-btn-focus-shadow-rgb: 255, 126, 0;
}
/* Every button gets the orange focus glow, whichever variant it is. */
.btn:focus { box-shadow: var(--app-focus-ring); }
.btn-check:focus-visible + .btn,
.btn-check:active + .btn { box-shadow: var(--app-focus-ring); }
.link-primary { color: var(--app-primary); }
.link-primary:hover { color: #5e262e; }
.border-primary { border-color: var(--app-primary) !important; }
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
    background-color: var(--app-primary);
    color: #fff;
}
.dropdown-item.active,
.dropdown-item:active { background-color: var(--app-primary); color: #fff; }

/* ---------- Cards ---------- */
.card {
    border: 1px solid var(--app-border, #ece5e5);
    border-radius: var(--app-radius, 14px);
    box-shadow: var(--app-shadow, 0 1px 2px rgba(15, 23, 42, .04));
    background-color: #fff;
}
.card-header {
    background-color: #fff;
    border-bottom: 1px solid var(--app-border, #ece5e5);
    font-weight: var(--app-fw-semi);
    font-size: var(--app-fs-sm);
    padding: .75rem 1rem;
}
.card-footer {
    background-color: #fbfcfe;
    border-top: 1px solid var(--app-border, #ece5e5);
    padding: .7rem 1rem;
}

/* ---------- Tables ---------- */
.table {
    font-size: var(--app-fs-sm);
    color: var(--app-text, #1e293b);
    --bs-table-border-color: var(--app-border, #ece5e5);
    margin-bottom: 0;
}
.table > thead th {
    font-size: var(--app-fs-xs);
    font-weight: var(--app-fw-bold);
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--app-muted, #64748b);
    background-color: #f8fafc;
    border-bottom: 1px solid var(--app-border, #ece5e5);
    padding: .6rem .75rem;
    white-space: nowrap;
}
.table > tbody > tr > td,
.table > tbody > tr > th {
    padding: .6rem .75rem;
    border-color: var(--app-border, #ece5e5);
    vertical-align: middle;
}
.table-hover > tbody > tr:hover > * { background-color: #faf6f5; color: var(--app-text, #1e293b); }
.table thead th a { color: inherit; text-decoration: none; }
.table-active > *, td.table-active { background-color: #f7efef; }

/* ---------- Overlays ---------- */
.dropdown-menu {
    font-size: var(--app-fs-sm);
    border: 1px solid var(--app-border, #ece5e5);
    border-radius: var(--app-radius-sm, 10px);
    box-shadow: var(--app-shadow-lg, 0 8px 28px rgba(15, 23, 42, .10));
    padding: .35rem;
}
.dropdown-item {
    font-size: var(--app-fs-sm);
    font-weight: var(--app-fw-mid);
    border-radius: 7px;
    padding: .45rem .6rem;
    color: var(--app-text, #1e293b);
}
.dropdown-item:hover, .dropdown-item:focus { background-color: #fbf5f3; color: var(--app-text, #1e293b); }
.dropdown-item:active { background-color: var(--app-primary, #722f38); color: #fff; }
.dropdown-header { font-size: var(--app-fs-xs); font-weight: var(--app-fw-bold); text-transform: uppercase; letter-spacing: .04em; }
.dropdown-divider { border-color: var(--app-border, #ece5e5); margin: .3rem 0; }

.modal-content {
    border: 0;
    border-radius: var(--app-radius, 14px);
    box-shadow: var(--app-shadow-lg, 0 8px 28px rgba(15, 23, 42, .10));
    font-size: var(--app-fs-sm);
}
.modal-header, .modal-footer { border-color: var(--app-border, #ece5e5); padding: .9rem 1.1rem; }
.modal-title { font-size: 1.0625rem; font-weight: var(--app-fw-bold); }
.modal-body { padding: 1.1rem; }

/* ---------- Badges, alerts, tabs, pagination ---------- */
.badge {
    font-size: var(--app-fs-xs);
    font-weight: var(--app-fw-semi);
    border-radius: 999px;
    padding: .28em .6em;
    letter-spacing: .01em;
}
.alert {
    font-size: var(--app-fs-sm);
    border-radius: var(--app-radius-sm, 10px);
    border-width: 1px;
    padding: .75rem 1rem;
}
.alert-heading { font-weight: var(--app-fw-bold); }
.list-group-item {
    background-color: #fff;
    border-color: var(--app-border, #ece5e5);
    font-size: var(--app-fs-sm);
    padding: .7rem 1rem;
}
.list-group-item.active { background-color: var(--app-primary, #722f38); border-color: var(--app-primary, #722f38); color: #fff; }

.nav-tabs { border-bottom-color: var(--app-border, #ece5e5); gap: .15rem; }
.nav-tabs .nav-link {
    font-size: var(--app-fs-sm);
    font-weight: var(--app-fw-semi);
    color: var(--app-muted, #64748b);
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    padding: .5rem .8rem;
}
.nav-tabs .nav-link:hover { color: var(--app-text, #1e293b); border-bottom-color: #cbd5e1; }
.nav-tabs .nav-link.active {
    color: var(--app-primary, #722f38);
    background-color: transparent;
    border-bottom-color: var(--app-primary, #722f38);
}

.page-link {
    font-size: var(--app-fs-sm);
    color: var(--app-primary, #722f38);
    border-color: var(--app-border, #ece5e5);
    border-radius: 8px !important;
    margin: 0 .15rem;
}
.page-item.active .page-link { background-color: var(--app-primary, #722f38); border-color: var(--app-primary, #722f38); }
.page-link:focus { box-shadow: var(--app-focus-ring, 0 0 0 3px rgba(255, 126, 0, .32)); }

.progress { background-color: #efe9e9; border-radius: 999px; }
.progress-bar { font-size: var(--app-fs-xs); font-weight: var(--app-fw-semi); }
.breadcrumb { font-size: var(--app-fs-sm); --bs-breadcrumb-divider-color: var(--app-muted, #64748b); }
.breadcrumb-item + .breadcrumb-item::before { color: var(--app-muted, #64748b); }
.tooltip .tooltip-inner, .popover { font-size: var(--app-fs-xs); }
.popover { border-color: var(--app-border, #ece5e5); box-shadow: var(--app-shadow-lg, 0 8px 28px rgba(15, 23, 42, .10)); }
.popover-header { font-weight: var(--app-fw-semi); background-color: #fbfcfe; }
.toast { font-size: var(--app-fs-sm); border-color: var(--app-border, #ece5e5); }

/* Keep the sidebar and topbar on the same stack as the page. */
#sidebar, .app-topbar, .app-user, .app-brand { font-family: var(--app-font); }
/* The dashboard's own sizes are already tuned - only the stack is shared. */
.stat-card__value, .dash-card__head h2, .dash-greet h1 { font-family: var(--app-font); }

/* ---------- SweetAlert2 dialogs ----------
   app.js loads sweetalert2.all.min.js, which INJECTS its own stylesheet into
   a <style> tag at runtime. That tag is appended to <head> AFTER app.css, so
   for equal specificity the injected rules win on order and the dialogs kept
   SweetAlert2's own font. !important is required here to win regardless. */
.swal2-container,
.swal2-popup,
.swal2-title,
.swal2-html-container,
.swal2-footer,
.swal2-input,
.swal2-textarea,
.swal2-select,
.swal2-label,
.swal2-validation-message,
.swal2-confirm,
.swal2-deny,
.swal2-cancel,
.swal2-close {
    font-family: var(--app-font) !important;
}
.swal2-title {
    font-size: 1.1875rem !important;
    font-weight: 700 !important;
    color: var(--app-text) !important;
    letter-spacing: -.3px;
}
.swal2-html-container {
    font-size: var(--app-fs-base) !important;
    color: var(--app-text) !important;
}
.swal2-footer { font-size: var(--app-fs-xs) !important; }
.swal2-label {
    font-size: var(--app-fs-sm) !important;
    font-weight: 600 !important;
}
.swal2-validation-message {
    font-size: var(--app-fs-xs) !important;
    font-weight: 500 !important;
}
.swal2-input,
.swal2-textarea,
.swal2-select {
    font-size: var(--app-fs-sm) !important;
    min-height: var(--app-control-h) !important;
    border: 1px solid var(--app-border) !important;
    border-radius: var(--app-radius-sm) !important;
    background-color: #fff !important;
}
.swal2-input:focus,
.swal2-textarea:focus,
.swal2-select:focus {
    border-color: var(--app-primary) !important;
    box-shadow: var(--app-focus-ring) !important;
}
.swal2-confirm,
.swal2-deny,
.swal2-cancel {
    font-size: var(--app-fs-sm) !important;
    font-weight: 600 !important;
    border-radius: var(--app-radius-sm) !important;
    min-height: 36px;
}
