/* Design tokens are defined in tokens.css (loaded BEFORE this file).
   Theme presets in /css/themes/*.css override them.
   Print overrides in print.css are loaded LAST. */

*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* The universal margin:0 above overrides the UA stylesheet's
   `dialog { margin:auto }`, which is what centers a modal <dialog>.
   Without this, every showModal() dialog (confirm/reversal modals)
   pins to the top-left corner. Restore the centering. */
dialog {
    margin: auto;
}

html, body {
    height: 100%;
    overflow: hidden;
    width:100%;
}

body {
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-body);
    font-size: 14px;
    line-height: 1.5;
    display: flex;
}

/* ── SIDEBAR ──────────────────────────────────────────────────── */
.sidebar {
    width: var(--sidebar-w);
    background: var(--sidebar-bg);
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    z-index: 300;
    box-shadow: 2px 0 12px rgba(0,0,0,0.15);
}

.sidebar-logo {
    padding: 20px 20px 16px;
    border-bottom: 1px solid #2e2920;
    display: flex;
    align-items: center;
    gap: 10px;
}

.logo-icon {
    width: 36px;
    height: 36px;
    background: var(--gold);
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    flex-shrink: 0;
}

.logo-text .logo-name {
    font-family: var(--font-head);
    font-size: 23px;
    color: #ffffff;
    font-style: italic;
}

.logo-text .logo-version {
    font-size: 10px;
    color: var(--sidebar-dim);
    letter-spacing: 1px;
    text-transform: uppercase;
}

/* Tenant badge */
.tenant-badge {
    margin: 12px 14px;
    background: #c8940a;
    border: 1px solid #3a3428;
    border-radius: 8px;
    padding: 8px 12px;
}

    .tenant-badge .tenant-code {
        font-family: var(--font-mono);
        font-size: 11px;
        color: var(--gold);
        letter-spacing: 1px;
    }

    .tenant-badge .tenant-name {
        font-size: 12px;
        color: var(--sidebar-text);
        margin-top: 2px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .tenant-badge .tenant-branch {
        font-size: 11px;
        color: var(--sidebar-dim);
        margin-top: 1px;
    }

.nav {
    padding: 6px 10px;
    flex: 1;
    overflow-y: auto;
}

.nav-label {
    font-size: 9.5px;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: #ffffff;
    padding: 14px 10px 5px;
    font-weight: 600;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: 8px;
    color: var(--sidebar-text);
    font-size: 13px;
    text-decoration: none;
    transition: all 0.15s;
    margin-bottom: 1px;
}

    .nav-item:hover {
        background: #2a2520;
        color: #ede8df;
    }

    .nav-item.active {
        background: var(--gold);
        color: #18150f;
        font-weight: 600;
    }

.nav-icon {
    font-size: 15px;
    width: 20px;
    text-align: center;
    flex-shrink: 0;
}

.nav-badge {
    margin-left: auto;
    background: var(--red);
    color: white;
    font-size: 10px;
    font-weight: 700;
    padding: 1px 6px;
    border-radius: 10px;
}

.nav-item.active .nav-badge {
    background: rgba(0,0,0,0.2);
}

.sidebar-footer {
    padding: 14px 16px;
    border-top: 1px solid #2e2920;
}

.user-info {
    display: flex;
    align-items: center;
    gap: 10px;
}

.user-avatar {
    width: 32px;
    height: 32px;
    background: var(--gold-dark);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
    color: white;
    flex-shrink: 0;
}

.user-name {
    font-size: 12px;
    font-weight: 500;
    color: var(--sidebar-text);
}

.user-role {
    font-size: 11px;
    color: #ffffff;
}

.logout-btn {
    margin-top: 8px;
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--sidebar-dim);
    font-size: 12px;
    text-decoration: none;
    padding: 4px 2px;
}

    .logout-btn:hover {
        color: var(--red-bg);
    }

/* ── MAIN AREA ────────────────────────────────────────────────── */
.main {
    margin-left: var(--sidebar-w);
    flex: 1;
    min-width: 0;           /* allow flex child to shrink below content size */
    display: flex;
    flex-direction: column;
    height: 100dvh;
    overflow-x: hidden;
}

    .main.no-sidebar {
        margin-left: 0;
    }

/* ── TOP BAR ──────────────────────────────────────────────────── */
.topbar {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    height: var(--topbar-h);
    padding: 0 28px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky;
    top: 0;
    z-index: 200;
    box-shadow: var(--shadow);
}

.topbar-left {
    display: flex;
    align-items: center;
    gap: 12px;
}

.topbar-title {
    font-family: var(--font-head);
    font-size: 20px;
    font-style: italic;
}

.breadcrumb {
    font-size: 12px;
    color: var(--text-muted);
}

/* Trail rendered by Views/Shared/_Breadcrumb.cshtml. Scoped to `ol` so the older
   plain-text uses of .breadcrumb are untouched. Was plain unbadged text at the
   same 12px as everything around it — easy to miss as a navigation aid. */
.breadcrumb > ol {
    list-style: none;
    margin: 0 0 14px;
    padding: 6px 14px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    background: var(--color-primary-soft);
    border-radius: 8px;
    width: fit-content;
}
.breadcrumb > ol > li {
    display: flex;
    align-items: center;
    gap: 6px;
}
.breadcrumb > ol > li + li::before {
    content: "›";
    color: var(--text-dim, #9aa0aa);
    font-size: 13px;
    line-height: 1;
}
.breadcrumb > ol > li > a {
    color: var(--text-muted);
    text-decoration: none;
}
.breadcrumb > ol > li > a:hover { color: var(--gold-dark); text-decoration: underline; }
.breadcrumb > ol > li > a:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 2px; }
.breadcrumb > ol > li > [aria-current="page"] { color: var(--text); font-weight: 600; }

.topbar-right {
    display: flex;
    align-items: center;
    gap: 10px;
}

.date-chip {
    font-family: var(--font-mono);
    font-size: 11px;
    background: var(--gold-bg);
    border: 1px solid var(--gold-border);
    color: var(--gold);
    padding: 5px 12px;
    border-radius: 20px;
}

.btn-new {
    background: var(--gold);
    color: #18150f;
    border: none;
    border-radius: 8px;
    padding: 8px 18px;
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s;
    white-space: nowrap;
}

    .btn-new:hover {
        background: var(--gold-light);
        color: #18150f;
    }

/* ── PAGE CONTENT ─────────────────────────────────────────────── */
.page {
    flex: 1; /* 👈 Add this */
    overflow-y: auto; /* 👈 Add this so ONLY the page content scrolls */
    overflow-x: hidden; /* 🔥 ADD THIS */
    animation: fadeSlide 0.22s ease;
}

@keyframes fadeSlide {
    from {
        opacity: 0;
        transform: translateY(8px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ── STAT GRID ───────────────────────────────────────────────── */
.stat-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin-bottom: 22px;
}
.print-only {
    display: none;
}
.stat-grid-5 {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 14px;
    margin-bottom: 22px;
}

.stat-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 18px 20px;
    box-shadow: var(--shadow);
    transition: box-shadow 0.15s;
    cursor: default;
}

    .stat-card:hover {
        box-shadow: var(--shadow-md);
    }

    .stat-card.clickable {
        cursor: pointer;
    }

.stat-label {
    font-size: 11px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.9px;
    font-weight: 1000;
}

.stat-value {
    font-family: var(--font-mono);
    font-size: 27px;
    font-weight: 500;
    margin-top: 6px;
    letter-spacing: -0.5px;
}

    .stat-value.c-gold {
        color: var(--gold);
    }

    .stat-value.c-green {
        color: var(--green);
    }

    .stat-value.c-red {
        color: var(--red);
    }

    .stat-value.c-blue {
        color: var(--blue);
    }

.chip {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 9px;
    border-radius: 20px;
    margin-top: 7px;
}

.chip-gold {
    background: var(--gold-bg);
    color: var(--gold-dark);
}

.chip-green {
    background: var(--green-bg);
    color: var(--green);
}

.chip-red {
    background: var(--red-bg);
    color: var(--red);
}

.chip-blue {
    background: var(--blue-bg);
    color: var(--blue);
}

.chip-orange {
    background: var(--orange-bg);
    color: var(--orange);
}

.chip-purple {
    background: var(--purple-bg);
    color: var(--purple);
}

/* ── CARD ─────────────────────────────────────────────────────── */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin-bottom: 20px;
}

.card-header {
    padding: 14px 20px;
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.card-title {
    font-family: var(--font-head);
    font-size: 16px;
}

.card-body {
    padding: 18px 20px;
}

    .card-body.p0 {
        padding: 0;
    }

/* ── GRIDS ────────────────────────────────────────────────────── */
.dash-2col {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 18px;
    margin-bottom: 18px;
}

.dash-3col {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 18px;
    margin-bottom: 18px;
}

.col-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

.col-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 14px;
}

.col-4 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    gap: 14px;
}

/* ── TABLE ─────────────────────────────────────────────────────── */
.tbl-wrap {
    overflow-x: auto;
    overflow-y: hidden; /* horizontal scroller ONLY — overflow-x:auto silently makes overflow-y
                           compute to auto, which traps the vertical mouse wheel and stops the
                           page from scrolling when the table overflows sideways. */
}

/* ── Sticky-right Action column (app-wide) ──────────────────────────
   Pin the last column (Action/Actions) to the right edge so its buttons
   stay visible no matter how far the table scrolls horizontally. Re-uses
   the same theme tokens as the base table rules, so dark mode + themes
   follow automatically. Opt-out per table with `.no-sticky-actions`. */
.tbl-wrap > table:not(.no-sticky-actions) > thead > tr > th:last-child,
.tbl-wrap > table:not(.no-sticky-actions) > tbody > tr > td:last-child {
    position: sticky;
    right: 0;
    z-index: 1;
    box-shadow: -4px 0 8px -3px rgba(0,0,0,.08);
}
.tbl-wrap > table:not(.no-sticky-actions) > thead > tr > th:last-child {
    z-index: 3;
    background-color: var(--surface0);
}
.tbl-wrap > table:not(.no-sticky-actions) > tbody > tr > td:last-child {
    background-color: var(--surface, #fff);
}
.tbl-wrap > table:not(.no-sticky-actions) > tbody > tr:hover > td:last-child {
    background-color: var(--surface2);
}

/* Approvals table — its own wrapper class (.ap-card has overflow-x on mobile) */
.ap-card .ap-table thead th:last-child,
.ap-card .ap-table tbody td:last-child {
    position: sticky;
    right: 0;
    z-index: 1;
    box-shadow: -4px 0 8px -3px rgba(0,0,0,.08);
}
.ap-card .ap-table thead th:last-child { z-index: 3; background-color: #f3f4f6; }
.ap-card .ap-table tbody td:last-child { background-color: #fff; }
.ap-card .ap-table tbody tr:hover td:last-child { background-color: #fffbe8; }

/* ── Global table-scroll-helper (table-scroll-helper.js) ────────────
   Floating ‹ › arrow buttons + wheel-horizontal scrolling for any
   .tbl-wrap with horizontal overflow. The JS wraps each .tbl-wrap in
   a .tw-shell so the buttons can be absolute-positioned against a
   stable parent and stay put while the table scrolls inside. */
.tw-shell { position: relative; }
.tw-scroll-btn {
    position: absolute; top: 50%; transform: translateY(-50%);
    width: 42px; height: 42px; border-radius: 50%;
    background: var(--gold, #b8860b); color: #fff;
    border: 2px solid #fff; font-size: 24px; font-weight: 700; line-height: 1;
    cursor: pointer; z-index: 50; user-select: none;
    box-shadow: 0 4px 14px rgba(0,0,0,.22);
    transition: opacity .18s ease, background .15s ease, transform .12s ease;
    display: flex; align-items: center; justify-content: center;
    padding: 0;
}
.tw-scroll-btn:hover    { background: var(--gold-dark, #8a6500); transform: translateY(-50%) scale(1.08); }
.tw-scroll-btn:active   { transform: translateY(-50%) scale(.95); }
.tw-scroll-btn:disabled { opacity: .3; cursor: not-allowed; pointer-events: none; }
.tw-scroll-btn.tw-hide  { display: none; }
.tw-scroll-left         { left: -14px; }
.tw-scroll-right        { right: -14px; }
@media (max-width: 600px) { .tw-scroll-btn { width: 36px; height: 36px; font-size: 20px; } }

/* Opt-in utility — apply `.sticky-actions` to any <table> or its wrapper
   that lives outside the .tbl-wrap convention. Same behaviour as above. */
.sticky-actions thead th:last-child,
.sticky-actions tbody td:last-child,
table.sticky-actions thead th:last-child,
table.sticky-actions tbody td:last-child {
    position: sticky;
    right: 0;
    z-index: 1;
    box-shadow: -4px 0 8px -3px rgba(0,0,0,.08);
}
.sticky-actions thead th:last-child,
table.sticky-actions thead th:last-child { z-index: 3; background-color: var(--surface0); }
.sticky-actions tbody td:last-child,
table.sticky-actions tbody td:last-child { background-color: var(--surface, #fff); }
.sticky-actions tbody tr:hover td:last-child,
table.sticky-actions tbody tr:hover td:last-child { background-color: var(--surface2); }

table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
}

thead th {
    background: var(--surface0);
    color: var(--text-muted);
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    padding: 10px 14px;
    text-align: left;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

tbody tr {
    border-bottom: 1px solid var(--border);
    transition: background 0.1s;
}

    tbody tr:last-child {
        border-bottom: none;
    }

    tbody tr:hover {
        background: var(--surface2);
    }

tbody td {
    padding: 11px 14px;
    color: var(--text);
    vertical-align: middle;
}

.td-mono {
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--gold-dark);
    font-weight:900;
}

    .td-mono a {
        color: var(--gold-dark);
        text-decoration: none;
    }

        .td-mono a:hover {
            text-decoration: underline;
        }

.td-name {
    font-weight: 600;
}

.td-dim {
    color: var(--text-muted);
    font-size: 12.5px;
}

/* ── STATUS BADGES ────────────────────────────────────────────── */
.status {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11.5px;
    font-weight: 600;
    padding: 3px 9px;
    border-radius: 20px;
    white-space: nowrap;
}

    .status::before {
        content: '';
        width: 6px;
        height: 6px;
        border-radius: 50%;
    }

.s-active {
    background: var(--green-bg);
    color: var(--green);
}

    .s-active::before {
        background: var(--green);
    }

.s-overdue {
    background: var(--red-bg);
    color: var(--red);
}

    .s-overdue::before {
        background: var(--red);
    }

.s-due {
    background: var(--orange-bg);
    color: var(--orange);
}

    .s-due::before {
        background: var(--orange);
    }

/* Offer stage (Users.IsPendingJoining) — deliberately NOT .s-closed. An
   inactive/closed grey reads as "no longer with us"; this row has never had a
   login and is waiting on the candidate's answer. */
.s-pending {
    background: var(--orange-bg);
    color: var(--orange);
}

    .s-pending::before {
        background: var(--orange);
    }

.s-closed {
    background: var(--border);
    color: var(--text-muted);
}

    .s-closed::before {
        background: var(--text-muted);
    }

.s-repledged {
    background: var(--purple-bg);
    color: var(--purple);
}

    .s-repledged::before {
        background: var(--purple);
    }

/* ── FORMS ─────────────────────────────────────────────────────── */
.fg {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

    .fg.full {
        grid-column: 1 / -1;
    }

label {
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

input, select, textarea {
    border: 1px solid var(--border);
    background: var(--surface);
    border-radius: 8px;
    padding: 9px 12px;
    font-family: var(--font-body);
    font-size: 13.5px;
    color: var(--text);
    outline: none;
    transition: border 0.15s, box-shadow 0.15s;
    width: 100%;
}

    input:focus, select:focus, textarea:focus {
        border-color: var(--gold);
        box-shadow: 0 0 0 3px rgba(200,148,10,0.1);
    }

textarea {
    resize: vertical;
    min-height: 72px;
}

.section-title {
    font-family: var(--font-head);
    font-size: 17px;
    font-style: italic;
    color: var(--gold-dark);
    margin-bottom: 14px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--gold-border);
}

.text-danger {
    color: var(--red);
    font-size: 11px;
    margin-top: 2px;
}

/* ── BUTTONS ───────────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: none;
    border-radius: 8px;
    padding: 10px 20px;
    font-family: var(--font-body);
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.15s;
    text-decoration: none;
    white-space: nowrap;
}

.btn-primary {
    background: var(--gold);
    color: #18150f;
}

    .btn-primary:hover {
        background: var(--gold-light);
    }

.btn-success {
    background: var(--green);
    color: white;
}

    .btn-success:hover {
        background: #185f3a;
    }

.btn-danger {
    background: var(--red);
    color: white;
}

    .btn-danger:hover {
        background: #a02a16;
    }

.btn-ghost {
    background: var(--surface2);
    border: 1px solid var(--border);
    color: var(--text);
}

    .btn-ghost:hover {
        background: var(--border);
    }

.btn-sm {
    padding: 6px 14px;
    font-size: 12.5px;
}

.btn-row {
    display: flex;
    gap: 10px;
    margin-top: 20px;
    flex-wrap: wrap;
}

/* ── CALC BOX ──────────────────────────────────────────────────── */
.calc-box {
    background: var(--gold-bg);
    border: 1px solid var(--gold-border);
    border-radius: var(--radius);
    padding: 16px 20px;
}

.calc-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 7px 0;
    border-bottom: 1px dashed var(--gold-border);
    font-size: 13.5px;
}

    .calc-row:last-child {
        border-bottom: none;
        font-weight: 700;
        font-size: 15px;
    }

.calc-label {
    color: var(--text-muted);
}

.calc-val {
    font-family: var(--font-mono);
    color: var(--gold-dark);
}

    .calc-val.big {
        font-size: 17px;
        color: var(--text);
    }

/* ── ALERTS ────────────────────────────────────────────────────── */
.alert {
    border-radius: 8px;
    padding: 12px 16px;
    font-size: 13.5px;
    margin-bottom: 16px;
}

.alert-gold {
    background: var(--gold-bg);
    border: 1px solid var(--gold-border);
    color: var(--gold-dark);
}

.alert-green {
    background: var(--green-bg);
    border: 1px solid #b0dfcc;
    color: var(--green);
}

.alert-red {
    background: var(--red-bg);
    border: 1px solid #f0c0b8;
    color: var(--red);
}

/* ── SEARCH BAR ────────────────────────────────────────────────── */
.search-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

.search-inp {
    flex: 1;
    min-width: 200px;
    max-width: 340px;
}

.filter-sel {
    width: 160px;
}

/* ── Staff-Performance page header bar (shared: My / MyTeam / Rollup) ──
   Lives here (not in a single view's <style>) so every Staff-Performance
   page renders the same tidy control bar: title block on the left, page
   actions on the right.

   ⚠ NEVER put a `.fpanel` inside this — it is a SIBLING, below the bar.
   This is a flex row with `justify-content: space-between`, so the panel (a full-width
   block whose body is an auto-fill grid) sizes to its own content instead of the row,
   and the row then throws title / panel / actions across a mostly empty band with a
   bordered card floating inside another bordered card. Same rule the Filter Panel
   contract above states for `.filter-bar` / `.search-row`; `Rollup.cshtml` is the
   shape to copy. Index / My / MyTeam all carried the nested form until 2026-09-20.
       grep -n 'sp-toolbar' -A 25 Views/StaffPerformance/*.cshtml | grep 'card fpanel'  */
.sp-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 12px;
    padding: 12px 14px;
    margin-bottom: 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}
.sp-filter-form { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 1 1 auto; }
.sp-actions     { display: flex; flex-wrap: wrap; gap: 6px; }
.sp-field       { display: inline-flex; align-items: center; gap: 6px; }
.sp-field-lbl   { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); white-space: nowrap; }

/* Fixed control widths. The descendant selectors (0,2,0) intentionally out-rank the
   global `input[type="date"], select { width: 100% }` rule (0,1,1) so the date pickers
   and dropdowns stay compact instead of stretching to full width. */
.sp-toolbar .filter-sel { height: 34px; }
.sp-toolbar .sp-date    { width: 150px; }
.sp-toolbar .sp-sel     { width: 160px; }
.sp-toolbar .sp-sel-sm  { width: 120px; }
.sp-toolbar .btn-sm     { height: 34px; padding: 0 12px; }

@media (max-width: 1200px) {
    .sp-toolbar .sp-actions { width: 100%; justify-content: flex-start; }
}
@media (max-width: 560px) {
    .sp-toolbar .sp-filter-form { width: 100%; }
    .sp-toolbar .sp-field { flex: 1 1 auto; }
    .sp-toolbar .sp-date,
    .sp-toolbar .sp-sel,
    .sp-toolbar .sp-sel-sm { flex: 1 1 140px; width: auto; }
}

/* ── PRINT ──────────────────────────────────────────────────────── */
.receipt-box {
    background: white;
    border: 1.5px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 30px 36px;
    max-width: 620px;
    font-size: 13px;
    line-height: 1.9;
}

.receipt-stamp {
    margin-top: 24px;
    padding-top: 14px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    font-size: 12px;
    color: var(--text-muted);
}

@media print {
    .sidebar, .topbar, .mob-header, .sidebar-overlay, .no-print {
        display: none !important;
    }

    .main {
        margin-left: 0 !important;
    }
}

/* ── SCROLLBAR ──────────────────────────────────────────────────── */
::-webkit-scrollbar {
    width: 5px;
    height: 5px;
}

::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 3px;
}

/* ── RESPONSIVE ─────────────────────────────────────────────────── */
@media (max-width: 1200px) {
    .stat-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .col-4 {
        grid-template-columns: 1fr 1fr;
    }
}

@media (max-width: 900px) {
    .dash-2col, .dash-3col {
        grid-template-columns: 1fr;
    }

    .col-3 {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 700px) {
    .main {
        margin-left: 0;
    }

    .page {
        padding: 16px;
    }
}

/* ── TOAST ANIMATIONS ─────────────────────────────────────────── */
@keyframes toastIn {
    from {
        opacity: 0;
        transform: translateX(40px);
    }

    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes toastOut {
    from {
        opacity: 1;
        transform: translateX(0);
    }

    to {
        opacity: 0;
        transform: translateX(40px);
    }
}

/* ── PAGINATION ───────────────────────────────────────────────── */
.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 16px;
    border-top: 1px solid var(--border);
    font-size: 13px;
    flex-wrap: wrap;
    gap: 8px;
}

.pagination-info {
    color: var(--text-muted);
}

.pagination-pages {
    display: flex;
    gap: 4px;
}

/* ── PHOTO UPLOAD ZONE ────────────────────────────────────────── */
.photo-zone {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.photo-thumb {
    width: 80px;
    height: 80px;
    object-fit: cover;
    border-radius: 8px;
    border: 2px solid var(--border);
    display: block;
}

.photo-thumb-sm {
    width: 52px;
    height: 52px;
    object-fit: cover;
    border-radius: 6px;
    border: 1px solid var(--border);
}

/* ── LOAN STATUS COLORS ───────────────────────────────────────── */
.s-repledged {
    background: var(--purple-bg);
    color: var(--purple);
}

    .s-repledged::before {
        background: var(--purple);
    }

/* ── EMI TABLE ────────────────────────────────────────────────── */
.emi-paid {
    background: var(--green-bg) !important;
}

.emi-overdue {
    background: var(--red-bg) !important;
}

.emi-pending {
}

/* ── SEARCH HIGHLIGHT ─────────────────────────────────────────── */
.loan-search-result {
    cursor: pointer;
    transition: background 0.1s;
}

    .loan-search-result:hover {
        background: var(--gold-bg) !important;
    }

/* ── MEMBER PHOTO HEADER ──────────────────────────────────────── */
.member-avatar-lg {
    width: 80px;
    height: 80px;
    object-fit: cover;
    border-radius: 50%;
    border: 3px solid var(--gold);
    flex-shrink: 0;
}

.member-avatar-placeholder {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    border: 3px solid var(--border);
    background: var(--surface2);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    color: var(--text-dim);
    flex-shrink: 0;
}

/* ── CHART CONTAINER ──────────────────────────────────────────── */
.chart-wrap {
    position: relative;
    height: 220px;
}

/* ── COMPACT PRINT LAYOUT ─────────────────────────────────────── */
@media print {
    * {
        box-sizing: border-box;
    }

    /* Reset overflow so the browser can render the full page — without
       this, html/body overflow:hidden clips all content on print/PDF */
    html, body {
        overflow: visible !important;
        height: auto !important;
        width: auto !important;
        margin: 0;
        padding: 0;
        font-size: 11px;
        font-family: Arial, sans-serif;
    }

    .main, .page {
        overflow: visible !important;
        height: auto !important;
    }

    /* A horizontal table scroller must print its WHOLE table, not the slice
       that happens to be scrolled into view. Same reason .main / .page are
       reset above: any overflow:auto ancestor clips at print time.

       !important is load-bearing. There is already a `.tbl-wrap { overflow:
       visible }` in the second @media print block below (~line 1350), but it
       is DEAD: the plain `.tbl-wrap { overflow-x: auto }` at ~line 1655 has
       the same specificity and comes LATER in the file, so it wins in print
       too. Do not delete this rule as a duplicate of that one. */
    .tbl-wrap {
        overflow: visible !important;
    }

    .sidebar, .topbar, .mob-header, .sidebar-overlay, .no-print, .btn, .btn-row, .alert, .tw-scroll-btn {
        display: none !important;
    }

    .main {
        margin-left: 0 !important;
        padding: 0;
    }

    .page {
        padding: 8px 10px !important;
        animation: none !important;
    }

    .card {
        border: 1px solid #ccc;
        border-radius: 4px;
        margin-bottom: 6px;
        box-shadow: none;
        break-inside: avoid;
    }

    .card-header {
        padding: 5px 10px;
        background: #f5f5f5;
        border-bottom: 1px solid #ccc;
    }

    .card-title {
        font-size: 12px;
        font-style: normal;
    }

    .card-body {
        padding: 6px 10px;
    }

    .dash-2col {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 6px;
    }

    table {
        font-size: 10px;
        border-collapse: collapse;
        width: 100%;
    }

    thead th {
        background: #eee !important;
        padding: 4px 6px;
        border: 1px solid #ccc;
        font-size: 9.5px;
    }

    tbody td {
        padding: 3px 6px;
        border: 1px solid #ddd;
    }

    tfoot td {
        padding: 4px 6px;
        border: 1px solid #ccc;
        background: #f9f7f0 !important;
        font-weight: 700;
        font-size: 10px;
    }

    .stat-grid, .stat-grid-5 {
        display: none;
    }

    .calc-box {
        border: 1px solid #ddd;
        padding: 5px 8px;
        font-size: 10.5px;
    }

    .calc-row {
        padding: 2px 0;
    }

    .col-2 {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 4px;
    }

    .stat-label {
        font-size: 9px;
        letter-spacing: 0.3px;
    }

    .chip {
        font-size: 9px;
        padding: 1px 5px;
    }

    .status {
        font-size: 10px;
        padding: 2px 6px;
    }

    .td-mono {
        font-size: 9.5px;
    }

    .tbl-wrap {
        overflow: visible;
    }
    /* Print header */
    .print-header {
        display: block !important;
        text-align: center;
        border-bottom: 2px solid #333;
        margin-bottom: 8px;
        padding-bottom: 6px;
    }

        .print-header h2 {
            margin: 0;
            font-size: 15px;
        }

        .print-header p {
            margin: 2px 0;
            font-size: 10px;
            color: #555;
        }
    /* Force single page */
    .dash-2col > div:first-child {
        break-before: auto;
    }
}

/* Print header (hidden on screen) */
.print-header {
    display: none;
}

/* ── COMPACT PRINT LAYOUT ─────────────────────────────────────── */
@media print {
    .sidebar, .topbar, .mob-header, .sidebar-overlay,
    .no-print, .btn, .btn-row, .pagination, .search-row, .alert {
        display: none !important;
    }

    .main {
        margin-left: 0 !important;
    }

    .page {
        padding: 0 !important;
        animation: none !important;
    }

    body {
        font-size: 11px !important;
        background: #fff !important;
    }

    /* Compact card headers */
    .card {
        box-shadow: none !important;
        border: 1px solid #ccc !important;
        margin-bottom: 8px !important;
        break-inside: avoid;
    }

    .card-header {
        padding: 6px 10px !important;
    }

    .card-title {
        font-size: 13px !important;
    }

    .card-body {
        padding: 8px 10px !important;
    }

    /* Compact table */
    table {
        font-size: 10px !important;
    }

    thead th {
        padding: 5px 8px !important;
        font-size: 9px !important;
    }

    tbody td {
        padding: 5px 8px !important;
    }

    tfoot td {
        padding: 5px 8px !important;
    }

    /* Compact stats */
    .stat-label {
        font-size: 9px !important;
    }

    .stat-value {
        font-size: 14px !important;
    }

    .stat-grid, .stat-grid-5 {
        margin-bottom: 8px !important;
        gap: 6px !important;
    }

    .stat-card {
        padding: 8px 10px !important;
    }

    /* Two-column to single on narrow */
    .dash-2col {
        grid-template-columns: 1fr 1fr !important;
        gap: 8px !important;
    }

    .col-2 {
        grid-template-columns: 1fr 1fr !important;
        gap: 6px !important;
    }

    /* Loan header compact */
    .print-loan-header {
        display: grid !important;
        grid-template-columns: 1fr 1fr 1fr !important;
        gap: 4px 16px !important;
        font-size: 11px !important;
        margin-bottom: 8px !important;
    }

        .print-loan-header .lh-label {
            font-size: 9px;
            color: #666;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .print-loan-header .lh-val {
            font-size: 12px;
            font-weight: 600;
        }

    /* Photo small in print */
    .photo-thumb, .member-avatar-lg {
        width: 50px !important;
        height: 50px !important;
    }

    .photo-thumb-sm {
        width: 36px !important;
        height: 36px !important;
    }

    /* Page break control */
    .print-break {
        page-break-before: always;
    }

    .print-no-break {
        break-inside: avoid;
    }

    /* Receipt header */
    .receipt-header {
        text-align: center;
        border-bottom: 2px solid #c8940a;
        padding-bottom: 8px;
        margin-bottom: 10px;
    }

        .receipt-header h1 {
            font-size: 18px;
            color: #c8940a;
            margin: 0;
        }

        .receipt-header p {
            font-size: 10px;
            color: #666;
            margin: 2px 0;
        }
}

/* ── PRINT-ONLY SECTION (receipt) ───────────────────────────────── */
.print-only {
    display: none;
}

@media print {
    /* Show print-only headers/sections */
    .print-only {
        display: block !important;
    }
}
/* ══════════════════════════════════════════════════════════════
   PREMIUM MOBILE & RESPONSIVE DESIGN (APP-LIKE UX)
══════════════════════════════════════════════════════════════ */

/* ── MOBILE HEADER (Glassmorphic) ── */
.mob-header {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 60px;
    background: rgba(33, 128, 128, 0.90); /* Transparent Sidebar Bg */
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    z-index: 200;
    align-items: center;
    padding: 0 16px;
    gap: 14px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
}

.mob-hamburger {
    background: none;
    border: none;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 6px;
    border-radius: 8px;
    transition: background 0.2s;
}

    .mob-hamburger:active {
        background: rgba(255, 255, 255, 0.15);
    }

    .mob-hamburger span {
        display: block;
        width: 22px;
        height: 2px;
        background: #ffffff;
        border-radius: 2px;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .mob-hamburger.open span:nth-child(1) {
        transform: rotate(45deg) translate(5px, 5px);
    }

    .mob-hamburger.open span:nth-child(2) {
        opacity: 0;
    }

    .mob-hamburger.open span:nth-child(3) {
        transform: rotate(-45deg) translate(5px, -5px);
    }

.mob-logo {
    color: var(--gold);
    font-family: var(--font-head);
    font-weight: 700;
    font-size: 18px;
    font-style: italic;
    flex: 1;
    letter-spacing: 0.5px;
}

.mob-new-loan {
    background: var(--gold);
    color: #18150f;
    border: none;
    padding: 8px 16px;
    border-radius: 20px;
    font-size: 13px;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    box-shadow: 0 2px 8px color-mix(in srgb, var(--color-primary) 32%, transparent);
    transition: transform 0.15s, box-shadow 0.15s;
}

    .mob-new-loan:active {
        transform: scale(0.94);
        box-shadow: 0 1px 4px color-mix(in srgb, var(--color-primary) 22%, transparent);
    }

/* ── SIDEBAR OVERLAY (Smooth Fade) ── */
.sidebar-overlay {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    z-index: 249;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}

    .sidebar-overlay.visible {
        opacity: 1;
        visibility: visible;
    }

/* ── RESPONSIVE TABLE SWIPE HINT ── */
.tbl-wrap {
    overflow-x: auto;
    overflow-y: hidden; /* horizontal scroller only — never trap the vertical wheel */
    -webkit-overflow-scrolling: touch;
    border-radius: var(--radius);
    padding-bottom: 4px; /* Room for modern scrollbars */
}

table {
    min-width: 650px; /* Never squish tables, allow fluid horizontal scrolling */
}

/* ── .kv — key/value tables, NOT data grids ──────────────────────────
   .kv is the label/value table used inside cards (deposit + savings
   detail/close/receipt, loan application review, no-dues certificate).
   These sit in narrow cards and .col-2 grid columns ~360-500px wide,
   so the 650px floor above forces the table wider than its card, blows
   out the grid track and clips the values off the right edge.
   Opting .kv out is the fix; the floor still applies to real data grids.
   overflow-wrap lets long member codes break instead of setting a wide
   min-content floor of their own. */
.kv {
    min-width: 0;
}

    .kv td {
        overflow-wrap: anywhere;
    }

/* ── Denomination tally tables — same opt-out, different shape ────────
   .cs-denom / .cs2-denom are the 3-column cash-denomination grids at the
   foot of the MFI collection sheets (Denom ₹ / Qty / Amount). They ask for
   width:340px and width:100% respectively inside a narrow flex column, but
   min-width wins over width, so the 650px floor above was stretching them
   to 650px — on screen AND on paper, since no print rule resets the floor.
   Like .kv these are tally blocks, not data grids: a horizontal scroller
   would be the wrong fix, the floor simply should not apply. */
.cs-denom,
.cs2-denom {
    min-width: 0;
}

/* ── .tbl-narrow — a REAL data grid that is simply narrow ─────────────
   Three columns of member / control / note. Wide enough to need a header
   row, narrow enough that the 650px floor is just wrong: at min-width:0
   the MFI meeting grids measure 246px, so they fit a 375px phone whole.
   Deliberately NOT .kv — that class documents itself as key/value pairs,
   not data grids — and deliberately not .tbl-wrap either: these carry the
   inputs the operator is filling in, and swiping sideways to reach a field
   while the member's name scrolls out of view is worse than fitting.
   Use it only where you have MEASURED that the table fits without it. */
.tbl-narrow {
    min-width: 0;
}

/* ── Component tables that are narrow BY DEFINITION ───────────────────
   These four classes are only ever used for one shape, so the opt-out
   belongs here rather than repeated on every <table> tag. Counted at the
   time of writing — re-count before adding a WIDE table to any of them:
     .detail-table   8 uses, all label/value pairs (Investor, Incentive,
                     StatutoryAudit, TaxAudit detail panes)
     .bs-tbl         4 uses, Balance Sheet item + amount
     .bs-recon-tbl   1 use,  Balance Sheet reconciliation, item + amount
     .rc-tbl         5 uses, Branch Evacuation reconciliation, 2-3 cols
   If one of these ever grows past ~4 columns, take it OFF this list and
   give that view a .tbl-wrap instead — the floor exists for a reason. */
.detail-table,
.bs-tbl,
.bs-recon-tbl,
.rc-tbl {
    min-width: 0;
}

/* ── 1200px — Large tablets ─────────────────────────── */
@media (max-width: 1200px) {
    .stat-grid, .col-4 {
        grid-template-columns: repeat(2, 1fr);
    }

    .stat-grid-5 {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* ── 960px — Tablets ────────────────────────────────── */
@media (max-width: 960px) {
    .sidebar {
        width: 220px;
    }

    .main {
        margin-left: 220px;
    }

    .stat-grid-5 {
        grid-template-columns: repeat(2, 1fr);
    }

    .dash-2col, .dash-3col {
        grid-template-columns: 1fr;
    }

    .col-3 {
        grid-template-columns: 1fr 1fr;
    }
}

/* ── 768px — Mobile Breakpoint ──────────────────────── */
@media (max-width: 768px) {
    .mob-header {
        display: flex;
    }

    /* 60fps GPU Accelerated Drawer */
    .sidebar {
        position: fixed;
        top: 0;
        left: -280px;
        width: 280px;
        height: 100vh;
        z-index: 250;
        transition: transform 0.35s cubic-bezier(0.25, 1, 0.5, 1);
        box-shadow: none;
    }

        .sidebar.open {
            transform: translateX(280px);
            box-shadow: 4px 0 24px rgba(0,0,0,0.25);
        }

    /* Adjust main frame for overlapping header */
    .main {
        margin-left: 0 !important;
        padding-top: 60px;
        overflow-x: hidden;
    }

    .topbar {
        display: none;
    }

    .page {
        padding: 12px;
        overflow-x: hidden;
    }

    /* Unwrapped report tables: horizontal swipe inside the card instead of page overflow */
    .card-body.p0 {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Forms & Touch Targets (Crucial iOS fix) */
    input, select, textarea {
        padding: 12px 14px;
        font-size: 16px; /* Prevents auto-zoom on iPhone */
        border-radius: 10px;
    }

    /* Search row: stack filters vertically */
    .search-row {
        flex-direction: column;
        align-items: stretch;
        background: var(--surface);
        padding: 12px;
        border-radius: 12px;
        box-shadow: var(--shadow);
        gap: 8px;
    }

    /* Forms inside search-row also stack */
    .search-row form {
        display: flex;
        flex-direction: column;
        gap: 8px;
        width: 100%;
    }

    /* Date/label pairs stay inline */
    .search-row form .fg {
        flex-direction: row !important;
        align-items: center;
        gap: 8px;
    }

    .search-inp, .filter-sel {
        max-width: 100%;
        width: 100%;
    }

    /* Grids to single column */
    .col-2, .col-3, .col-4 {
        grid-template-columns: 1fr;
        gap: 12px;
    }

    /* Cards */
    .card {
        margin-bottom: 14px;
        border-radius: 14px;
    }

    .card-header {
        padding: 14px 16px;
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
    }

    .card-header .card-title {
        font-size: 15px;
    }

    .card-body {
        padding: 14px 16px;
    }

    /* Native-App style chunky buttons */
    .btn-row {
        flex-direction: column;
        gap: 10px;
        width: 100%;
        margin-top: 20px;
    }

        .btn-row .btn {
            width: 100%;
            justify-content: center;
            padding: 14px;
            font-size: 15px;
            border-radius: 12px;
        }

    /* Widget Stat Cards */
    .stat-card {
        padding: 14px;
        border-radius: 12px;
        display: flex;
        flex-direction: column;
    }

    .stat-value {
        font-size: 22px;
    }

    /* Hide date chip to save header space */
    .date-chip {
        display: none;
    }

    /* Footer compact */
    footer {
        padding: 14px 16px !important;
        font-size: 11px !important;
    }
}

/* ── 480px — Small phones ───────────────────────────── */
@media (max-width: 480px) {
    /* Keep stats 2x2 on tiny screens so they don't consume extreme height */
    .stat-grid, .stat-grid-5 {
        grid-template-columns: 1fr 1fr;
        gap: 10px;
    }

    .stat-card {
        padding: 14px;
    }

    .stat-value {
        font-size: 20px;
    }

    .stat-label {
        font-size: 10px;
    }

    /* Make calculator amounts stack uniquely */
    .calc-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 4px;
        padding: 10px 0;
    }

    .calc-val {
        font-size: 16px;
    }

        .calc-val.big {
            font-size: 24px;
        }

    /* Resize chips */
    .chip {
        padding: 4px 10px;
        font-size: 11px;
    }

    /* Pagination layout */
    .pagination {
        flex-direction: column;
        align-items: flex-start;
        gap: 12px;
    }
}

/* ══════════════════════════════════════════════════════════════
   MFI / MICROFINANCE DESIGN SYSTEM
   Classes used across all MFI module views
══════════════════════════════════════════════════════════════ */

/* ── Page Layout ─────────────────────────────────────────────── */
.page {
    padding: 24px 28px;
}

.page-hdr {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 24px;
    flex-wrap: wrap;
}

.page-title {
    font-family: var(--font-head);
    font-size: 22px;
    font-weight: 700;
    color: var(--text);
    margin: 0;
}

.page-sub,
.page-subtitle {
    font-size: 12.5px;
    color: var(--text-muted);
    margin-top: 3px;
}

.page-actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
}

/* ── Card Header (MFI variant) ───────────────────────────────── */
.card-hdr {
    padding: 12px 18px;
    border-bottom: 1px solid var(--border);
    font-family: var(--font-head);
    font-size: 13.5px;
    font-weight: 700;
    color: var(--text);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    letter-spacing: 0.2px;
    background: var(--surface2);
    border-radius: var(--radius) var(--radius) 0 0;
}

/* ── Form Grid System ────────────────────────────────────────── */
.form-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    padding: 18px;
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.form-hint {
    font-size: 11.5px;
    color: var(--text-muted);
    margin-top: 2px;
    line-height: 1.4;
}

.form-actions {
    display: flex;
    gap: 10px;
    padding: 16px 0 4px;
    flex-wrap: wrap;
}

/* ── Input class (alias for native input styling) ────────────── */
.inp {
    border: 1px solid var(--border);
    background: var(--surface);
    border-radius: 8px;
    padding: 9px 12px;
    font-family: var(--font-body);
    font-size: 13.5px;
    color: var(--text);
    outline: none;
    transition: border 0.15s, box-shadow 0.15s;
    width: 100%;
}

.inp:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 14%, transparent);
}

.inp-sm {
    padding: 6px 10px;
    font-size: 12.5px;
    border-radius: 6px;
}

/* ── Badges ──────────────────────────────────────────────────── */
.badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 9px;
    border-radius: 20px;
    white-space: nowrap;
}

.badge-neutral {
    background: var(--surface0);
    color: var(--text-muted);
}

.badge-success {
    background: var(--green-bg);
    color: var(--green);
}

.badge-danger {
    background: var(--red-bg);
    color: var(--red);
}

.badge-warning {
    background: var(--orange-bg);
    color: var(--orange);
}

.badge-info {
    background: var(--blue-bg);
    color: var(--blue);
}

.badge-gold {
    background: var(--gold-bg);
    color: var(--gold-dark);
}

/* ── Alert variants ──────────────────────────────────────────── */
.alert-danger {
    background: var(--red-bg);
    border: 1px solid #f0c0b8;
    color: var(--red);
}

.alert-success {
    background: var(--green-bg);
    border: 1px solid #b0dfcc;
    color: var(--green);
}

.alert-warning {
    background: var(--orange-bg);
    border: 1px solid #f0ccaa;
    color: var(--orange);
}

.alert-info {
    background: var(--blue-bg);
    border: 1px solid #b8d4f0;
    color: var(--blue);
}

/* ── Table (tbl) ─────────────────────────────────────────────── */
.tbl {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.tbl thead th {
    background: var(--surface0);
    color: var(--text-muted);
    font-weight: 700;
    font-size: 11px;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    padding: 10px 14px;
    text-align: left;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

.tbl tbody tr {
    border-bottom: 1px solid var(--border);
    transition: background 0.1s;
}

.tbl tbody tr:last-child {
    border-bottom: none;
}

.tbl tbody tr:hover {
    background: var(--surface2);
}

.tbl tbody td {
    padding: 11px 14px;
    color: var(--text);
    vertical-align: middle;
}

.tbl .empty {
    text-align: center;
    color: var(--text-muted);
    font-style: italic;
    padding: 28px;
}

.row-warning {
    background: var(--orange-bg) !important;
}

.row-muted {
    opacity: 0.55;
}

/* ── Branch pill multi-select (User Create/Edit — Additional Branch Access) ── */
.branch-pill-group {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface2, #f9fafb);
}
.branch-pill { position: relative; cursor: pointer; user-select: none; margin: 0; }
.branch-pill input {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}
.branch-pill span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border-radius: 999px;
    border: 1.5px solid var(--border);
    background: var(--surface, #fff);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-muted);
    transition: background .15s, border-color .15s, color .15s;
}
.branch-pill:hover span {
    border-color: var(--gold);
    color: var(--text);
}
.branch-pill input:checked + span {
    background: var(--gold-bg);
    border-color: var(--gold);
    color: var(--gold-dark);
}
.branch-pill input:checked + span::before {
    content: '✓';
    font-weight: 800;
}
.branch-pill input:focus-visible + span {
    box-shadow: 0 0 0 3px var(--gold-border);
}

/* ── KPI Cards ───────────────────────────────────────────────── */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
    margin-bottom: 20px;
}

/* KPI stat strip used across report/summary pages (DCB, DCR, LDR, Gold
   Inventory, Recovery, Leave …). auto-fit fills the full row width for any
   card count (2–5), so cards never collapse into a narrow left column with a
   dead gap on the right. Pages that need a fixed column count (e.g. Daily
   Collection Summary) override .kpi-row in their own <style> block. */
.kpi-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 14px;
    margin-bottom: 16px;
}

.kpi-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px 18px;
    box-shadow: var(--shadow);
}

.kpi-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
}

.kpi-value {
    font-family: var(--font-mono);
    font-size: 22px;
    font-weight: 600;
    margin-top: 5px;
    color: var(--text);
}

.kpi-sub {
    font-size: 11.5px;
    color: var(--text-muted);
    margin-top: 3px;
}

/* ── Definition List Grid ────────────────────────────────────── */
.dl-grid {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 8px 16px;
    padding: 16px 18px;
    font-size: 13px;
    align-items: baseline;
}

.dl-grid dt {
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    white-space: nowrap;
}

.dl-grid dd {
    color: var(--text);
    margin: 0;
}

/* ── Filter / Action Bar ─────────────────────────────────────── */
.filter-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 12px 16px;
    background: var(--surface2);
    border-bottom: 1px solid var(--border);
}

/* ── Filter / search bars: keep date pickers & dropdowns compact + inline ──
   The global `.inp, .search-inp, .filter-sel { width: 100% }` rule makes any
   such control WITHOUT an inline width stretch to a full-width, own-line row
   inside a flex filter bar — that is the stacked date inputs and full-width
   "All Branches / All Agents" dropdowns seen on the report pages (P&L, DCB,
   Agent Performance, Income, Group Performance). Scope date/time inputs and
   selects back to their natural size so they line up inline. Text/search
   inputs are intentionally left alone (a wide search box is desirable), and an
   explicit inline width on a control still wins, so views that set one are
   unaffected. */
.filter-bar input[type="date"],
.filter-bar input[type="time"],
.filter-bar input[type="month"],
.filter-bar select,
.filter-bar .filter-sel,
.search-row input[type="date"],
.search-row input[type="time"],
.search-row input[type="month"],
.search-row select,
.search-row .filter-sel {
    width: auto;
    min-width: 150px;
    flex: 0 1 auto;
}
@media (min-width: 769px) {
    /* Desktop only: cap dropdown width so a long branch/agent name can't stretch
       the control across the bar. Left off on mobile, where .search-row is meant
       to stack full-width. */
    .filter-bar select, .filter-bar .filter-sel,
    .search-row select, .search-row .filter-sel { max-width: 260px; }
}

/* ── Filter Panel ────────────────────────────────────────────────
   The house filter block for list & report pages. Approved 2026-08-26
   ("Option B — always-open labelled grid"); replaces the unlabelled
   `.filter-bar` / `.search-row` wrap ONE VIEW AT A TIME. Both of those
   are untouched and still back ~180 unconverted views — do not retire
   them until the last view moves.

   Markup contract — filter-panel.js reads this shape, so keep it:

     <form method="get" class="card fpanel">
       <div class="fpanel-hdr">
         <h3>Filter loans</h3>
         <span class="fp-count"><b>1,284</b> of 5,875 loans</span>   @* optional *@
       </div>
       <div class="fpanel-body">
         <div class="fp-fld">
           <label for="fStatus">Status</label>
           <select id="fStatus" name="Status" class="inp">…</select>
         </div>
         …
       </div>
       <div class="fpanel-foot">
         <button type="submit" class="btn btn-primary">Apply filters</button>
         <a asp-action="Index" class="fp-link">Clear all</a>
       </div>
     </form>

   Rules that keep the rollout mechanical:
   * EVERY control carries a <label for="…"> — that text names its
     applied-filter tag. An unlabelled control is skipped by the tag row,
     so it silently becomes un-removable. Label everything.
   * NO inline width styles on the controls. The grid sizes them; an inline
     width re-creates the ragged wrap this component exists to remove.
   * NEVER nest this inside .filter-bar / .search-row — those scope selects
     to width:auto and the grid track collapses.
   * A branch picker keeps its onchange="window.syncBranchToSidebar(this.value, this)"
     — see the standing both-halves rule in the branch-sync notes.        */

.fpanel { margin-bottom: 16px; }

.fpanel-hdr {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 16px;
    background: var(--surface2);
    border-bottom: 1px solid var(--border);
    border-radius: var(--radius) var(--radius) 0 0;
}

.fpanel-hdr h3 {
    margin: 0;
    font-family: var(--font-head);
    font-size: 13px;
    font-weight: 700;
    color: var(--color-ink-strong);
}

.fpanel-hdr .fp-ico { flex: none; color: var(--color-primary); }

.fpanel-hdr .fp-sep {
    width: 1px;
    height: 20px;
    background: var(--border);
    flex: none;
}

/* Quick-status chips promoted INTO the header (Loan + MfiLoan books only).
   They used to sit in a free-floating .status-chip-row below the card, reading
   as unrelated to the Status dropdown that sets the same value. Kept as links,
   so they still carry every other active filter through PageUrl(). */
.fpanel-hdr .status-chip-row { margin: 0; }

@media (max-width: 900px) {
    .fpanel-hdr { flex-wrap: wrap; }
    .fpanel-hdr .fp-sep { display: none; }
    .fpanel-hdr .fp-count { margin-left: 0; width: 100%; }
}

/* Row count — "1,284 of 5,875 loans". Optional; fed from the view model. */
.fp-count {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--text-muted);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.fp-count b { color: var(--color-ink-strong); font-weight: 600; }

/* Explanatory copy that belonged to the card this panel replaced — the Renewal vs
   Re-Loan vs Foreclosure screens each carry a paragraph telling the operator which one
   they are on. Full width, between header and fields; it is prose, not a control. */
.fp-note {
    padding: 10px 16px 0;
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-muted);
}

/* auto-fill (not auto-fit) on purpose: a 3-field panel keeps ~190px controls
   instead of stretching each one across a third of a 1400px screen.
   170px is also load-bearing for HEIGHT, and the number was measured on the
   running page, not guessed. Track count is floor((contentW + gap) / (min + gap)),
   and contentW excludes this block's own 32px of horizontal padding — 1366px of
   viewport leaves 919px here, not 951. At 210px that gave 4 tracks / 3 rows and the
   panel came out ~100px TALLER than the unlabelled `.filter-bar` it replaced; 180px
   still dropped to 4 tracks below 1440px. 170px holds 5 tracks from 1366px up, so
   MfiLoan's 10 track-units land in 2 rows on every laptop we support.
   RE-MEASURE IN THE BROWSER BEFORE RAISING IT — the failure is silent and looks
   only like "the filters got tall again". */
.fpanel-body {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: 12px;
    padding: 14px 16px;
}

.fp-fld {
    display: flex;
    flex-direction: column;
    gap: 5px;
    min-width: 0;
}

.fp-fld > label {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-family: var(--font-body);
}

/* A checkbox filter, sized and bordered like the other controls so it sits on the
   same 36px baseline instead of floating half a row up. The wrapping <label> would
   otherwise inherit the uppercase caption style above — hence the reset. The field's
   CAPTION must still be a separate `<label for="…">` and must come FIRST in the
   markup, because filter-panel.js names the tag from the first matching label. */
.fp-fld > label.fp-check {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--text);
    cursor: pointer;
}

.fp-fld > label.fp-check input {
    width: auto;
    flex: none;
    margin: 0;
    padding: 0;
}

/* Some report pages wrap their whole body in one card, so the panel ends up inside a
   `.card-body`. That is allowed — only `.filter-bar` / `.search-row` break the grid — but
   drop the second shadow so it reads as a section rather than a card floating on a card. */
.card-body form.fpanel { box-shadow: none; }

/* Safety net for a panel whose fields are ALL conditional — a branch picker that only
   renders for HO, say. For a single-branch user the body comes out empty and the page
   shows a card with a title, an Apply button and nothing to apply. Hide the whole panel
   instead. Caught on MfiCentre during Wave 2; the same shape recurs across the rollout,
   so this is a rule rather than a per-view fix.
   `:has()` is Chrome/Edge 105+, Safari 15.4+, Firefox 121+ — an older browser degrades
   to showing the empty card, which is cosmetic. Where the emptiness is KNOWN at render
   time, still wrap the form in the same `@if` so it never reaches the DOM. */
form.fpanel:not(:has(.fp-fld)) { display: none; }

/* ── Filter Panel: the "More filters" block ──────────────────────
   For a report whose filter set is genuinely large (Customer Loan Master carries ~35),
   an always-open grid becomes a wall of controls that buries the four an operator
   actually reaches for. The core filters stay in the first `.fpanel-body`; the rest go
   into a `<details class="fpanel-more">` holding a SECOND `.fpanel-body`.

   The nested block MUST keep the `.fpanel-body` class: filter-panel.js selects
   `.fpanel-body .fp-fld`, so an advanced filter still renders its removable tag in the
   footer even while the section is shut — which is how the operator finds out a
   collapsed filter is narrowing the report.

   `<details>` only HIDES its content; the inputs still post, so nothing is lost by
   collapsing. Views open it server-side (`open` when any advanced filter is set) rather
   than leaving an active filter behind a closed lid.                              */
.fpanel-more {
    border-top: 1px dashed var(--border);
}

.fpanel-more > summary {
    list-style: none;
    cursor: pointer;
    padding: 9px 16px;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-primary);
    user-select: none;
    display: flex;
    align-items: center;
    gap: 7px;
}

.fpanel-more > summary::-webkit-details-marker { display: none; }

.fpanel-more > summary::before {
    content: "▸";
    font-size: 10px;
    transition: transform 0.12s ease;
}

.fpanel-more[open] > summary::before { transform: rotate(90deg); }

.fpanel-more > summary:hover { background: var(--surface2); }

.fpanel-more > .fpanel-body { padding-top: 4px; }

/* ── Column packs ────────────────────────────────────────────────
   Which columns a wide register shows is NOT a filter — it narrows nothing — so it
   deliberately lives outside `.fpanel` rather than adding chips to the applied-filter
   tag row. Each chip is a link that toggles its own key in ?columns= and carries every
   active filter through, so re-columning never re-scopes the report.                */
.clm-packs {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.clm-packs-lbl {
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.clm-packs-sep {
    width: 1px;
    align-self: stretch;
    background: var(--border);
    margin: 2px 6px;
}

.clm-chip,
.clm-preset {
    display: inline-flex;
    align-items: center;
    height: 26px;
    padding: 0 10px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface);
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    text-decoration: none;
    white-space: nowrap;
}

.clm-chip:hover,
.clm-preset:hover { border-color: var(--color-primary); color: var(--color-primary); }

.clm-chip.on {
    background: var(--color-primary-soft);
    border-color: var(--gold-border);
    color: var(--color-primary);
    font-weight: 650;
}

.clm-preset.on {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
    font-weight: 650;
}

/* Page actions (New X, exports) for views that had them sharing a row with the old
   filter bar. Right-aligned above the panel, which is where they already sat when the
   filter form took the remaining width. Views with a `.page-hdr` keep using that. */
.fp-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: flex-end;
    margin-bottom: 12px;
}

/* Left-aligned variant, for the back-link + heading block that shared the old filter row
   on the StaffPerformance drill-downs. Same spacing, opposite end. */
.fp-actions.start { justify-content: flex-start; }

/* Search boxes and date ranges earn two tracks. */
.fp-fld.wide { grid-column: span 2; }

@media (max-width: 640px) {
    .fp-fld.wide { grid-column: span 1; }
}

.fp-range {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 6px;
}

.fp-range .fp-to {
    color: var(--text-dim);
    font-size: 12px;
    padding: 0 2px;
}

.fpanel-foot {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 10px 16px;
    border-top: 1px solid var(--border);
    background: var(--surface2);
    border-radius: 0 0 var(--radius) var(--radius);
}

.fp-link {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0 4px;
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
    color: var(--text-muted);
    text-decoration: none;
}

.fp-link:hover { color: var(--red); }

/* Applied-filter tags — built by filter-panel.js from the form's own
   labelled controls, so no view has to render them. */
.fp-tags {
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
    margin-left: auto;
}

.fp-tag {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 26px;
    padding: 0 6px 0 10px;
    border-radius: 999px;
    background: var(--color-primary-soft);
    border: 1px solid var(--gold-border);
    font-size: 12px;
    font-weight: 500;
    color: var(--color-primary);
    max-width: 260px;
}

.fp-tag .fp-tag-v {
    font-weight: 650;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fp-tag button {
    border: none;
    background: none;
    cursor: pointer;
    color: inherit;
    opacity: 0.55;
    font-size: 14px;
    line-height: 1;
    padding: 2px 4px;
    border-radius: 50%;
    width: auto;
    flex: none;
}

.fp-tag button:hover {
    opacity: 1;
    background: color-mix(in srgb, var(--color-primary) 16%, transparent);
}

/* ── Empty State ─────────────────────────────────────────────── */
.empty-state {
    text-align: center;
    padding: 48px 24px;
    color: var(--text-muted);
}

.empty-state .empty-icon {
    font-size: 40px;
    margin-bottom: 12px;
    opacity: 0.4;
}

.empty-state .empty-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 6px;
}

/* ── Utility ─────────────────────────────────────────────────── */
.mono {
    font-family: var(--font-mono);
    font-size: 12.5px;
}

.text-muted {
    color: var(--text-muted);
}

.text-success {
    color: var(--green);
}

.c-gold  { color: var(--gold); }
.c-green { color: var(--green); }
.c-red   { color: var(--red); }
.c-blue  { color: var(--blue); }

.btn-xs {
    padding: 4px 10px;
    font-size: 11.5px;
    border-radius: 6px;
}

/* ── Responsive: MFI form-grid ───────────────────────────────── */
@media (max-width: 1100px) {
    .form-grid {
        grid-template-columns: repeat(2, 1fr);
    }
    .kpi-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 768px) {
    .form-grid {
        grid-template-columns: 1fr;
    }
    .kpi-grid {
        grid-template-columns: repeat(2, 1fr);
    }
    .page-hdr {
        flex-direction: column;
        align-items: flex-start;
    }
    .dl-grid {
        grid-template-columns: 1fr;
        gap: 4px 0;
    }
}

/* ════════════════════════════════════════════════════════════════
   v2 — Global control spacing normalization (10x design pass)
   These rules use semantic spacing tokens so EVERY existing form,
   card, table and section gets consistent rhythm — without touching
   60+ individual views. Themes and density toggles still apply.
   ════════════════════════════════════════════════════════════════ */

/* Cards: standard padding everywhere */
.card { border-radius: 10px; }
.card-header, .card-hdr { padding: 12px 18px; gap: 12px; font-weight: 600; font-size: 14px; color: var(--color-ink-strong); border-bottom: 1px solid var(--color-border); display: flex; align-items: center; justify-content: space-between; }
.card-body   { padding: 16px 18px; }
.card-body.p0 { padding: 0; }

/* Section titles: uniform rhythm */
.section-title {
    font-size: 13px; font-weight: 700; color: var(--color-ink-strong);
    text-transform: uppercase; letter-spacing: 0.4px;
    margin: 0 0 10px 0; padding-bottom: 6px;
    border-bottom: 1px solid var(--color-border);
}

/* Form groups: tighter vertical rhythm — label tight on input */
.fg, .form-group {
    display: flex; flex-direction: column;
    gap: 5px; margin-bottom: 14px;
}
.fg label, .form-group label {
    font-size: 12px; font-weight: 600;
    color: var(--color-ink-muted);
    text-transform: uppercase; letter-spacing: 0.4px;
    margin: 0;
}
.fg input, .fg select, .fg textarea,
.form-group input, .form-group select, .form-group textarea,
.inp, .search-inp, .filter-sel {
    height: var(--input-h);
    padding: 0 10px;
    border: 1px solid var(--color-border);
    border-radius: 5px;
    background: var(--color-surface);
    color: var(--color-ink-strong);
    font-family: var(--font-body);
    font-size: 13px;
    width: 100%;
    max-width: 100%;
    transition: border-color 0.12s, box-shadow 0.12s;
}
.fg textarea, .form-group textarea {
    height: auto;
    min-height: 64px;
    padding: 8px 10px;
    resize: vertical;
    line-height: 1.5;
}
.fg input:focus, .fg select:focus, .fg textarea:focus,
.form-group input:focus, .form-group select:focus, .form-group textarea:focus,
.inp:focus, .search-inp:focus, .filter-sel:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px var(--color-primary-soft);
}
.fg input[readonly], .form-group input[readonly] { background: var(--color-surface-sunken, var(--surface2)); cursor: default; }

/* ── Browser autofill: suppress the yellow wash ────────────────────────────
   Chrome/Edge paint rgb(250,255,189) over any field they consider autofillable
   and refuse to let background-color override it. Two tricks are needed:

     1. A huge inset box-shadow repaints the field in our own surface colour.
        The spread must exceed the widest control on any page — a small spread
        (the 30px this codebase used in the sidebar) leaves the yellow visible
        across the middle and right of a wide input.
     2. An absurdly long background-color transition, so the yellow cannot even
        flash mid-state before the shadow lands.

   Scoped to :-webkit-autofill, so normal focus/hover styling is untouched.
   This is deliberately global: the wash hits whole toolbars — most visibly the
   Bulk Disbursement batch bar, where Chrome treats the account/mode selects as
   a payment form and washes the surrounding cards too. Fixing it per-page just
   moves the bug to the next form the browser guesses at. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus,
select:-webkit-autofill:active,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
textarea:-webkit-autofill:active {
    -webkit-box-shadow: 0 0 0 1000px var(--color-surface, #fff) inset !important;
            box-shadow: 0 0 0 1000px var(--color-surface, #fff) inset !important;
    -webkit-text-fill-color: var(--color-ink-strong, #111) !important;
    caret-color: var(--color-ink-strong, #111);
    transition: background-color 600000s 0s, color 600000s 0s;
}
/* Firefox has its own (milder) autofill tint, and honours a plain background. */
input:autofill, select:autofill, textarea:autofill {
    background: var(--color-surface, #fff);
    color: var(--color-ink-strong, #111);
}

/* Form grids: tighter gaps + cap input column width for readability */
.form-grid, .col-2, .col-3, .col-4 { display: grid; gap: 12px 14px; }
.col-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.col-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.col-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.form-grid { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
/* Avoid super-wide single-column inputs in 1- or 2-column form-grids */
.form-grid.tight { max-width: 880px; }
@media (max-width: 768px) {
    .col-2, .col-3, .col-4 { grid-template-columns: 1fr; }
}

/* Button row: consistent gap and top margin */
.btn-row, .form-actions {
    display: flex; gap: 8px; flex-wrap: wrap;
    align-items: center;
    margin-top: 20px;
    padding-top: 14px;
    border-top: 1px solid var(--color-border);
}

/* Buttons: identical heights regardless of class */
.btn, button.btn {
    height: var(--btn-h);
    padding: 0 12px;
    border-radius: 5px;
    font-size: 12.5px; font-weight: 600;
    display: inline-flex; align-items: center; gap: 6px;
    cursor: pointer; border: 1px solid transparent;
    transition: background 0.12s, border-color 0.12s, transform 0.06s;
    line-height: 1;
}
.btn:active { transform: translateY(1px); }
.btn-sm { height: 26px; padding: 0 9px; font-size: 11.5px; }
.btn-xs { height: 22px; padding: 0 7px; font-size: 11px; border-radius: 4px; }
.btn-lg { height: 40px; padding: 0 16px; font-size: 14px; }

/* Search row: consistent spacing */
.search-row {
    display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
    margin-bottom: 16px;
}

/* Tables: uniform cell padding via density tokens */
table { width: 100%; border-collapse: collapse; }
table th, table td { padding: var(--row-py) var(--row-px); }

/* Validation message rhythm */
.text-danger, .field-validation-error, span[asp-validation-for] {
    display: block; font-size: 12px; color: var(--color-danger);
    margin-top: 4px;
}
.field-err {
    border-color: var(--color-danger) !important;
    box-shadow: 0 0 0 3px var(--color-danger-soft) !important;
}
.field-err-msg { animation: shakeIn 0.2s ease-out; }
@keyframes shakeIn {
    0% { transform: translateX(-3px); opacity: 0; }
    50% { transform: translateX(3px); }
    100% { transform: translateX(0); opacity: 1; }
}
.alert { padding: 10px 14px; border-radius: 6px; margin-bottom: 14px; font-size: 13px; }

/* ════════════════════════════════════════════════════════════════
   v2 — Topbar buttons, KPI cards, sticky tables, slide-over, etc.
   Added in the 2026 design refresh. Uses semantic tokens so themes
   automatically restyle these without per-component overrides.
   ════════════════════════════════════════════════════════════════ */

/* ── Row actions: primary CTA + icon group (used in list tables) ── */
.row-actions { display: inline-flex; align-items: center; gap: 8px; flex-wrap: nowrap; }
.row-actions .ra-pay { font-weight: 700; }
.row-actions .ra-icons {
    display: inline-flex; align-items: center;
    border: 1px solid var(--color-border); border-radius: 6px;
    background: var(--color-surface); overflow: hidden;
}
.row-actions .ra-icon {
    display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 26px;
    text-decoration: none; color: var(--color-ink-muted);
    font-size: 14px; line-height: 1;
    border-right: 1px solid var(--color-border);
    transition: background .12s, color .12s;
}
.row-actions .ra-icon:last-child { border-right: none; }
.row-actions .ra-icon:hover { background: var(--color-primary-soft); color: var(--color-primary); }

/* ── Topbar quick-action buttons ──────────────────────────────── */
.topbar-icon-btn {
    display: inline-flex; align-items: center; gap: 6px;
    height: 32px; padding: 0 10px;
    background: var(--color-surface);
    color: var(--color-ink);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-size: 13px; cursor: pointer;
    transition: background .12s, border-color .12s;
}
.topbar-icon-btn:hover { background: var(--color-primary-soft); border-color: var(--color-primary); color: var(--color-ink-strong); }
.topbar-icon-btn .kbd {
    font-family: var(--font-mono); font-size: 10px;
    padding: 1px 5px; border: 1px solid var(--color-border); border-radius: 3px;
    color: var(--color-ink-muted);
}

/* ── KPI cards (used in Dashboard) ────────────────────────────── */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-bottom: 20px; }
.kpi-card {
    background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: 10px; padding: 16px; transition: box-shadow .15s, border-color .15s;
    display:flex; flex-direction:column; gap:6px;
}
.kpi-card:hover { box-shadow: var(--shadow-md); border-color: var(--color-primary); }
.kpi-card .kpi-label { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--color-ink-muted); font-weight: 600; }
.kpi-card .kpi-value { font-size: 24px; font-weight: 700; color: var(--color-ink-strong); font-variant-numeric: tabular-nums; line-height: 1.2; }
.kpi-card .kpi-delta { font-size: 12px; font-weight: 500; }
.kpi-card .kpi-delta.up   { color: var(--color-success); }
.kpi-card .kpi-delta.down { color: var(--color-danger);  }
.kpi-card .kpi-delta.flat { color: var(--color-ink-muted); }
.kpi-card .kpi-link { margin-top: 6px; font-size: 12px; color: var(--color-primary); text-decoration: none; font-weight: 600; }
.kpi-card .kpi-link:hover { text-decoration: underline; }

/* ── Quick actions strip ──────────────────────────────────────── */
.quick-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 18px; }
.qa-btn {
    display:inline-flex; align-items:center; gap:8px;
    padding: 10px 16px; background: var(--color-surface); border: 1px solid var(--color-border);
    border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--color-ink-strong); text-decoration: none;
    transition: background .12s, border-color .12s, transform .08s;
}
.qa-btn:hover { background: var(--color-primary-soft); border-color: var(--color-primary); transform: translateY(-1px); }
.qa-btn.primary { background: var(--color-primary); color: #fff; border-color: var(--color-primary); }
.qa-btn.primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); color: #fff; }

/* ── Sticky table headers + density ───────────────────────────── */
.tbl-sticky { position: relative; max-height: 70vh; overflow: auto; border: 1px solid var(--color-border); border-radius: 8px; }
.tbl-sticky table { width: 100%; border-collapse: separate; border-spacing: 0; }
.tbl-sticky thead th {
    position: sticky; top: 0; z-index: 2;
    background: var(--color-surface-sunken, var(--surface2));
    box-shadow: inset 0 -1px 0 var(--color-border);
    padding: var(--row-py) var(--row-px); font-weight: 600; text-align: left;
    font-size: 12px; color: var(--color-ink-muted); text-transform: uppercase; letter-spacing: .3px;
}
.tbl-sticky tbody td { padding: var(--row-py) var(--row-px); border-bottom: 1px solid var(--color-border); font-size: var(--text-sm); color: var(--color-ink-strong); }
.tbl-sticky tbody tr:hover { background: var(--color-primary-soft); }
.tbl-sticky tbody tr.expanded { background: var(--color-primary-soft); }
.tbl-sticky tbody tr.row-detail td { padding: 14px 18px; background: var(--color-surface-sunken, var(--surface2)); }
.tbl-sticky .num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl-sticky .checkbox-col { width: 36px; }
.tbl-toolbar { display: flex; gap: 8px; align-items: center; padding: 10px 12px; border-bottom: 1px solid var(--color-border); background: var(--color-surface); flex-wrap:wrap; }
.tbl-density-toggle { display:inline-flex; border:1px solid var(--color-border); border-radius:6px; overflow:hidden; }
.tbl-density-toggle button {
    background: var(--color-surface); border: none; padding: 4px 10px;
    font-size: 12px; cursor: pointer; color: var(--color-ink-muted);
}
.tbl-density-toggle button.active { background: var(--color-primary); color: #fff; }
.bulk-action-bar {
    position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(100px);
    background: var(--color-ink-strong); color: #fff; border-radius: 999px; padding: 10px 22px;
    display: flex; align-items: center; gap: 14px; box-shadow: var(--shadow-lg);
    transition: transform .25s ease;
    z-index: 500;
    font-size: 13px;
}
.bulk-action-bar.visible { transform: translateX(-50%) translateY(0); }
.bulk-action-bar .ba-btn { background: var(--color-primary); color: #fff; border: none; padding: 6px 14px; border-radius: 999px; cursor: pointer; font-size: 12px; font-weight: 600; }
.bulk-action-bar .ba-clear { background: transparent; color: #fff; border: 1px solid #ffffff44; padding: 6px 12px; border-radius: 999px; cursor: pointer; font-size: 12px; }

/* ── Scroll-to-top floating button ───────────────────────────────
   Bottom-right (bulk-action-bar owns bottom-center) so the two never
   overlap on a page that has both a long table and an active selection. */
.scroll-top-btn {
    position: fixed; right: 24px; bottom: var(--fab-bottom, 24px); z-index: 400;
    width: 44px; height: 44px; border-radius: 50%;
    background: var(--color-primary); color: #fff; border: none;
    font-size: 18px; line-height: 1; cursor: pointer;
    box-shadow: var(--shadow-lg);
    display: flex; align-items: center; justify-content: center;
    opacity: 0; visibility: hidden; transform: translateY(12px);
    transition: opacity .2s ease, transform .2s ease, background .12s ease;
}
.scroll-top-btn.visible { opacity: 1; visibility: visible; transform: translateY(0); }
.scroll-top-btn:hover { background: var(--color-primary-hover, var(--color-primary)); }

/* ── Clearance for a page's OWN fixed bottom action bar ──────────
   Four views pin an action bar of their own to the viewport bottom: .lc-sticky
   (MfiLoan/Create, LoanTopUpMerge/Select) and .rc-sticky (MfiCollection/RegularEntry,
   GoldCollection/EmiEntry). Those bars sit at z-index 50-100 and this button at 400,
   so at the default bottom:24px the button lands ON TOP of the bar's right-hand
   primary control — "Disburse Loan →", "Save Collections" — clipping the label and
   swallowing the click, because the higher z-index wins the hit test.

   ⚠ The two bars are NOT the same height, and a static number was wrong once already:
   measured in the browser at 1600px wide, .lc-sticky is 57px but .rc-sticky is 84px.
   (RegularEntry.cshtml used to claim "≈64px"; believing it produced a clearance that
   still overlapped .rc-sticky by 8px. Measure — do not read the number off a comment.)
   Both also carry flex-wrap:wrap, so either grows a row on a narrow viewport.
   scroll-to-top.js therefore MEASURES the bar and writes the exact --fab-bottom,
   re-measuring on resize. The values below are only the no-JS fallback, sized for
   the taller bar. A new page with its own fixed bottom bar must be added BOTH here
   and to the querySelector in scroll-to-top.js. */
body:has(.lc-sticky, .rc-sticky) { --fab-bottom: 100px; }

@media (max-width: 768px) {
    /* Clear the mobile .bottom-nav bar — .main reserves 70px for it (line ~2714). */
    .scroll-top-btn { right: 16px; width: 40px; height: 40px; font-size: 16px; }
    :root { --fab-bottom: 76px; }
    /* Stacked: the page's own bar sits above .bottom-nav, so clear both. */
    body:has(.lc-sticky, .rc-sticky) { --fab-bottom: 170px; }
}

/* ── Status quick-filter chips ────────────────────────────────────
   One-click shortcuts for the most common status-dropdown values on a
   list page. Plain links (not JS) so they work identically to the
   dropdown they shortcut — same query param, same server-side filter. */
.status-chip-row { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 12px; }
.status-chip {
    padding: 5px 13px; font-size: 12px; font-weight: 600;
    color: var(--color-ink-muted); background: var(--color-surface);
    border: 1px solid var(--color-border); border-radius: 999px;
    text-decoration: none; white-space: nowrap; transition: all .12s ease;
}
.status-chip:hover { border-color: var(--color-primary); color: var(--color-primary); }
.status-chip.active { color: #fff; border-color: transparent; }
.status-chip.active.chip-neutral { background: var(--color-primary); }
.status-chip.active.chip-success { background: var(--color-success); }
.status-chip.active.chip-danger  { background: var(--color-danger); }
.status-chip.active.chip-warning { background: var(--color-warning); }
/* Matches the .s-closed badge convention: closed is a neutral end-state,
   not a semantic color — grey, not red/green/blue. */
.status-chip.active.chip-muted   { background: var(--color-ink-muted); }

/* ── Slide-over panel ─────────────────────────────────────────── */
.slideover-overlay { position: fixed; inset: 0; background: rgba(15,23,36,.4); z-index: 8000; opacity: 0; pointer-events: none; transition: opacity .2s; }
.slideover-overlay.open { opacity: 1; pointer-events: auto; }
.slideover {
    position: fixed; top: 0; right: 0; bottom: 0; width: min(440px, 100%);
    background: var(--color-surface); border-left: 1px solid var(--color-border); box-shadow: var(--shadow-lg);
    transform: translateX(110%); transition: transform .25s ease;
    z-index: 8001; display: flex; flex-direction: column;
}
.slideover.open { transform: translateX(0); }
.slideover-header { padding: 14px 18px; border-bottom: 1px solid var(--color-border); display: flex; align-items: center; gap: 10px; }
.slideover-header .so-title { font-size: 15px; font-weight: 700; color: var(--color-ink-strong); flex: 1; }
.slideover-header .so-close { background: none; border: none; font-size: 20px; cursor: pointer; color: var(--color-ink-muted); }
.slideover-body { flex: 1; overflow-y: auto; padding: 18px; }
.slideover-footer { padding: 14px 18px; border-top: 1px solid var(--color-border); display: flex; gap: 10px; justify-content: flex-end; background: var(--color-surface-sunken, var(--surface2)); }

/* ── Two-pane (Loan Create) ───────────────────────────────────── */
.two-pane { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 20px; align-items: start; }
.two-pane > .pane-form { min-width: 0; }
.two-pane > .pane-preview { position: sticky; top: calc(var(--topbar-h) + 16px); }
.preview-card { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 10px; padding: 16px; }
.preview-card h4 { font-size: 12px; text-transform: uppercase; letter-spacing: .5px; color: var(--color-ink-muted); margin-bottom: 10px; font-weight: 600; }
.preview-row { display: flex; justify-content: space-between; padding: 6px 0; font-size: 13px; }
.preview-row.total { border-top: 1px solid var(--color-border); margin-top: 6px; padding-top: 10px; font-weight: 700; font-size: 14px; color: var(--color-ink-strong); }
.preview-row .v { font-variant-numeric: tabular-nums; }
.ltv-gauge { height: 6px; background: var(--color-border); border-radius: 3px; overflow: hidden; margin-top: 10px; }
.ltv-gauge .ltv-fill { height: 100%; background: var(--color-success); transition: width .2s, background .2s; }
.ltv-gauge.warn .ltv-fill { background: var(--color-warning); }
.ltv-gauge.danger .ltv-fill { background: var(--color-danger); }
.ltv-status { font-size: 12px; margin-top: 6px; color: var(--color-success); font-weight: 600; }
.ltv-status.warn { color: var(--color-warning); }
.ltv-status.danger { color: var(--color-danger); }

@media (max-width: 1024px) {
    .two-pane { grid-template-columns: 1fr; }
    .two-pane > .pane-preview { position: static; }
}

/* ── Bottom nav (mobile only) ─────────────────────────────────── */
.bottom-nav { display: none; }
@media (max-width: 768px) {
    .bottom-nav {
        display: flex; position: fixed; left: 0; right: 0; bottom: 0;
        background: var(--color-surface); border-top: 1px solid var(--color-border);
        box-shadow: 0 -2px 8px rgba(0,0,0,0.05);
        z-index: 200; padding: 6px 4px; padding-bottom: calc(6px + env(safe-area-inset-bottom));
    }
    .bottom-nav a {
        flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
        padding: 6px 4px; text-decoration: none; color: var(--color-ink-muted);
        font-size: 10px; font-weight: 600;
    }
    .bottom-nav a.active { color: var(--color-primary); }
    .bottom-nav a .bn-icon { font-size: 20px; }
    .main { padding-bottom: 70px !important; }
}

/* ════════════════════════════════════════════════════════════════
   FinPay restyle overlay (Phase B)
   Surgical layer that lifts existing components into the FinPay
   look without changing markup. Sits at the bottom so its rules
   beat earlier declarations of the same selector.
   ════════════════════════════════════════════════════════════════ */

/* ── SIDEBAR · violet gradient + ambient glow ─────────────────── */
.sidebar {
    background: linear-gradient(180deg, var(--sidebar-bg) 0%, var(--sidebar-bg-2, #1F1660) 100%);
    box-shadow: 1px 0 0 rgba(255,255,255,0.04) inset, 4px 0 24px rgba(17,17,26,0.18);
    overflow: hidden;
}
.sidebar::after {
    content: '';
    position: absolute;
    top: -120px;
    right: -100px;
    width: 320px;
    height: 320px;
    border-radius: 50%;
    background: radial-gradient(circle, color-mix(in srgb, var(--color-accent) 22%, transparent), transparent 70%);
    pointer-events: none;
}

.sidebar-logo {
    border-bottom: 1px solid rgba(255,255,255,0.10);
    position: relative;
    z-index: 1;
}
.logo-icon {
    background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
    box-shadow: 0 4px 12px color-mix(in srgb, var(--color-accent) 40%, transparent);
    color: #fff;
    font-weight: 800;
}
.logo-text .logo-name {
    font-style: normal;
    font-weight: 800;
    letter-spacing: -0.3px;
}
.logo-text .logo-version {
    color: rgba(255,255,255,0.62);
}

/* Tenant badge — tinted glass card */
.tenant-badge {
    background: rgba(255,255,255,0.06);
    border: 1px solid rgba(255,255,255,0.10);
    border-radius: var(--radius);
    position: relative;
    z-index: 1;
}
.tenant-badge .tenant-code {
    color: var(--sidebar-accent, #FBBF24);
    font-weight: 700;
}
.tenant-badge .tenant-name {
    color: #FFFFFF;
    font-weight: 700;
}
.tenant-badge .tenant-branch {
    color: rgba(255,255,255,0.70);
}

.nav { position: relative; z-index: 1; }
.nav-label { color: rgba(255,255,255,0.55); font-weight: 700; }

.nav-item {
    color: rgba(255,255,255,0.78);
    border-radius: 10px;
    position: relative;
    padding-left: 28px;
}
.nav-item::before {
    content: '';
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: rgba(255,255,255,0.25);
    transition: background 0.15s, transform 0.15s, width 0.15s, height 0.15s;
}
.nav-item:hover {
    background: rgba(255,255,255,0.06);
    color: #FFFFFF;
}
.nav-item:hover::before {
    background: rgba(255,255,255,0.65);
}
.nav-item.active {
    background: rgba(255,255,255,0.10);
    color: #FFFFFF;
    font-weight: 700;
}
.nav-item.active::before {
    background: var(--sidebar-accent, #FBBF24);
    width: 5px;
    height: 5px;
}
.nav-item .nav-icon { color: inherit; }

.nav-badge {
    background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
    color: #FFFFFF;
    box-shadow: 0 2px 6px color-mix(in srgb, var(--color-primary) 32%, transparent);
}
.nav-item.active .nav-badge {
    background: rgba(255,255,255,0.22);
    box-shadow: none;
}

.sidebar-footer {
    border-top: 1px solid rgba(255,255,255,0.10);
    position: relative;
    z-index: 1;
}
.user-avatar {
    background: linear-gradient(135deg, var(--color-accent), #B8A6FF);
    color: #FFFFFF;
    box-shadow: 0 0 0 2px rgba(255,255,255,0.20);
}
.user-name { color: #FFFFFF; font-weight: 700; }
.user-role { color: rgba(255,255,255,0.62); }
.logout-btn { color: rgba(255,255,255,0.62); }
.logout-btn:hover { color: #FFFFFF; }

/* ── TOPBAR · cleaner divider, brand-tinted accents ───────────── */
.topbar {
    border-bottom: 1px solid var(--color-border);
    box-shadow: 0 1px 0 var(--color-border), 0 0 transparent;
    backdrop-filter: saturate(140%);
}
.topbar-title {
    font-style: normal;
    font-weight: 800;
    letter-spacing: -0.3px;
}
.breadcrumb { font-weight: 500; }

.date-chip {
    background: var(--color-primary-soft);
    border: 1px solid transparent;
    color: var(--color-primary);
    font-weight: 700;
    font-family: var(--font-body);
}

.btn-new {
    background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
    color: #FFFFFF;
    border-radius: 12px;
    padding: 9px 20px;
    box-shadow: 0 4px 12px color-mix(in srgb, var(--color-primary) 28%, transparent);
    font-weight: 700;
    transition: transform 0.12s, box-shadow 0.12s;
}
.btn-new:hover {
    background: linear-gradient(135deg, var(--color-primary-hover), var(--color-primary));
    color: #FFFFFF;
    transform: translateY(-1px);
    box-shadow: 0 6px 16px color-mix(in srgb, var(--color-primary) 36%, transparent);
}

/* ── CARDS · borderless + soft shadow + bigger radius ─────────── */
.card {
    border: 1px solid transparent;
    border-radius: var(--radius-card, 16px);
    box-shadow: var(--shadow);
}
.card-header {
    border-bottom: 1px solid var(--border);
    padding: 16px 20px;
}
.card-title {
    font-style: normal;
    font-weight: 800;
    letter-spacing: -0.2px;
}

/* Stat / KPI cards */
.stat-card {
    border: 1px solid transparent;
    border-radius: var(--radius-card, 16px);
    box-shadow: var(--shadow);
    transition: transform 0.18s, box-shadow 0.18s;
}
.stat-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}
.stat-label {
    font-weight: 700;
    letter-spacing: 0.6px;
    color: var(--text-dim);
}
.stat-value {
    font-family: var(--font-body);
    font-weight: 800;
    letter-spacing: -0.5px;
    color: var(--text);
}
.stat-value.c-gold { color: var(--primary, var(--gold)); }
.stat-value.c-green { color: var(--green); }
.stat-value.c-red { color: var(--red); }
.stat-value.c-blue { color: var(--blue); }

/* ── BUTTONS · gradient primary, pill-friendly radii ──────────── */
.btn {
    border-radius: 12px;
    font-weight: 700;
    transition: transform 0.12s, box-shadow 0.12s, background 0.15s;
}
.btn-primary {
    background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
    color: #FFFFFF;
    box-shadow: 0 4px 12px color-mix(in srgb, var(--color-primary) 28%, transparent);
}
.btn-primary:hover {
    background: linear-gradient(135deg, var(--color-primary-hover), var(--color-primary));
    color: #FFFFFF;
    transform: translateY(-1px);
    box-shadow: 0 6px 16px color-mix(in srgb, var(--color-primary) 36%, transparent);
}
.btn-success {
    background: var(--green);
    box-shadow: 0 4px 12px rgba(16,185,129,0.24);
}
.btn-success:hover { background: #047857; }
.btn-danger {
    background: var(--red);
    box-shadow: 0 4px 12px rgba(239,68,68,0.24);
}
.btn-danger:hover { background: #B91C1C; }
.btn-ghost {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    color: var(--text);
    box-shadow: none;
}
.btn-ghost:hover {
    background: var(--color-primary-soft);
    border-color: var(--color-primary);
    color: var(--color-primary);
}

/* ── FORM FIELDS · violet focus ring ──────────────────────────── */
input:focus, select:focus, textarea:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
}

/* ── SECTION TITLE · subtle violet underline, no italic ───────── */
.section-title {
    font-style: normal;
    font-weight: 800;
    letter-spacing: -0.2px;
    color: var(--text);
    border-bottom: 1px solid var(--color-border);
    padding-bottom: 10px;
    margin-bottom: 16px;
}

/* ── STATUS PILLS · keep semantic colors, refine padding ─────── */
.status {
    padding: 4px 11px;
    font-weight: 700;
    letter-spacing: 0.4px;
}

/* ── TABLE · softer header band, hover violet tint ────────────── */
thead th {
    background: var(--surface2);
    color: var(--text-dim);
    font-weight: 700;
    letter-spacing: 0.6px;
}
tbody tr:hover {
    background: color-mix(in srgb, var(--color-primary) 6%, transparent);
}
.td-mono {
    color: var(--color-primary);
    font-weight: 700;
}
.td-mono a { color: var(--color-primary); }

/* ── CHIPS · keep semantic, tweak padding/letter ──────────────── */
.chip {
    padding: 3px 10px;
    font-weight: 700;
    letter-spacing: 0.4px;
}
.chip-gold {
    background: var(--gold-bg);
    color: var(--primary, var(--gold-dark));
}

/* ── CALC BOX · tinted violet panel ───────────────────────────── */
.calc-box {
    background: var(--color-primary-soft);
    border: 1px solid transparent;
    border-radius: var(--radius-card, 16px);
}
.calc-row {
    border-bottom: 1px dashed color-mix(in srgb, var(--color-primary) 24%, transparent);
}
.calc-val {
    color: var(--color-primary);
    font-family: var(--font-body);
    font-weight: 700;
}

/* ── ALERTS · use border-left accent rather than full border ──── */
.alert {
    border-radius: var(--radius);
    border: none;
    border-left: 4px solid currentColor;
    padding: 14px 16px;
    background: var(--surface);
    box-shadow: var(--shadow);
}
.alert-gold {
    color: var(--primary);
    background: var(--color-primary-soft);
}
.alert-green {
    color: var(--green);
    background: var(--green-bg);
}

/* ── DASH HERO (optional helper for FinPay-style banners) ─────── */
.dash-hero {
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-accent) 100%);
    border-radius: 20px;
    padding: 26px 30px;
    color: #FFFFFF;
    box-shadow: var(--shadow-hero);
    position: relative;
    overflow: hidden;
    margin-bottom: 22px;
}
.dash-hero::after {
    content: '';
    position: absolute;
    top: -80px;
    right: -60px;
    width: 280px;
    height: 280px;
    border-radius: 50%;
    background: rgba(255,255,255,0.10);
    pointer-events: none;
}
.dash-hero::before {
    content: '';
    position: absolute;
    bottom: -160px;
    right: 100px;
    width: 320px;
    height: 320px;
    border-radius: 50%;
    background: rgba(255,255,255,0.06);
    pointer-events: none;
}
.dash-hero > * { position: relative; z-index: 2; }
.dash-hero .dh-label {
    font-size: 11px;
    font-weight: 700;
    opacity: 0.9;
    text-transform: uppercase;
    letter-spacing: 0.7px;
    margin-bottom: 6px;
}
.dash-hero .dh-amount {
    font-size: 36px;
    font-weight: 800;
    letter-spacing: -0.8px;
    line-height: 1;
    margin-bottom: 6px;
}
.dash-hero .dh-delta { font-size: 13px; opacity: 0.92; }
.dash-hero .dh-delta .up { color: #6EE7B7; font-weight: 800; }

/* ── DARK-MODE TUNING ─────────────────────────────────────────── */
:root[data-color-mode="dark"] .card,
:root[data-color-mode="dark"] .stat-card {
    border-color: var(--border);
}
:root[data-color-mode="dark"] .topbar { background: var(--surface); }
:root[data-color-mode="dark"] .btn-ghost {
    background: var(--surface2);
    color: var(--text);
}
:root[data-color-mode="dark"] tbody tr:hover {
    background: color-mix(in srgb, var(--color-primary) 14%, transparent);
}

/* ── REDUCED MOTION ────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .stat-card, .btn, .btn-primary, .btn-new {
        transition: none;
    }
    .stat-card:hover, .btn-primary:hover, .btn-new:hover {
        transform: none;
    }
}

/* ════════════════════════════════════════════════════════════════
   Control alignment patch — uniform field height, label rhythm,
   grid gap, button sizing, and section spacing across every form.
   No markup changes; this section wins the cascade by sitting at
   the bottom of site.css.
   ════════════════════════════════════════════════════════════════ */

:root {
    --ctl-h:        40px;
    --ctl-h-sm:     32px;
    --ctl-h-lg:     48px;
    --ctl-px:       14px;
    --ctl-radius:   10px;
    --label-mb:     6px;
    --field-mb:     16px;
    --grid-gap:     16px;
    --section-gap:  20px;
    --section-pad-x: 22px;
    --section-pad-y: 18px;
}

/* ── FORM CONTROLS — every input/select/textarea same height + look ── */
input[type="text"],
input[type="number"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="search"],
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"],
input[type="week"],
input[type="url"],
select {
    height: var(--ctl-h);
    padding: 0 var(--ctl-px);
    border-radius: var(--ctl-radius);
    font-size: 14px;
    line-height: 1.4;
    border: 1.5px solid var(--color-border);
    background: var(--color-surface);
    color: var(--text);
    font-family: var(--font-body);
    width: 100%;
    box-sizing: border-box;
    transition: border-color 0.15s, box-shadow 0.15s;
}

textarea {
    min-height: calc(var(--ctl-h) * 2);
    padding: 10px var(--ctl-px);
    border-radius: var(--ctl-radius);
    font-size: 14px;
    line-height: 1.5;
    border: 1.5px solid var(--color-border);
    background: var(--color-surface);
    color: var(--text);
    font-family: var(--font-body);
    width: 100%;
    box-sizing: border-box;
    resize: vertical;
}

/* Native select chevron — manual draw so it doesn't drift */
select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 36px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5l3 3 3-3' stroke='%236B7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 12px 12px;
}

/* Date inputs — clean up native pickers */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
    cursor: pointer;
    opacity: 0.55;
    transition: opacity 0.15s;
}
input[type="date"]:hover::-webkit-calendar-picker-indicator,
input[type="time"]:hover::-webkit-calendar-picker-indicator {
    opacity: 1;
}

input::placeholder, textarea::placeholder { color: var(--ink-dim); }

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
}

input:disabled, select:disabled, textarea:disabled {
    background: var(--bg);
    color: var(--ink-muted);
    cursor: not-allowed;
}

/* ── LABELS — uniform sizing + rhythm ───────────────────────────── */
label {
    display: block;
    font-size: 11px;
    font-weight: 700;
    color: var(--ink-dim);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin-bottom: var(--label-mb);
    line-height: 1.4;
}

/* Required marker */
label .req,
label .text-danger,
.required-mark { color: var(--color-danger); font-weight: 700; margin-left: 2px; }

/* Inline help next to a label */
label .help,
label .hint-inline {
    color: var(--ink-muted);
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    font-size: 11px;
    margin-left: 6px;
}

/* ── FORM GROUP (.fg) — consistent vertical rhythm ──────────────── */
.fg {
    display: flex;
    flex-direction: column;
    gap: 0;
    min-width: 0;
    margin-bottom: 0;
}

.fg label { margin-bottom: var(--label-mb); }

.fg .hint,
.fg .field-hint,
.fg small {
    font-size: 11px;
    color: var(--ink-muted);
    margin-top: 6px;
    line-height: 1.45;
}

.fg .text-danger {
    font-size: 11px;
    color: var(--color-danger);
    margin-top: 6px;
    font-weight: 600;
    line-height: 1.4;
}

/* Span across full grid row when needed */
.fg.full,
.fg.span-all { grid-column: 1 / -1; }

/* ── GRID GAPS — col-N consistent across the app ────────────────── */
.col-2,
.col-3,
.col-4 {
    display: grid;
    gap: var(--grid-gap) calc(var(--grid-gap) + 2px);
    align-items: start;
}
.col-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.col-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.col-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Mobile collapse — re-applied AFTER the col-N redefinitions above so it actually wins */
@media (max-width: 768px) {
    .col-2, .col-3, .col-4 { grid-template-columns: 1fr; }
}

/* col-N children inherit the field gap when stacked */
.col-2 > .fg + .fg,
.col-3 > .fg + .fg,
.col-4 > .fg + .fg { margin-top: 0; }

/* When .fg sits outside a grid (single column), keep field rhythm */
.card-body > .fg + .fg,
.card-body > * + .fg,
form > .fg + .fg { margin-top: var(--field-mb); }

/* ── BUTTONS — same height as inputs, no taller text ────────────── */
.btn {
    height: var(--ctl-h);
    padding: 0 18px;
    line-height: 1;
    align-items: center;
    border-radius: var(--ctl-radius);
}
.btn-sm  { height: var(--ctl-h-sm); padding: 0 12px; font-size: 12.5px; border-radius: 8px; }
.btn-lg  { height: var(--ctl-h-lg); padding: 0 22px; font-size: 14.5px; border-radius: 12px; }
.btn-xs  { height: 26px; padding: 0 9px; font-size: 11.5px; border-radius: 7px; }

/* Buttons inside a .btn-row — uniform gap */
.btn-row {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
    margin-top: var(--field-mb);
}

/* Form-action footer (sticky save bar pattern) */
.form-actions,
.action-bar {
    display: flex;
    align-items: center;
    gap: 10px;
}
.form-actions .btn + .btn,
.action-bar .btn + .btn { margin-left: 0; }

/* ── CARD HEADER + BODY — consistent padding ────────────────────── */
.card-header {
    padding: var(--section-pad-y) var(--section-pad-x);
    align-items: center;
}
/* Was a hardcoded 22px 24px — didn't match the header's own tokens two
   lines up despite the comment above claiming "consistent padding". */
.card-body { padding: var(--section-pad-y) var(--section-pad-x); }
.card-body.p0 { padding: 0; }
.card-body > .col-2,
.card-body > .col-3,
.card-body > .col-4 { margin-bottom: 0; }
.card-body > .col-2 + .col-2,
.card-body > .col-3 + .col-3,
.card-body > .col-4 + .col-4,
.card-body > .col-2 + .col-3,
.card-body > .col-3 + .col-2,
.card-body > .col-4 + .col-2 { margin-top: var(--section-gap); }

/* ── SECTION TITLE — uniform heading rhythm ─────────────────────── */
.section-title {
    font-size: 14px;
    font-weight: 800;
    letter-spacing: -0.1px;
    color: var(--text);
    margin: 0 0 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--color-border);
    font-style: normal;
    font-family: var(--font-body);
    text-transform: none;
    display: flex;
    align-items: center;
    gap: 8px;
}
.section-title + .col-2,
.section-title + .col-3,
.section-title + .col-4 { margin-top: 0; }

/* Sections that follow each other inside a card */
.section-title:not(:first-child) { margin-top: var(--section-gap); }

/* ── CHECKBOX / RADIO — vertically centered with labels ─────────── */
input[type="checkbox"],
input[type="radio"] {
    width: 16px;
    height: 16px;
    accent-color: var(--color-primary);
    margin: 0;
    cursor: pointer;
    flex-shrink: 0;
    vertical-align: middle;
}

/* Inline label-with-checkbox pattern */
label.inline,
label.checkbox-label,
.inline-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text);
    text-transform: none;
    letter-spacing: 0;
    margin-bottom: 0;
    cursor: pointer;
}

/* ── INPUT PREFIX/SUFFIX — uniform inline layout ───────────────── */
.input-prefix,
.input-suffix,
.input-group-inline {
    display: inline-flex;
    align-items: stretch;
    border: 1.5px solid var(--color-border);
    border-radius: var(--ctl-radius);
    background: var(--color-surface);
    overflow: hidden;
    width: 100%;
    height: var(--ctl-h);
}
.input-prefix:focus-within,
.input-suffix:focus-within,
.input-group-inline:focus-within {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 18%, transparent);
}
.input-prefix > input,
.input-suffix > input,
.input-group-inline > input {
    border: none;
    box-shadow: none;
    height: auto;
    padding: 0 var(--ctl-px);
    flex: 1;
    background: transparent;
    border-radius: 0;
}
.input-prefix > input:focus,
.input-suffix > input:focus,
.input-group-inline > input:focus { box-shadow: none; }
.input-prefix > .pre,
.input-suffix > .suf {
    display: flex;
    align-items: center;
    padding: 0 12px;
    background: var(--surface-2);
    color: var(--ink-muted);
    font-size: 12.5px;
    font-weight: 700;
    border-right: 1px solid var(--color-border);
}
.input-suffix > .suf { border-right: none; border-left: 1px solid var(--color-border); }

/* ── SEARCH ROW (filters above tables) — vertical alignment ─────── */
.search-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 8px 12px;
    margin-bottom: 10px;
}
.search-row > input,
.search-row > select,
.search-row > .search-inp,
.search-row > .filter-sel,
.search-row .btn { height: var(--ctl-h); margin: 0; }
.search-row > input,
.search-row > .search-inp { flex: 1; min-width: 220px; }
.search-row form { gap: 8px !important; row-gap: 8px !important; }
.search-row .fg { margin-bottom: 0 !important; }
.search-row .fg label { margin-bottom: 0; padding-right: 4px; white-space: nowrap; }

/* ── ALERTS — content alignment ─────────────────────────────────── */
/* Deliberately NOT display:flex. Alerts here are prose containing inline
   <strong>/<a>, so flex would make every element and every run of text its
   own flex item and space them apart — shredding the sentence and orphaning
   the punctuation that follows an element. Keep them block-level. */
.alert {
    padding: 14px 18px;
    line-height: 1.5;
}

/* ── KPI / STAT CARDS — consistent inner rhythm ─────────────────── */
.stat-card,
.kpi-card {
    padding: 18px 20px;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 10px;
    min-height: 96px;
}
.stat-card .stat-label,
.kpi-card .kpi-label {
    margin: 0;
    font-size: 11px;
    font-weight: 700;
    color: var(--ink-dim);
    text-transform: uppercase;
    letter-spacing: 0.6px;
}
.stat-card .stat-value,
.kpi-card .kpi-value {
    margin: 0;
    font-size: 26px;
    font-weight: 800;
    letter-spacing: -0.5px;
    line-height: 1.05;
}

/* ── STATUS PILLS — center the dot/text properly ────────────────── */
.status,
.chip,
.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    line-height: 1;
    height: 22px;
    padding: 0 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.4px;
    white-space: nowrap;
}
.status::before { margin: 0; flex-shrink: 0; }

/* ── TABLE CELLS — vertical alignment + uniform padding ─────────── */
table { border-collapse: separate; border-spacing: 0; }
thead th,
tbody td {
    vertical-align: middle;
    padding: 12px 14px;
}
thead th { padding-top: 11px; padding-bottom: 11px; }

/* Numeric cells right-aligned with tabular numerals */
td.num, th.num,
td.right, th.right {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* ── TWO-PANE FORMS — even gutter and column rhythm ─────────────── */
.two-pane {
    align-items: flex-start;
    gap: 20px;
}
.two-pane > .pane-form .card,
.two-pane > .pane-preview > .card { margin-bottom: 16px; }
.two-pane > .pane-preview > .card:last-child { margin-bottom: 0; }

/* ── PAGE HEADER — title row consistent baseline ────────────────── */
.page-head,
.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}
.page-head > .actions,
.page-header > .actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
}

/* ── TWO-PANE SUMMARY ROWS (already styled but tighten alignment) */
.preview-row {
    align-items: center;
    gap: 12px;
    padding: 8px 0;
}
.preview-row .v {
    font-variant-numeric: tabular-nums;
    text-align: right;
    margin-left: auto;
}

/* ── SUB-PIXEL FIX FOR SAFARI/EDGE BORDER OFFSET ────────────────── */
.fg input,
.fg select,
.fg textarea { box-sizing: border-box; }

/* ════════════════════════════════════════════════════════════════
   COMMON PADDING / FORM-CARD CLEANUP — final cascade pass
   Keeps every form / list page visually aligned regardless of which
   author wrote it. Sits at the very bottom so it wins specificity.
   ════════════════════════════════════════════════════════════════ */

/* 1 ── Page wrapper: consistent inner padding everywhere */
.page {
    padding: 22px 28px;
    min-height: calc(100vh - var(--topbar-height, 56px));
}
@media (max-width: 768px) { .page { padding: 16px 14px; } }

/* 2 ── Form cards: expand to fill the full content area instead of
       sitting as a narrow ribbon with a sea of empty space on the right.
       View authors set inline `max-width:NNNpx` (480/520/600/680/720/780/
       820/860/880/900) — all are overridden here so cards use 100% of
       what `.page` allocates. The `.page` wrapper already adds 28px
       horizontal padding, which keeps the content from touching the
       viewport edge.

       Inner form layout (.col-2 / .form-grid) still controls column
       count, so individual inputs never become absurdly wide — they
       just get more breathing room and the right side of the page
       stops looking empty. */
.page > .card[style*="max-width:"],
.page > .card[style*="max-width :"],
.page > form[style*="max-width:"],
.page > div[style*="max-width:"] { max-width: none !important; width: 100%; }
/* Page-level wrappers that nest the card inside their own div */
.page > div > .card[style*="max-width:"],
.page > div > form[style*="max-width:"] { max-width: none !important; width: 100%; }

/* 3 ── Card body: uniform inner padding (cards built without .card-body
       wrapper still get breathing room) */
.page > .card { padding: 20px 22px; }
.page > .card .card-header,
.page > .card .card-hdr { margin: -20px -22px 14px; padding: 14px 22px; }
.page > .card > form { margin: 0; }

/* 3a ── A card whose ONLY child is its header — the page-banner shape
   `<div class="card"><div class="card-header">…</div></div>`, used as a title strip
   by all four CGT screens among others.

   Rule 3 above gives the header a 14px bottom margin for the body that follows it,
   and `.page > .card` still adds its own 20px bottom padding underneath. With NO
   body those two become ~35px of empty, BORDERED white space hanging below the
   header's bottom rule — measured at 34.8px on /Cgt/Register, 2026-09-29 — which
   reads as a panel whose contents failed to load rather than as a page title.
   It builds, it renders and nothing logs; the only way to see it is to look.

   Pull the card's bottom padding back so the card ends ON the header's border.
   Scoped with `>` and `:last-child`, so a card that HAS a body is untouched. */
.page > .card > .card-header:last-child,
.page > .card > .card-hdr:last-child { margin-bottom: -20px; }

/* 4 ── Eliminate accidental yellow/gold left-borders on plain cards
       (some legacy authors used border-left:4px solid var(--gold) as a
       cheap accent — that fires on top of inputs and looks like a stripe). */
.page > .card:not([class*="alert"]):not([class*="warning"]):not([class*="hero"]) {
    border-left-width: 1px !important;
}

/* 5 ── Form rows: consistent column rhythm.
       Use flex-basis 0 so inline `style="flex:2"` from view authors actually
       gets 2× the share. Wraps cleanly via the @media rule below when the
       parent column is too narrow for two side-by-side inputs. */
/* `.form-row` keeps its flex behaviour so view authors can use inline
   `style="flex:N"` on children to set custom column widths.
   `.col-2` is intentionally NOT in this rule — it must remain a true
   2-column GRID (defined earlier in this stylesheet) so forms with
   many .fg children render two-up rather than cramming all fields
   into a single squashed row. */
.form-row {
    display: flex;
    gap: var(--grid-gap, 16px);
    flex-wrap: wrap;
    margin-bottom: var(--field-mb, 16px);
}
.form-row > .form-field,
.form-row > .fg {
    flex: 1 1 0;       /* equal share by default; inline flex:N overrides grow */
    min-width: 0;      /* allow shrinking when needed */
}
@media (max-width: 640px) {
    .form-row > .form-field,
    .form-row > .fg {
        flex: 1 1 100%;
    }
}
/* `.col-full` spans the whole row regardless of how many columns
   `.col-2` resolves to (1 / 2 / 3 / 4 depending on viewport). */
.col-2 > .col-full,
.col-2 > .fg.col-full { grid-column: 1 / -1; }

/* Auto-fit grid: with Option B in effect, form cards span the full
   page width (~1500px on 1080p, ~1080px on 1366), so an inflexible
   2-column layout would still leave huge gaps. Switch `.col-2` to
   auto-fit with a 360px minimum track size — yields:
     · 4 columns at ~1500px (full HD desktop)
     · 3 columns at ~1100px (1366 laptop)
     · 2 columns at ~750px  (small laptop / split screen)
     · 1 column  at ~380px  (mobile)
   Auto-fit collapses empty tracks, so a 2-field form on a wide card
   becomes 2 columns of ~750px each (input cap below keeps it sane).
   This rule wins because it's later in the stylesheet than the
   earlier `.col-2 { grid-template-columns: repeat(2, minmax(0,1fr)) }`
   declarations. */
.col-2 { grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); }

/* Cap individual input width so on a 2-column-fallback (each column
   ~700px) a phone/pincode field doesn't stretch absurdly wide. The
   field group keeps its full column allocation; only the input/select
   inside is bounded. Textareas and full-span fields stay 100%. */
.col-2 > .fg > input,
.col-2 > .fg > select,
.col-3 > .fg > input,
.col-3 > .fg > select { max-width: 540px; }
.col-2 > .fg > textarea,
.col-2 > .col-full > input,
.col-2 > .col-full > select,
.col-2 > .col-full > textarea,
.col-2 > .fg.col-full > input,
.col-2 > .fg.col-full > select,
.col-2 > .fg.col-full > textarea { max-width: none; }

/* On narrower viewports the @media rule at site.css:2152 already
   collapses .col-2 to a single column — that still applies because
   it's a media query and our auto-fit rule is non-media (specificity
   ties at media > non-media within the cascade). */

/* 6 ── Page header: even spacing above first card */
.page > .page-hdr,
.page > .page-header { margin-bottom: 18px; }

/* 7 ── List/table cards: same outer rhythm as form cards */
.page > .card .tbl-wrap { margin: 0 -22px -20px; }
.page > .card .tbl-wrap table { width: 100%; }
.page > .card .tbl-wrap table th:first-child,
.page > .card .tbl-wrap table td:first-child { padding-left: 22px; }
.page > .card .tbl-wrap table th:last-child,
.page > .card .tbl-wrap table td:last-child  { padding-right: 22px; }

/* 7a ── .card-flush — a card that has ALREADY zeroed its own padding.
   ⚠ The two bleed rules above (and `.page > .card .card-hdr` in section 4)
   pull their child OUTWARDS with negative margins to cancel the card's default
   20px/22px padding, so the header band and the table span the full card width.
   On a card written `style="padding:0;overflow:hidden"` there is no padding to
   cancel — so the header is dragged 22px LEFT and 20px ABOVE the card, the
   table 22px left and 20px BELOW it, and the card's own `overflow:hidden`
   silently CLIPS all four edges.

   What that looks like in the wild (MfiGroupBatch/Review, reported 2026-09-22):
   the roster heading rendered as "embers in this batch (1)" with the M cut off,
   and the tfoot "Batch total ₹10,000" was sliced in half by the card's bottom
   edge — a figure someone reconciles against, unreadable, with no error and
   nothing in the markup to suggest why.

   Add .card-flush to ANY card that sets its own padding to 0. Find them with:
     grep -rn 'class="card"[^>]*padding:0' Views/ --include=*.cshtml
   (28 such views at the time of writing — most do not contain a .card-hdr or a
   .tbl-wrap and so are unaffected, but every one of them is one added header
   away from this.) */
.page > .card.card-flush > .card-hdr { margin: 0; }
.page > .card.card-flush .tbl-wrap   { margin: 0; }

/* 7b ── .tbl-entry — a DATA-ENTRY grid sitting INSIDE a form, which is a
   different thing from a list card whose body IS the table.

   Rule 7 above bleeds a .tbl-wrap out to the card's edges and pulls the
   card's bottom padding back with `-20px`. That is right when nothing
   follows the table. Mid-form all three effects are wrong, and all three
   were measured on /Loan/Amend (gold ornament grid, 2026-09-18):

     • the ±22px bleed pushes the first and last columns out under the
       card padding, so `ITEM TYPE` renders clipped;
     • the -20px drags the NEXT block up by 20px — the hint paragraph
       under the grid was printing ON TOP of the table's own horizontal
       scrollbar (gap measured at -10px);
     • a 14px-padded control inside a 14px-padded cell spends 28px of a
       64-96px column on padding, so the column CLIPS ITS OWN VALUE:
       `17.072` needed 86px in a 72px box (rendered "17.C"), and a 64px
       Pcs column left SIX pixels of content box, so a value of 1 read
       as an empty field.

   Compacting the cell to 8px and the control to 10px buys back 12px per
   column — ~144px across a 12-column grid — so the values fit AND the
   grid scrolls less than it did before.

   table-scroll-helper.js also leaves a .tbl-entry's floating ‹ › arrows
   off: every cell here is a control, so a 42px button has nowhere to sit
   that is not on top of one. It was covering the ✕ remove-ornament button
   outright — elementFromPoint over that ✕ returned the arrow, not the ✕.
   Wheel, shift+wheel, trackpad swipe and the native scrollbar all still
   scroll the grid. */
.page > .card .tbl-wrap.tbl-entry { margin: 0; }

.tbl-entry > table > thead > tr > th,
.tbl-entry > table > tbody > tr > td { padding-left: 8px; padding-right: 8px; }

.page > .card .tbl-wrap.tbl-entry table th:first-child,
.page > .card .tbl-wrap.tbl-entry table td:first-child { padding-left: 12px; }
.page > .card .tbl-wrap.tbl-entry table th:last-child,
.page > .card .tbl-wrap.tbl-entry table td:last-child  { padding-right: 12px; }

/* The control keeps enough right padding for the number spinner Chrome
   overlays on hover — a right-aligned digit under it is the same defect
   in a smaller coat. */
.tbl-entry > table > tbody > tr > td > input { padding-left: 10px; padding-right: 10px; }

/* 8 ── Focus outline: cleaner, keeps inside the field instead of bleeding out */
.inp:focus,
input:focus,
select:focus,
textarea:focus {
    outline: 2px solid var(--color-primary, #5B45D9);
    outline-offset: -1px;
    border-color: var(--color-primary, #5B45D9);
}

/* ════════════════════════════════════════════════════════════════
   USER WIDGET (top-right of every authenticated page)
   ════════════════════════════════════════════════════════════════ */
.user-widget { position: relative; margin-left: 8px; }

.user-widget-btn {
    display: flex; align-items: center; gap: 10px;
    padding: 5px 10px 5px 5px;
    background: var(--color-bg, #F5F6FA);
    border: 1px solid var(--color-border, #E5E7EB);
    border-radius: 999px;
    cursor: pointer;
    transition: all .15s;
    font-family: inherit;
}
.user-widget-btn:hover { border-color: var(--color-primary, #5B45D9); background: #fff; }

.uw-avatar {
    width: 32px; height: 32px; border-radius: 999px;
    background: linear-gradient(135deg, #5B45D9, #7B61FF);
    display: grid; place-items: center;
    color: #fff; font-weight: 700; font-size: 12px; letter-spacing: .3px;
    flex-shrink: 0;
}
.uw-avatar.lg { width: 46px; height: 46px; font-size: 16px; }

.uw-meta { text-align: left; line-height: 1.2; min-width: 0; }
.uw-name { font-weight: 600; font-size: 13px; color: var(--color-ink-strong, #0F172A); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 160px; }
.uw-role { font-size: 11px; color: var(--color-ink-muted, #64748B); display: flex; align-items: center; gap: 6px; }
.uw-role > span:first-child { white-space: nowrap; }

.uw-pill {
    font-size: 9.5px; font-weight: 700; letter-spacing: .4px;
    padding: 1px 6px; border-radius: 999px; text-transform: uppercase;
}
.uw-pill.sa { background: linear-gradient(135deg, #F59E0B, #FBBF24); color: #fff; }
.uw-pill.ho { background: #EEEAFE; color: #5B45D9; }
.uw-pill.br { background: #DBEAFE; color: #1D4ED8; }

.uw-caret {
    margin-left: 4px; font-size: 11px; color: var(--color-ink-muted, #64748B);
    transition: transform .15s;
}

/* Dropdown panel */
.user-menu {
    position: absolute; top: calc(100% + 8px); right: 0;
    width: 320px; max-width: 92vw;
    background: #fff;
    border: 1px solid var(--color-border, #E5E7EB);
    border-radius: 14px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, .12), 0 1px 3px rgba(15, 23, 42, .06);
    z-index: 1000;
    opacity: 0; pointer-events: none;
    transform: translateY(-6px) scale(.98);
    transition: opacity .15s, transform .15s;
    overflow: hidden;
}
.user-menu.open { opacity: 1; pointer-events: auto; transform: translateY(0) scale(1); }

.uw-header {
    display: flex; gap: 12px; align-items: center;
    padding: 16px 18px;
    background: linear-gradient(135deg, #F5F3FF 0%, #EEEAFE 100%);
    border-bottom: 1px solid var(--color-border, #E5E7EB);
}
.uw-h-name { font-weight: 700; font-size: 15px; color: var(--color-ink-strong, #0F172A); }
.uw-h-sub  { font-size: 11.5px; color: #5B45D9; margin-top: 2px; word-break: break-all; }

.uw-grid { padding: 12px 18px; border-bottom: 1px solid #F1F5F9; }
.uw-row {
    display: flex; justify-content: space-between; align-items: center;
    padding: 4px 0; font-size: 12.5px;
}
.uw-l { color: var(--color-ink-muted, #64748B); font-weight: 500; }
.uw-v { color: var(--color-ink, #0F172A); font-weight: 600; text-align: right; max-width: 200px; word-break: break-word; }

.uw-actions { padding: 8px; }
.uw-link {
    display: block; padding: 9px 12px; border-radius: 8px;
    font-size: 13px; color: var(--color-ink, #0F172A); text-decoration: none;
    transition: background .12s;
}
.uw-link:hover { background: #F5F3FF; color: #5B45D9; }

.uw-footer { padding: 8px; border-top: 1px solid #F1F5F9; background: #FAFBFC; }
.uw-logout {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px; border-radius: 8px;
    font-size: 13px; font-weight: 600; color: #B91C1C;
    text-decoration: none; transition: background .12s;
}
.uw-logout:hover { background: #FEE2E2; }

/* Compact mode for narrower viewports */
@media (max-width: 900px) {
    .uw-meta { display: none; }
    .uw-caret { display: none; }
    .user-widget-btn { padding: 4px; }
}

/* Dark mode (uses existing .dark class on <html> if app supports it) */
html.dark .user-widget-btn { background: #1F1B33; border-color: #ffffff20; }
html.dark .user-widget-btn:hover { background: #2A2543; }
html.dark .uw-name { color: #E2E8F0; }
html.dark .user-menu { background: #1F1B33; border-color: #ffffff20; box-shadow: 0 12px 32px rgba(0,0,0,.5); }
html.dark .uw-header { background: linear-gradient(135deg, #2A2543, #1F1B33); }
html.dark .uw-h-name { color: #fff; }
html.dark .uw-link { color: #CBD5E1; }
html.dark .uw-link:hover { background: #2A2543; color: #fff; }


/* ════════════════════════════════════════════════════════════════
   NOTIFICATION BELL (top-bar 🔔 — Approvals + Alerts tabs)
   Mirrors .user-menu's panel language so the two top-right dropdowns
   read as one family. Panel is wider (380px) because bell rows carry
   three lines; below 480px it goes full-bleed instead of overflowing.
   ════════════════════════════════════════════════════════════════ */
.nb-wrap { position: relative; }

.nb-btn {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 34px;
    background: var(--color-bg, #F5F6FA);
    border: 1px solid var(--color-border, #E5E7EB);
    border-radius: 8px;
    font-size: 16px; line-height: 1; cursor: pointer;
    transition: all .15s; font-family: inherit;
}
.nb-btn:hover { background: var(--color-primary-soft, #F5F3FF); border-color: var(--color-primary, #5B45D9); }
.nb-btn[aria-expanded="true"] { background: var(--color-primary-soft, #F5F3FF); border-color: var(--color-primary, #5B45D9); }

/* Badge — red when something is on THIS user's rung, slate when the
   count is only informational. Hidden entirely at zero (no "0" chip). */
.nb-badge {
    position: absolute; top: -6px; right: -6px;
    min-width: 18px; height: 18px; padding: 0 5px;
    border-radius: 999px;
    background: #64748B; color: #fff;
    font-size: 10px; font-weight: 800; line-height: 18px;
    text-align: center; letter-spacing: -.2px;
    border: 2px solid #fff;
    box-sizing: content-box;
}
.nb-badge.mine { background: #DC2626; }
.nb-badge[hidden] { display: none; }

/* Gentle one-shot pulse when the count grows — draws the eye without
   an animation that keeps running and becomes wallpaper. */
@keyframes nb-pulse { 0% { transform: scale(1); } 40% { transform: scale(1.35); } 100% { transform: scale(1); } }
.nb-badge.bump { animation: nb-pulse .45s ease-out; }

.nb-panel {
    position: absolute; top: calc(100% + 8px); right: 0;
    width: 380px; max-width: 92vw;
    background: #fff;
    border: 1px solid var(--color-border, #E5E7EB);
    border-radius: 14px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, .12), 0 1px 3px rgba(15, 23, 42, .06);
    z-index: 1000;
    opacity: 0; pointer-events: none;
    transform: translateY(-6px) scale(.98);
    transition: opacity .15s, transform .15s;
    overflow: hidden;
}
.nb-panel.open { opacity: 1; pointer-events: auto; transform: translateY(0) scale(1); }

.nb-tabs {
    display: flex; align-items: stretch;
    border-bottom: 1px solid var(--color-border, #E5E7EB);
    background: linear-gradient(135deg, #F5F3FF 0%, #EEEAFE 100%);
}
.nb-tab {
    flex: 1; padding: 11px 8px;
    background: none; border: none; border-bottom: 2px solid transparent;
    font-family: inherit; font-size: 12.5px; font-weight: 600;
    color: var(--color-ink-muted, #64748B);
    cursor: pointer; transition: color .12s, border-color .12s;
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.nb-tab:hover { color: var(--color-ink-strong, #0F172A); }
.nb-tab[aria-selected="true"] { color: #5B45D9; border-bottom-color: #5B45D9; }
.nb-tab .ct {
    font-size: 10px; font-weight: 800; padding: 1px 6px; border-radius: 999px;
    background: #E2E8F0; color: #475569;
}
.nb-tab[aria-selected="true"] .ct { background: #5B45D9; color: #fff; }
.nb-tab .ct[hidden] { display: none; }

.nb-list { max-height: 60vh; overflow-y: auto; overscroll-behavior: contain; }

/* Row = link + dismiss button as SIBLINGS (a <button> inside an <a> is invalid
   content model and gives the row two competing activation targets). */
.nb-item {
    display: flex; align-items: flex-start;
    padding-right: 8px;
    border-bottom: 1px solid #F1F5F9;
    border-left: 3px solid transparent;
    transition: background .12s;
}
.nb-item:hover { background: #F8FAFC; }
.nb-item.sev-high     { border-left-color: #F59E0B; }
.nb-item.sev-critical { border-left-color: #DC2626; }

.nb-link {
    flex: 1; min-width: 0;
    display: flex; gap: 10px; align-items: flex-start;
    padding: 11px 4px 11px 11px;
    text-decoration: none; color: inherit;
}
.nb-link:focus-visible { outline: 2px solid #5B45D9; outline-offset: -2px; border-radius: 4px; }

.nb-ic { font-size: 16px; line-height: 1.3; flex-shrink: 0; }
.nb-body { min-width: 0; flex: 1; }
.nb-title {
    font-size: 12.5px; font-weight: 700;
    color: var(--color-ink-strong, #0F172A);
    line-height: 1.35;
}
.nb-sub, .nb-meta {
    font-size: 11.5px; color: var(--color-ink-muted, #64748B);
    margin-top: 2px; line-height: 1.35;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nb-meta { font-variant-numeric: tabular-nums; }
.nb-age { font-size: 10.5px; color: #94A3B8; white-space: nowrap; flex-shrink: 0; margin-top: 1px; }

/* Per-row dismiss — client-side only (localStorage), never a DB write. */
.nb-x {
    border: none; background: none; cursor: pointer;
    color: #CBD5E1; font-size: 14px; line-height: 1;
    margin-top: 11px; padding: 3px 5px; border-radius: 4px; flex-shrink: 0;
    opacity: 0; transition: opacity .12s, color .12s, background .12s;
}
.nb-item:hover .nb-x { opacity: 1; }
.nb-x:hover { color: #DC2626; background: #FEE2E2; }
.nb-x:focus-visible { opacity: 1; outline: 2px solid #5B45D9; outline-offset: 1px; }

.nb-empty {
    padding: 40px 20px; text-align: center;
    font-size: 12.5px; color: var(--color-ink-muted, #64748B);
}
.nb-empty .ic { display: block; font-size: 30px; opacity: .35; margin-bottom: 8px; }

.nb-warn {
    padding: 9px 14px; font-size: 11.5px;
    background: #FEF3C7; color: #92400E; border-bottom: 1px solid #FDE68A;
}

.nb-foot {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    padding: 8px 12px; border-top: 1px solid #F1F5F9; background: #FAFBFC;
}
.nb-foot a, .nb-foot button {
    font-size: 12px; font-weight: 600; color: #5B45D9;
    text-decoration: none; background: none; border: none;
    cursor: pointer; font-family: inherit; padding: 4px 6px; border-radius: 6px;
}
.nb-foot a:hover, .nb-foot button:hover { background: #F5F3FF; }

@media (max-width: 480px) {
    .nb-panel { position: fixed; top: 56px; right: 8px; left: 8px; width: auto; max-width: none; }
}

html.dark .nb-btn { background: #1F1B33; border-color: #ffffff20; }
html.dark .nb-btn:hover,
html.dark .nb-btn[aria-expanded="true"] { background: #2A2543; border-color: #7B61FF; }
html.dark .nb-badge { border-color: #1F1B33; }
html.dark .nb-panel { background: #1F1B33; border-color: #ffffff20; box-shadow: 0 12px 32px rgba(0,0,0,.5); }
html.dark .nb-tabs { background: linear-gradient(135deg, #2A2543, #1F1B33); border-bottom-color: #ffffff20; }
html.dark .nb-tab { color: #94A3B8; }
html.dark .nb-tab:hover { color: #E2E8F0; }
html.dark .nb-tab[aria-selected="true"] { color: #A78BFA; border-bottom-color: #A78BFA; }
html.dark .nb-tab .ct { background: #3A3454; color: #CBD5E1; }
html.dark .nb-tab[aria-selected="true"] .ct { background: #7B61FF; color: #fff; }
html.dark .nb-item { border-bottom-color: #ffffff12; }
html.dark .nb-item:hover { background: #2A2543; }
html.dark .nb-title { color: #E2E8F0; }
html.dark .nb-sub, html.dark .nb-meta { color: #94A3B8; }
html.dark .nb-foot { background: #191527; border-top-color: #ffffff12; }
html.dark .nb-foot a, html.dark .nb-foot button { color: #A78BFA; }
html.dark .nb-foot a:hover, html.dark .nb-foot button:hover { background: #2A2543; }
html.dark .nb-warn { background: #3A2E12; color: #FCD34D; border-bottom-color: #ffffff20; }
html.dark .nb-x:hover { color: #FCA5A5; background: #4A1D1D; }


/* ── File input styling ─────────────────────────────────────────── */
input[type="file"] {
    cursor: pointer;
    border: 1px dashed var(--border, #d1d5db);
    border-radius: 6px;
    padding: 6px 8px;
    background: var(--surface2, #f9fafb);
    width: 100%;
    font-size: 12px;
    color: var(--text-muted, #6b7280);
    box-sizing: border-box;
}
input[type="file"]:hover {
    border-color: var(--primary, #1a5276);
    background: var(--surface, #fff);
}
input[type="file"]::file-selector-button {
    background: var(--primary, #1a5276);
    color: #fff;
    border: none;
    padding: 4px 12px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    font-weight: 500;
    margin-right: 10px;
    transition: opacity .15s;
}
input[type="file"]::file-selector-button:hover {
    opacity: .85;
}

/* ── ERROR MESSAGE CONTEXT & VALIDATION HINTS (Phase 1.1) ────────── */

.form-error-context {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 10px 12px;
    background-color: #FEE2E2;
    border-left: 3px solid #EF4444;
    border-radius: 4px;
    font-size: 13px;
    color: #7F1D1D;
}

.form-error-context strong {
    display: block;
    font-weight: 600;
    color: #DC2626;
}

.form-error-context .error-hint {
    font-size: 12px;
    color: #9F1239;
    margin-top: 2px;
}

.form-error-context .error-recovery {
    font-size: 12px;
    color: #7F1D1D;
    margin-top: 4px;
    font-style: italic;
}

/* Field-level error state */
.form-group.has-error input,
.form-group.has-error textarea,
.form-group.has-error select {
    border-color: #EF4444 !important;
    background-color: #FEF2F2;
}

.form-group.has-error label {
    color: #DC2626;
    font-weight: 600;
}

/* Error tooltip on fields */
.field-error-tooltip {
    position: absolute;
    background-color: #DC2626;
    color: white;
    padding: 6px 8px;
    border-radius: 3px;
    font-size: 11px;
    margin-top: -25px;
    margin-left: 0;
    white-space: nowrap;
    z-index: 1000;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    pointer-events: none;
}

.field-error-tooltip::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 8px;
    border: 4px solid transparent;
    border-top-color: #DC2626;
}

/* Dark mode adjustments for error messages */
[data-color-mode="dark"] .form-error-context {
    background-color: #7F1D1D;
    border-left-color: #FCA5A5;
    color: #FEE2E2;
}

[data-color-mode="dark"] .form-error-context strong {
    color: #FCA5A5;
}

[data-color-mode="dark"] .form-error-context .error-hint {
    color: #FECACA;
}

[data-color-mode="dark"] .form-error-context .error-recovery {
    color: #FEE2E2;
}

[data-color-mode="dark"] .form-group.has-error input,
[data-color-mode="dark"] .form-group.has-error textarea,
[data-color-mode="dark"] .form-group.has-error select {
    border-color: #FCA5A5 !important;
    background-color: #5F1D1D;
}

[data-color-mode="dark"] .form-group.has-error label {
    color: #FCA5A5;
}

[data-color-mode="dark"] .field-error-tooltip {
    background-color: #FCA5A5;
    color: #1F2937;
}

[data-color-mode="dark"] .field-error-tooltip::after {
    border-top-color: #FCA5A5;
}

/* ── CALCULATION PREVIEW STYLING (Phase 1.2) ────────────────────── */

.calc-preview-panel {
    display: grid;
    gap: 12px;
    padding: 14px 16px;
    background: var(--surface0, #f5f6fa);
    border-left: 3px solid var(--primary, #5b45d9);
    border-radius: 6px;
    margin-top: 10px;
    font-size: 13px;
}

.calc-preview-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
}

.calc-preview-label {
    color: var(--text-muted, #6b7280);
    font-weight: 500;
    flex: 1;
}

.calc-preview-value {
    font-family: var(--font-mono, 'JetBrains Mono', monospace);
    font-size: 14px;
    font-weight: 600;
    color: var(--primary, #5b45d9);
    min-width: 120px;
    text-align: right;
}

.calc-preview-value.high {
    color: var(--red, #ef4444);
}

.calc-preview-value.good {
    color: var(--green, #10b981);
}

.calc-preview-hint {
    font-size: 11px;
    color: var(--text-muted, #6b7280);
    font-style: italic;
    margin-top: 4px;
}

.calc-preview-section {
    border-top: 1px solid var(--border, #e5e7eb);
    padding-top: 8px;
    margin-top: 8px;
}

.calc-preview-section:first-child {
    border-top: none;
    padding-top: 0;
    margin-top: 0;
}

/* Dark mode */
[data-color-mode="dark"] .calc-preview-panel {
    background: #2A2A38;
    border-left-color: #7B61FF;
}

[data-color-mode="dark"] .calc-preview-label {
    color: #A0A0B8;
}

[data-color-mode="dark"] .calc-preview-value {
    color: #7B61FF;
}

[data-color-mode="dark"] .calc-preview-value.high {
    color: #FCA5A5;
}

[data-color-mode="dark"] .calc-preview-value.good {
    color: #6EE7B7;
}

[data-color-mode="dark"] .calc-preview-section {
    border-top-color: #3A3A48;
}

/* ── ENHANCED FILE UPLOAD STYLING (Phase 1.3) ────────────────── */

.file-upload-wrapper {
    position: relative;
}

.file-drop-zone {
    position: relative;
    padding: 16px 12px;
    border: 2px dashed var(--border, #d1d5db);
    border-radius: 8px;
    background: var(--surface0, #f5f6fa);
    transition: all 0.2s ease;
    cursor: pointer;
}

.file-drop-zone input[type="file"] {
    cursor: pointer;
}

.file-drop-zone.drag-active {
    border-color: var(--primary, #5b45d9);
    background: rgba(91, 69, 217, 0.05);
    box-shadow: 0 0 0 3px rgba(91, 69, 217, 0.1);
}

.file-size-hint {
    font-size: 11px;
    color: var(--text-muted, #6b7280);
    margin-top: 6px;
    text-align: center;
}

.file-preview-container {
    margin-top: 12px;
}

.file-preview-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    background: var(--surface0, #f5f6fa);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 8px;
    position: relative;
}

.file-preview-img {
    width: 60px;
    height: 60px;
    object-fit: cover;
    border-radius: 6px;
}

.file-preview-icon {
    width: 60px;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 28px;
    background: rgba(91, 69, 217, 0.1);
    border-radius: 6px;
    flex-shrink: 0;
}

.file-preview-info {
    flex: 1;
    min-width: 0;
}

.file-preview-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--text, #1a1a2e);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.file-preview-size {
    font-size: 11px;
    color: var(--text-muted, #6b7280);
    margin-top: 2px;
}

.file-preview-remove {
    width: 28px;
    height: 28px;
    min-width: 28px;
    padding: 0;
    background: transparent;
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 50%;
    color: var(--text-muted, #6b7280);
    font-size: 14px;
    cursor: pointer;
    transition: all 0.15s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}

.file-preview-remove:hover {
    background: #FEE2E2;
    border-color: #EF4444;
    color: #EF4444;
}

.file-upload-error {
    padding: 12px 14px;
    background: #FEE2E2;
    border: 1px solid #EF4444;
    border-radius: 6px;
    color: #7F1D1D;
    font-size: 13px;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Dark mode */
[data-color-mode="dark"] .file-drop-zone {
    background: #2A2A38;
    border-color: #3A3A48;
}

[data-color-mode="dark"] .file-drop-zone.drag-active {
    border-color: #7B61FF;
    background: rgba(123, 97, 255, 0.1);
    box-shadow: 0 0 0 3px rgba(123, 97, 255, 0.15);
}

[data-color-mode="dark"] .file-size-hint {
    color: #A0A0B8;
}

[data-color-mode="dark"] .file-preview-item {
    background: #2A2A38;
    border-color: #3A3A48;
}

[data-color-mode="dark"] .file-preview-icon {
    background: rgba(123, 97, 255, 0.15);
}

[data-color-mode="dark"] .file-preview-name {
    color: #F5F5F7;
}

[data-color-mode="dark"] .file-preview-size {
    color: #A0A0B8;
}

[data-color-mode="dark"] .file-preview-remove {
    border-color: #3A3A48;
    color: #A0A0B8;
}

[data-color-mode="dark"] .file-preview-remove:hover {
    background: #7F1D1D;
    border-color: #FCA5A5;
    color: #FCA5A5;
}

[data-color-mode="dark"] .file-upload-error {
    background: #7F1D1D;
    border-color: #FCA5A5;
    color: #FEE2E2;
}

/* ── SPARKLINE STYLING (Phase 2.1) ──────────────────────────── */

.kpi-sparkline-container {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
}

.kpi-sparkline {
    flex: 1;
    height: 40px;
    min-width: 80px;
}

.kpi-sparkline svg {
    width: 100%;
    height: 100%;
}

.kpi-trend-indicator {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    font-weight: 600;
    padding: 2px 6px;
    border-radius: 4px;
    background: rgba(16, 185, 129, 0.1);
    color: var(--green, #10b981);
}

.kpi-trend-indicator.negative {
    background: rgba(239, 68, 68, 0.1);
    color: var(--red, #ef4444);
}

.kpi-trend-indicator.neutral {
    background: rgba(107, 114, 128, 0.1);
    color: var(--text-muted, #6b7280);
}

.kpi-trend-label {
    font-size: 10px;
    color: var(--text-muted, #6b7280);
    margin-top: 4px;
}

/* Dark mode */
[data-color-mode="dark"] .kpi-trend-indicator {
    background: rgba(110, 231, 183, 0.15);
    color: #6EE7B7;
}

[data-color-mode="dark"] .kpi-trend-indicator.negative {
    background: rgba(252, 165, 165, 0.15);
    color: #FCA5A5;
}

[data-color-mode="dark"] .kpi-trend-indicator.neutral {
    background: rgba(160, 160, 184, 0.15);
    color: #A0A0B8;
}

/* ── PERIOD-OVER-PERIOD COMPARISON (Phase 2.2) ──────────────────── */

.kpi-pop-badge {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 11px;
    font-weight: 700;
    padding: 2px 6px;
    border-radius: 3px;
    margin-left: 6px;
    font-variant-numeric: tabular-nums;
}

.kpi-pop-badge.positive {
    background: rgba(16, 185, 129, 0.15);
    color: #10b981;
}

.kpi-pop-badge.negative {
    background: rgba(239, 68, 68, 0.15);
    color: #ef4444;
}

.kpi-pop-badge.neutral {
    background: rgba(107, 114, 128, 0.15);
    color: #6b7280;
}

.kpi-pop-label {
    font-size: 9px;
    color: var(--text-muted, #6b7280);
    display: block;
    margin-top: 2px;
}

/* Dark mode */
[data-color-mode="dark"] .kpi-pop-badge.positive {
    background: rgba(110, 231, 183, 0.15);
    color: #6EE7B7;
}

[data-color-mode="dark"] .kpi-pop-badge.negative {
    background: rgba(252, 165, 165, 0.15);
    color: #FCA5A5;
}

[data-color-mode="dark"] .kpi-pop-badge.neutral {
    background: rgba(160, 160, 184, 0.15);
    color: #A0A0B8;
}

[data-color-mode="dark"] .kpi-pop-label {
    color: #A0A0B8;
}

[data-color-mode="dark"] .kpi-trend-label {
    color: #A0A0B8;
}

/* ══════════════════════════════════════════════════════════════════════
   SIDEBAR COLLAPSE / EXPAND  (icon rail)
   ──────────────────────────────────────────────────────────────────────
   State lives on <html class="sb-collapsed">, written by the pre-paint
   inline script in _Layout's <head> (localStorage key `sb-collapsed`) so
   a collapsed sidebar never flashes at full width during load.

   Desktop only. Below 769px the sidebar is the off-canvas hamburger
   drawer, so every rule below is inside a min-width query and the toggle
   handle is hidden.

   `!important` on the hide/centre rules is load-bearing: several sidebar
   rows (Dashboard Hub, Approvals, the greeting line) carry inline
   `style="display:flex;gap:9px;padding:9px 12px"` straight from the Razor
   markup, and inline styles outrank any selector without it.
   ══════════════════════════════════════════════════════════════════════ */

/* Handle straddling the sidebar's right edge.
   It CANNOT live inside .sidebar — that element sets `overflow: hidden`
   (site.css ~2755, clips the ::after ambient glow), which would clip a
   negatively-offset child. So it is a fixed-position sibling and its
   `left` tracks the sidebar width per breakpoint. */
.sb-rail-toggle {
    position: fixed;
    top: 74px;
    left: calc(var(--sidebar-w) - 13px);
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,0.20);
    background: var(--sidebar-bg, #0e1424);
    color: rgba(255,255,255,0.88);
    font-size: 12px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 320;                       /* above .sidebar (300) and .topbar (200) */
    box-shadow: 0 2px 8px rgba(0,0,0,0.35);
    opacity: 0.55;
    transition: left 0.18s ease, opacity 0.15s, background 0.15s, color 0.15s, transform 0.15s;
}

    .sb-rail-toggle:hover {
        opacity: 1;
        background: var(--sidebar-accent, #FBBF24);
        color: #18150f;
        transform: scale(1.10);
    }

    .sb-rail-toggle:focus-visible {
        opacity: 1;
        outline: 2px solid var(--sidebar-accent, #FBBF24);
        outline-offset: 2px;
    }

/* .sidebar itself narrows to 220px here (see the 960px block above) */
@media (max-width: 960px) {
    .sb-rail-toggle { left: calc(220px - 13px); }
}

@media (max-width: 768px) {
    .sb-rail-toggle { display: none; }
}

@media (min-width: 769px) {
    /* Scoped to desktop ON PURPOSE: a bare `.sidebar { transition }` at the
       end of this file would outrank the drawer's `transition: transform`
       in the 768px block (media queries add no specificity, so source order
       decides) and the mobile hamburger drawer would snap instead of slide. */
    .sidebar { transition: width 0.18s ease; }
    .main    { transition: margin-left 0.18s ease; }

    html.sb-collapsed .sidebar       { width: var(--sidebar-rail-w); }
    html.sb-collapsed .main          { margin-left: var(--sidebar-rail-w); }
    html.sb-collapsed .sb-rail-toggle { left: calc(var(--sidebar-rail-w) - 13px); }

    /* Anything that needs horizontal room simply goes away in rail mode. */
    html.sb-collapsed .sidebar .logo-text,
    html.sb-collapsed .sidebar .tenant-badge,
    html.sb-collapsed .sidebar .menu-search-wrap,
    html.sb-collapsed .sidebar .greet,
    html.sb-collapsed .sidebar .smart-sb-section > h6,
    html.sb-collapsed .sidebar .fav-empty,
    html.sb-collapsed .sidebar .fav-pill > .star-toggle,
    html.sb-collapsed .sidebar .fav-pill > span:not(.icon),
    html.sb-collapsed .sidebar .nav > .nav-item > span:not(:first-child),
    html.sb-collapsed .sidebar a.nav-grp-link > span:not(:first-child),
    html.sb-collapsed .sidebar details.nav-grp > summary > *:not(:first-child) {
        display: none !important;
    }

    /* Every remaining row becomes a centred icon button. */
    html.sb-collapsed .sidebar .nav > .nav-item,
    html.sb-collapsed .sidebar .fav-pill,
    html.sb-collapsed .sidebar a.nav-grp-link,
    html.sb-collapsed .sidebar details.nav-grp > summary {
        justify-content: center !important;
        gap: 0 !important;
        padding-left: 0 !important;
        padding-right: 0 !important;
    }

    /* .nav-item's accent dot is anchored at left:14px (site.css ~2818). With
       the row centred it reads as a stray speck beside the icon. */
    html.sb-collapsed .sidebar .nav > .nav-item::before { display: none; }

    /* Group rows inherit summary's 13px, the two pinned links carry an inline
       16px — even them up so the rail reads as one column of icons. */
    html.sb-collapsed .sidebar details.nav-grp > summary > span:first-child,
    html.sb-collapsed .sidebar a.nav-grp-link > span:first-child,
    html.sb-collapsed .sidebar .fav-pill > .icon {
        font-size: 16px;
    }

    html.sb-collapsed .sidebar details.nav-grp > summary,
    html.sb-collapsed .sidebar a.nav-grp-link { padding-top: 9px; padding-bottom: 9px; }
    html.sb-collapsed .sidebar .fav-pill        { margin-bottom: 4px; }
    html.sb-collapsed .sidebar-logo             { justify-content: center; padding: 20px 0 16px; }
    html.sb-collapsed .sidebar .nav             { padding: 6px 6px; }
    html.sb-collapsed .sidebar .smart-sb         { padding: 8px 6px; gap: 4px; }
    html.sb-collapsed .sidebar .smart-sb-section { padding: 4px 0; }
    html.sb-collapsed .sidebar .fav-strip,
    html.sb-collapsed .sidebar .compliance-strip { padding: 4px; }

    /* A scrollbar would eat ~8 of the 68px rail — keep the wheel, drop the bar. */
    html.sb-collapsed .sidebar .nav { scrollbar-width: none; }
    html.sb-collapsed .sidebar .nav::-webkit-scrollbar { width: 0; height: 0; }

    /* The active group is server-rendered as <details open>, so on a
       collapsed first paint its whole item list would wrap into the 68px
       rail before any script runs. In rail mode the list only ever shows
       as the hover fly-out below. */
    html.sb-collapsed .sidebar .nav-grp-items { display: none; }

    /* ── Hover fly-out ────────────────────────────────────────────────
       .nav is an `overflow-y: auto` scroll container and .sidebar is
       `overflow: hidden`, so an absolutely-positioned panel would be
       clipped at the rail edge. The panel is therefore position:fixed
       (fixed descendants escape overflow clipping) and placed by the
       sbRail script in ~/js/sidebar-rail.js. */
    html.sb-collapsed .sidebar .nav-grp-items.sb-flyout {
        display: flex;
        position: fixed;
        z-index: 400;
        min-width: 236px;
        max-width: 320px;
        max-height: 74vh;
        overflow-y: auto;
        padding: 10px 12px 12px;
        background: var(--sidebar-bg, #0e1424);
        border: 1px solid rgba(255,255,255,0.14);
        border-radius: 10px;
        box-shadow: 0 14px 38px rgba(0,0,0,0.48);
    }

    /* Group name as the fly-out heading — the rail hides the summary label. */
    html.sb-collapsed .sidebar .nav-grp-items.sb-flyout::before {
        content: attr(data-grp-title);
        display: block;
        padding: 0 4px 8px;
        margin-bottom: 6px;
        font-size: 10px;
        letter-spacing: 1.4px;
        text-transform: uppercase;
        font-weight: 700;
        color: var(--sidebar-accent, #FBBF24);
        border-bottom: 1px solid rgba(255,255,255,0.10);
    }
}

@media (prefers-reduced-motion: reduce) {
    .sidebar, .main, .sb-rail-toggle { transition: none; }
}

/* ══════════════════════════════════════════════════════════════════
   Tenant brand mark — the company's own logo in place of the glyph
   ──────────────────────────────────────────────────────────────────
   Set by IBrandingResolver. The .logo-icon box keeps its size and its
   collapsed-rail behaviour; only its fill changes, so nothing in the
   SIDEBAR COLLAPSE rules needs to know a logo exists.
   ══════════════════════════════════════════════════════════════════ */
.logo-icon.has-img {
    background: #fff;
    padding: 3px;
    box-shadow: none;
}
.logo-icon.has-img img {
    width: 100%;
    height: 100%;
    object-fit: contain;   /* never crop a logo to fill a square */
    border-radius: 5px;
    display: block;
}
.mob-logo img.brand-mark {
    height: 22px;
    width: auto;
    vertical-align: -5px;
    margin-right: 4px;
}
/* "MicroFin" was 8 characters; a tenant name is arbitrary. Shrink with the
   viewport and clamp to two lines rather than widening the fixed sidebar. */
.logo-text .logo-name {
    font-size: clamp(15px, 1.35vw, 23px);
    line-height: 1.15;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* ════════════════════════════════════════════════════════════════
   ── Bank Statement Reconciliation (319) ──
   The customised BRS at /BankStatementRecon. Everything module-specific
   is prefixed `bsr-`; the handful of unprefixed helpers below were
   genuinely missing from the house sheet and are additive.

   The filter panels on these screens use the shared `.fpanel` contract —
   see the "Filter Panel" block above. Nothing here overrides it.
   ════════════════════════════════════════════════════════════════ */

/* ── Missing house helpers (additive, used beyond this module) ── */
.page-hdr-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-left: auto; }
.inline-form      { display: inline-flex; gap: 6px; align-items: center; margin: 0; }
.lnk-btn {
    background: none; border: 0; padding: 0; cursor: pointer;
    color: var(--color-primary, #3b5bdb); text-decoration: underline; font: inherit;
}
.card-foot {
    padding: 12px 16px; border-top: 1px solid var(--color-border, #e5e7eb);
    display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
}
.frow  { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.frow .fld { display: flex; flex-direction: column; gap: 4px; }
.frow .fld > label { font-size: 12px; font-weight: 600; }
.chk   { display: inline-flex; gap: 6px; align-items: center; font-size: 13px; }

/* Cell modifiers. `.num` already exists for td/th; these do not. */
.tbl td.wrap, .tbl th.wrap { white-space: normal; min-width: 200px; }
.tbl td.nowrap, .tbl th.nowrap { white-space: nowrap; }
.tbl td.sm, .tbl .sm { font-size: 11.5px; }
.tbl .sub {
    font-size: 11px; color: var(--color-text-muted, #6b7280);
    line-height: 1.35; margin-top: 2px;
}
.tbl tr.muted, .tbl td.muted { opacity: .55; }
.tbl td.empty { text-align: center; padding: 26px 12px; color: var(--color-text-muted, #6b7280); }
.tbl-sm th, .tbl-sm td { padding: 4px 7px; font-size: 12px; }

.pager {
    display: flex; gap: 10px; align-items: center; justify-content: center;
    padding: 10px; font-size: 12.5px;
}
.hint { font-size: 12px; color: var(--color-text-muted, #6b7280); }
.ok   { color: var(--color-success, #15803d); }
.bad  { color: var(--color-danger,  #b91c1c); }
.warn { color: var(--color-warning, #b45309); }

/* ── Header strip on a statement ── */
.bsr-hdr-strip {
    display: flex; flex-wrap: wrap; gap: 6px 20px; align-items: center;
    padding: 9px 14px; margin-bottom: 12px; font-size: 12.5px;
    background: var(--color-surface-alt, #f8fafc);
    border: 1px solid var(--color-border, #e5e7eb); border-radius: 8px;
}
.bsr-hdr-strip b { font-weight: 600; color: var(--color-text-muted, #6b7280); margin-right: 4px; }

/* ── Status pills ──
   Four visual states over seven statuses, because the four exception
   statuses share one workflow: a human has to look at them. */
.bsr-pill {
    display: inline-block; padding: 1px 8px; border-radius: 999px;
    font-size: 11px; font-weight: 600; white-space: nowrap; line-height: 1.7;
}
.bsr-pill-ok    { background: #dcfce7; color: #15803d; }
.bsr-pill-warn  { background: #fef3c7; color: #b45309; }
.bsr-pill-bad   { background: #fee2e2; color: #b91c1c; }
.bsr-pill-muted { background: #e5e7eb; color: #4b5563; }

.bsr-status-draft       { background: #e5e7eb; color: #4b5563; }
.bsr-status-mapping     { background: #dbeafe; color: #1d4ed8; }
.bsr-status-reconciling { background: #fef3c7; color: #b45309; }
.bsr-status-closed      { background: #dcfce7; color: #15803d; }

/* ── Progress bar on the statements list ── */
.bsr-bar {
    height: 6px; border-radius: 999px; overflow: hidden; min-width: 90px;
    background: var(--color-border, #e5e7eb);
}
.bsr-bar > span { display: block; height: 100%; background: var(--color-success, #22c55e); }

/* ── Outcome tabs ── */
.bsr-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 12px; }
.bsr-tabs > a {
    display: inline-flex; gap: 6px; align-items: center;
    padding: 6px 12px; border-radius: 7px; font-size: 12.5px; text-decoration: none;
    background: var(--color-surface-alt, #f3f4f6); color: var(--color-text, #374151);
    border: 1px solid transparent;
}
.bsr-tabs > a:hover  { background: var(--color-border, #e5e7eb); }
.bsr-tabs > a.on     { background: var(--color-primary, #3b5bdb); color: #fff; font-weight: 600; }
.bsr-tabs > a.alert:not(.on) { border-color: #fca5a5; color: #b91c1c; }
.bsr-tabs > a > span {
    background: rgba(0,0,0,.10); border-radius: 999px;
    padding: 0 6px; font-size: 11px; font-weight: 700;
}
.bsr-tabs > a.on > span { background: rgba(255,255,255,.25); }

/* ── Row tints by outcome ──
   Left border, not a full fill: a fully tinted row fights the table's own
   zebra striping and makes long narrations harder to read. */
.bsr-row-ok    { box-shadow: inset 3px 0 0 #22c55e; }
.bsr-row-warn  { box-shadow: inset 3px 0 0 #f59e0b; }
.bsr-row-bad   { box-shadow: inset 3px 0 0 #ef4444; background: #fef7f7; }
.bsr-row-muted { box-shadow: inset 3px 0 0 #9ca3af; opacity: .7; }

/* ── The mapping cell: whom / counterparty / purpose / remarks ──
   A grid rather than a row of inline inputs, so the four controls keep a
   predictable width as the narration column flexes. */
.bsr-lines td.bsr-map { min-width: 340px; }
.bsr-mapform {
    display: grid; grid-template-columns: 1fr 1fr; gap: 4px; align-items: start; margin: 0;
}
.bsr-mapform .bsr-member { position: relative; }
.bsr-mapform .inp-sm, .bsr-mapform .bsr-memsearch {
    width: 100%; padding: 3px 6px; font-size: 11.5px; border-radius: 5px;
    border: 1px solid var(--color-border, #d1d5db);
}
.bsr-mapform > button { grid-column: 1 / -1; justify-self: start; }

/* ── 321: category first, then whichever "whom" it calls for ──
   The category spans both tracks because it governs the row; the single
   visible .bsr-whom and the purpose then sit side by side. A category with
   no counterparty hides every .bsr-whom, and the purpose takes the row. */
.bsr-mapform > .bsr-cat { grid-column: 1 / -1; }
.bsr-mapform > .bsr-whom { min-width: 0; }
.bsr-mapform > .bsr-whom[hidden] { display: none; }

/* ── 321: the seam between the bank's columns and ours ──
   The statement is read left of this line and worked right of it. One rule
   on both th and td, so the divider runs the whole height of the table. */
.bsr-lines th.bsr-seam,
.bsr-lines td.bsr-seam { border-left: 2px solid var(--color-border, #d1d5db); }

/* ── 321: Categories & Purposes admin ──────────────────────────
   One card per category, its purposes tabulated inside it. The nesting IS
   the information: a purpose only means anything under its category. */
.bst-tax { display: flex; flex-direction: column; gap: 14px; }
.bst-cat-hdr { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.bst-cat-hdr h3 { margin: 0; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.bst-cat-acts { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.bst-purposes { margin: 0; }
.bst-purposes td, .bst-purposes th { padding: 6px 12px; }
.bst-addrow { padding: 10px 12px; }

/* A switched-off row stays legible — it is read to decide whether to switch it
   back on. Greyed, never hidden, and never so faint it cannot be read. */
.bst-off { opacity: .62; }
.bst-cat.bst-off { border-style: dashed; }

.pill-muted { background: var(--color-bg-muted, #f1f3f5); color: var(--color-text-muted, #6b7280); }
.pill-warn  { background: #fdf3e3; color: #9a6212; }

/* ── 323: payees ───────────────────────────────────────────────
   The picker and its "+ New" sit on one line; the button must not wrap
   under the select or the mapping cell gains a row per payee category. */
.bsr-payee { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; }
.bsr-payee > select { flex: 1 1 auto; min-width: 0; }
.bsr-payee > .sub   { flex: 1 0 100%; }

/* The alias suggestion. Deliberately quiet — it is an offer, not a finding,
   and styling it as an alert would make every recognised vendor look urgent. */
.bsr-sugg {
    grid-column: 1 / -1; justify-self: start;
    background: none; border: 1px dashed var(--color-border, #d1d5db);
    border-radius: 5px; padding: 2px 7px; font-size: 11px; cursor: pointer;
    color: var(--color-text-muted, #6b7280);
}
.bsr-sugg:hover { border-style: solid; color: var(--color-text, #111827); }
.bsr-sugg b { font-weight: 600; }

/* Aliases on the payee master: each fragment with its match count and an × */
.bsp-alias { display: inline-flex; align-items: center; gap: 4px; margin: 0 6px 3px 0; }
.bsp-alias code { font-size: 11px; }
.bsp-aliasadd { display: flex; gap: 4px; margin-top: 4px; max-width: 240px; }
.bsr-modal-wide .bsr-modal-box, .bsr-modal-box.bsr-modal-wide { max-width: 640px; }

/* ── 324: posting ──────────────────────────────────────────────
   Its own column beside Reconciliation, because they answer different
   questions and a line can legitimately be Unmatched AND Posted. */
.bsr-lines td.bsr-post { min-width: 150px; }
.bsr-postacts { display: flex; gap: 4px; align-items: center; margin-top: 4px; flex-wrap: wrap; }
.bsr-pill-info { background: #e6f0f7; color: #1d5a7a; }
.bsr-postsum th { width: 34%; text-align: left; color: var(--color-text-muted, #6b7280); font-weight: 500; }
.bsr-undo { margin-top: 3px; }

/* Member type-ahead */
.bsr-memdrop {
    position: absolute; z-index: 40; top: 100%; left: 0; min-width: 240px; max-height: 220px;
    overflow-y: auto; background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #d1d5db); border-radius: 7px;
    box-shadow: 0 8px 22px rgba(0,0,0,.13);
}
.bsr-memdrop button {
    display: block; width: 100%; text-align: left; padding: 5px 9px;
    background: none; border: 0; cursor: pointer; font-size: 12px; line-height: 1.35;
}
.bsr-memdrop button:hover { background: var(--color-surface-alt, #f3f4f6); }
.bsr-memdrop button span {
    display: block; font-size: 10.5px; color: var(--color-text-muted, #6b7280);
}
.bsr-memnone { padding: 7px 9px; font-size: 12px; color: var(--color-text-muted, #6b7280); }

.bsr-recon { min-width: 210px; }
.bsr-acts  { text-align: right; }
.bsr-acts .btn { margin-left: 4px; }

/* ── Import preview ── */
.bsr-preamble {
    background: var(--color-surface-alt, #f8fafc);
    border: 1px solid var(--color-border, #e5e7eb);
    border-radius: 8px; padding: 10px 14px; margin: 12px 0;
}
.bsr-preamble h4 { margin: 0 0 6px; font-size: 12.5px; }
.bsr-preamble dl {
    display: grid; grid-template-columns: max-content 1fr; gap: 2px 14px;
    margin: 0; font-size: 12.5px;
}
.bsr-preamble dt { font-weight: 600; color: var(--color-text-muted, #6b7280); }
.bsr-preamble dd { margin: 0; }
.bsr-preamble .ok-note { margin: 8px 0 0; font-size: 12px; color: var(--color-success, #15803d); }

.bsr-cols { margin: 12px 0; }
.bsr-cols > summary { cursor: pointer; font-size: 12.5px; font-weight: 600; padding: 4px 0; }

/* ── Report grouping cards, side by side ── */
.bsr-groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; }

/* ── Audit diff ── */
.bsr-diff { font-size: 11.5px; display: flex; gap: 6px; flex-wrap: wrap; align-items: baseline; }
.bsr-diff .old { color: #b91c1c; text-decoration: line-through; }
.bsr-diff .new { color: #15803d; }
.bsr-diff .arr { color: var(--color-text-muted, #6b7280); }

/* ── Match picker ── */
.bsr-modal {
    position: fixed; inset: 0; z-index: 1000; background: rgba(15,23,42,.45);
    display: flex; align-items: flex-start; justify-content: center; padding: 6vh 16px;
}
.bsr-modal[hidden] { display: none !important; }
.bsr-modal-box {
    background: var(--color-surface, #fff); border-radius: 11px; width: min(980px, 100%);
    max-height: 80vh; display: flex; flex-direction: column;
    box-shadow: 0 22px 55px rgba(0,0,0,.3);
}
.bsr-modal-hdr {
    display: flex; align-items: center; justify-content: space-between;
    padding: 12px 16px; border-bottom: 1px solid var(--color-border, #e5e7eb);
}
.bsr-modal-hdr h3 { margin: 0; font-size: 14px; }
.bsr-modal-x { background: none; border: 0; font-size: 17px; cursor: pointer; line-height: 1; }
.bsr-modal-body { padding: 12px 16px; overflow: auto; }

/* Dark theme — only the hand-picked light tints need restating; everything
   else above resolves through the house variables already. */
[data-theme="dark"] .bsr-pill-ok    { background: #14532d; color: #bbf7d0; }
[data-theme="dark"] .bsr-pill-warn  { background: #4a2c05; color: #fde68a; }
[data-theme="dark"] .bsr-pill-bad   { background: #4c1414; color: #fecaca; }
[data-theme="dark"] .bsr-pill-muted { background: #374151; color: #d1d5db; }
[data-theme="dark"] .bsr-status-draft       { background: #374151; color: #d1d5db; }
[data-theme="dark"] .bsr-status-mapping     { background: #1e3a8a; color: #bfdbfe; }
[data-theme="dark"] .bsr-status-reconciling { background: #4a2c05; color: #fde68a; }
[data-theme="dark"] .bsr-status-closed      { background: #14532d; color: #bbf7d0; }
[data-theme="dark"] .bsr-row-bad            { background: #2a1414; }

/* ════════════════════════════════════════════════════════════════
   ── BRS statement & dashboard ──
   /BankStatementRecon/Statement and /Dashboard. Prefixed `brs-` to sit
   beside the `bsr-` line-working styles above without colliding: `bsr-`
   is the statement WORKBENCH, `brs-` is the reconciliation DOCUMENT.

   The bridge is deliberately typeset like an accounting statement rather
   than a data table — a ruled column of labels against one right-aligned
   money column — because that is the shape an auditor reads without being
   taught, and this page's whole job is to be believed.
   ════════════════════════════════════════════════════════════════ */

.brs-doc .card-body { padding-top: 10px; }

.brs-bridge { width: 100%; border-collapse: collapse; max-width: 760px; }
.brs-bridge td { padding: 5px 4px; vertical-align: top; }
.brs-bridge .brs-label { font-size: 13px; }
.brs-bridge .brs-amt {
    text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums;
    font-size: 13px; width: 170px; padding-left: 18px;
}
.brs-bridge .brs-amt.zero { color: var(--color-text-muted, #9ca3af); }

/* The three figures that carry the argument. A reader should be able to find
   the bank's number, our number and the residue without reading the rows. */
.brs-bridge .brs-anchor  td { font-weight: 600; border-bottom: 1px solid var(--color-border, #e5e7eb); }
.brs-bridge .brs-derived td { font-weight: 600; border-top: 1px solid var(--color-border, #e5e7eb); padding-top: 8px; }
.brs-bridge .brs-actual  td { font-weight: 600; }
.brs-bridge .brs-residue td {
    font-weight: 700; font-size: 14px;
    border-top: 2px solid var(--color-text, #111827);
    border-bottom: 3px double var(--color-text, #111827);
    padding: 7px 4px;
}
.brs-bridge .brs-residue.ok      td { color: #15803d; }
.brs-bridge .brs-residue.bad     td { color: #b91c1c; }
.brs-bridge .brs-residue.unknown td { color: #b45309; }

.brs-bridge .brs-item .brs-label a { text-decoration: none; }
.brs-bridge .brs-item .brs-label a:hover { text-decoration: underline; }

/* Add / Less / Adjust — the sign is the thing a reader most often loses, so it
   is a fixed-width chip rather than a word buried in the sentence. */
.brs-eff {
    display: inline-block; min-width: 44px; margin-right: 6px; padding: 1px 5px;
    border-radius: 4px; font-size: 10.5px; font-weight: 700; text-align: center;
    text-transform: uppercase; letter-spacing: .03em;
}
.brs-eff.add  { background: #dcfce7; color: #15803d; }
.brs-eff.less { background: #fee2e2; color: #b91c1c; }
.brs-eff.adj  { background: #e5e7eb; color: #4b5563; }

.brs-ct  { font-size: 11px; color: var(--color-text-muted, #6b7280); margin-left: 6px; }
.brs-src { display: block; font-size: 11px; color: var(--color-text-muted, #6b7280); margin-left: 50px; }

.brs-verdict { margin: 14px 0 0; font-size: 13px; max-width: 760px; line-height: 1.5; }
.brs-verdict.ok      { color: #15803d; }
.brs-verdict.bad     { color: #b91c1c; }
.brs-verdict.unknown { color: #b45309; }

.brs-causes { margin: 6px 0 0 18px; font-size: 12.5px; line-height: 1.6; max-width: 760px; }
.brs-causes li { margin-bottom: 3px; }

.brs-explain {
    margin: 0 0 10px; font-size: 12px; color: var(--color-text-muted, #6b7280);
    max-width: 900px; line-height: 1.5;
}
.brs-hidden { margin: 8px 0 0; font-size: 12px; color: var(--color-text-muted, #6b7280); }

.brs-caveats ul { margin: 6px 0 0 18px; line-height: 1.55; }
.brs-caveats li { margin-bottom: 3px; }

.brs-sec-hdr { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

.brs-items td, .brs-items th { white-space: normal; }
.brs-health .sub {
    display: block; font-size: 11px; color: var(--color-text-muted, #6b7280); font-weight: 400;
}
.brs-health .bsr-bar { margin-bottom: 2px; }

/* Credit / debit sparkline. Both bars are scaled against ONE maximum across the
   whole table — per-row scaling would draw a quiet month exactly like a heavy
   one, which is the opposite of what a trend column is for. */
.brs-spark { min-width: 90px; }
.brs-spark > span { display: block; height: 5px; border-radius: 3px; margin: 2px 0; }
.brs-spark > span.cr { background: #22c55e; }
.brs-spark > span.dr { background: #f97316; }
.brs-spark > span[style*="width:0%"] { background: var(--color-border, #e5e7eb); min-width: 2px; }

.brs-key { display: inline-block; width: 14px; height: 5px; border-radius: 3px; vertical-align: middle; }
.brs-key.cr { background: #22c55e; }
.brs-key.dr { background: #f97316; }

[data-theme="dark"] .brs-eff.add  { background: #14532d; color: #bbf7d0; }
[data-theme="dark"] .brs-eff.less { background: #4c1414; color: #fecaca; }
[data-theme="dark"] .brs-eff.adj  { background: #374151; color: #d1d5db; }
[data-theme="dark"] .brs-bridge .brs-residue.ok      td { color: #86efac; }
[data-theme="dark"] .brs-bridge .brs-residue.bad     td { color: #fecaca; }
[data-theme="dark"] .brs-bridge .brs-residue.unknown td { color: #fde68a; }
[data-theme="dark"] .brs-verdict.ok      { color: #86efac; }
[data-theme="dark"] .brs-verdict.bad     { color: #fecaca; }
[data-theme="dark"] .brs-verdict.unknown { color: #fde68a; }

/* ── Company-hidden member fields (Settings → Member Form Fields) ──────────────
   Set by wwwroot/js/hidden-fields.js on a field wrapper, on a grid whose fields are
   all hidden, and on the section around it. !important because several of these
   wrappers are also driven by inline style from the page's own scripts — the MFI
   form's Business-details toggle sets style.display='' on #businessNameGroup the
   moment MemberType changes, which would otherwise un-hide a field the company
   switched off. Sibling of .fg / .form-group; see _MemberHiddenFieldStyles.cshtml
   for the no-flash rules that hide the same wrappers at parse time. */
.mf-hidden { display: none !important; }

/* ── Staff Handover picker (.hdp) ────────────────────────────────
   The Selective pane on /StaffHandover. Replaced four stacked
   `<select multiple>` boxes, of which two are usually empty and the one
   that matters showed ~7 rows of a 103-row book behind a Ctrl-click.

   RULES
   - Every pane's checkboxes POST, including the panes that are hidden.
     `display:none` still submits; `disabled` does not. Never disable a
     pane to hide it, or its picks vanish on submit with no message.
   - The table carries `data-dt-skip`. dt-toolbar.js auto-initialises any
     table with 2 or more body rows and would then DETACH every row past
     page 1, so their checkboxes would never post — TRIGGER 18.
   - `.hdp-list` owns the scroll and its `th` are sticky, so the header
     survives a 2,000-row list.
   - Filtering hides rows with `.hdp-hide`; it never unchecks anything.
     A hidden pick still posts, and the rail says how many are hidden.
   - Status colours come from the shared `.badge-*` classes so the dark
     theme keeps working; do not hardcode hexes here.  ───────────── */
.hdp { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 14px; align-items: start; }
@media (max-width: 1100px) { .hdp { grid-template-columns: minmax(0, 1fr); } }

.hdp-main, .hdp-rail { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }

.hdp-tabs { display: flex; gap: 4px; padding: 8px 10px 0; background: var(--surface2); border-bottom: 1px solid var(--border); overflow-x: auto; }
.hdp-tab { display: inline-flex; align-items: center; gap: 6px; height: 38px; padding: 0 13px; margin-bottom: -1px;
           border: 1px solid transparent; border-radius: 9px 9px 0 0; background: transparent; cursor: pointer;
           color: var(--text-muted); font-family: inherit; font-size: 13px; font-weight: 500; white-space: nowrap; }
.hdp-tab.on { background: var(--surface); border-color: var(--border); border-bottom-color: var(--surface); color: var(--text); font-weight: 600; }
.hdp-tab .n { padding: 1px 7px; border-radius: 9px; background: var(--surface0); color: var(--text-muted); font-size: 11px; font-weight: 600; }
.hdp-tab.on .n { background: var(--primary-soft); color: var(--primary-deep); }
.hdp-tab .p { padding: 1px 7px; border-radius: 9px; background: var(--primary); color: #fff; font-size: 11px; font-weight: 600; }

.hdp-pane { display: none; }
.hdp-pane.on { display: block; }

.hdp-tools { padding: 11px 14px; display: flex; flex-direction: column; gap: 8px; border-bottom: 1px solid var(--surface0); }
.hdp-r1 { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.hdp-r2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px; }
.hdp-search { flex: 1 1 220px; display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 10px;
              border: 1px solid var(--border); border-radius: 8px; background: var(--surface); }
.hdp-search input { flex: 1 1 auto; min-width: 0; border: 0; outline: none; background: transparent;
                    font-family: inherit; font-size: 13px; color: var(--text); }
.hdp-tools select { height: 36px; min-width: 0; padding: 0 8px; border: 1px solid var(--border); border-radius: 8px;
                    background: var(--surface); font-family: inherit; font-size: 13px; color: var(--text); }
.hdp-tools select.on { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-deep); font-weight: 600; }
.hdp-tog { height: 36px; padding: 0 13px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
           color: var(--text); font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer; }
.hdp-tog.on { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-deep); }

.hdp-bulk { padding: 9px 14px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
            background: var(--primary-soft); border-bottom: 1px solid var(--gold-border); }
.hdp-bulk button { height: 30px; padding: 0 12px; border-radius: 7px; font-family: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.hdp-bulk .go  { border: 1px solid var(--primary); background: var(--primary); color: #fff; }
.hdp-bulk .alt { border: 1px solid var(--gold-border); background: var(--surface); color: var(--primary-deep); }
.hdp-bulk .off { border: 1px solid var(--border); background: var(--surface); color: var(--text-muted); }
.hdp-bulk .count { margin-left: auto; font-size: 12px; font-weight: 600; color: var(--primary-deep); }

.hdp-list { max-height: 430px; overflow: auto; }
.hdp-list table { width: 100%; border-collapse: collapse; }
.hdp-list th { position: sticky; top: 0; z-index: 1; padding: 8px 10px; text-align: left; white-space: nowrap;
               background: var(--surface2); border-bottom: 1px solid var(--border);
               font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }
.hdp-list td { padding: 9px 10px; border-bottom: 1px solid var(--surface0); font-size: 13px; color: var(--text); vertical-align: middle; }
.hdp-list tbody tr { cursor: pointer; }
.hdp-list tbody tr.picked td { background: var(--primary-soft); }
.hdp-list tr.hdp-hide { display: none; }
.hdp-list input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--primary); cursor: pointer; }
.hdp-grp { color: var(--primary-deep); }
.hdp-grp.none { color: var(--text-dim); font-style: italic; }
.hdp-num { font-family: var(--font-mono); font-size: 12px; }
.hdp-rt { text-align: right; }

.hdp-foot { padding: 9px 14px; border-top: 1px solid var(--border); background: var(--surface2);
            display: flex; gap: 10px; flex-wrap: wrap; align-items: center; font-size: 12px; color: var(--text-muted); }
.hdp-foot .sp { margin-left: auto; }
.hdp-empty { padding: 34px 14px; text-align: center; font-size: 13px; color: var(--text-muted); }

.hdp-rail-hdr { padding: 12px 14px; background: var(--surface2); border-bottom: 1px solid var(--border); }
.hdp-rail-row { display: flex; align-items: baseline; gap: 8px; padding: 5px 14px; font-size: 13px; color: var(--text); }
.hdp-rail-row .l { flex: 1 1 auto; }
.hdp-rail-row .v { font-weight: 600; color: var(--primary-deep); }
.hdp-rail-ttl { padding: 10px 14px 6px; font-size: 11px; font-weight: 600; letter-spacing: .06em;
                text-transform: uppercase; color: var(--text-muted); }
.hdp-chips { padding: 0 14px 12px; display: flex; flex-wrap: wrap; gap: 6px; max-height: 190px; overflow: auto; }
.hdp-pill { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 8px;
            border: 1px solid var(--gold-border); border-radius: 13px; background: var(--primary-soft);
            color: var(--primary-deep); font-family: inherit; font-size: 12px; cursor: pointer; }
.hdp-warn { padding: 11px 14px; border-top: 1px solid var(--orange-bg); background: var(--orange-bg);
            font-size: 12px; line-height: 1.5; color: var(--orange); }
.hdp-warn button { margin-top: 7px; height: 30px; padding: 0 12px; border: 1px solid var(--orange);
                   border-radius: 7px; background: var(--surface); color: var(--orange);
                   font-family: inherit; font-size: 12px; font-weight: 600; cursor: pointer; }
.hdp-quiet { padding: 11px 14px; border-top: 1px solid var(--surface0); background: var(--surface2);
             font-size: 12px; color: var(--text-muted); }

.hdp-sum { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 14px; padding: 14px 16px;
           background: var(--surface); border: 1px solid var(--border); border-radius: 12px; }
.hdp-sum .big { font-family: var(--font-head); font-size: 18px; font-weight: 700; color: var(--text); }
.hdp-sum .sp { margin-left: auto; }

/* Bulk-vs-Selective mode switch and the preview count tiles. These lived in an
   inline <style> block in Views/StaffHandover/Index.cshtml until 2026-09-18 and
   moved here with the picker. `.hd-mode-btn` is deliberately NOT `.hdp-tog`:
   setMode() clears `on` across the mode pair, and sharing a class with the
   filter toggles would wipe the "Overdue only" state on every pane. */
.hd-mode-btn { padding: 8px 14px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface);
               color: var(--text); font-family: inherit; font-size: 13px; font-weight: 500; cursor: pointer; }
.hd-mode-btn.on { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }

.hd-counts { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 10px; margin: 14px 0; }
.hd-count { padding: 10px; background: var(--surface2); border: 1px solid var(--border); border-radius: 8px; text-align: center; }
.hd-count .n { font-family: var(--font-head); font-size: 22px; font-weight: 700; color: var(--primary-deep); }
.hd-count .l { font-size: 11px; color: var(--text-muted); margin-top: 4px; }

/* ── Customer verification panel (_CustomerVerification.cshtml) ────────────────
   The four facts confirmed before a loan's cash is released. Rendered inside the
   Bulk Disbursement preview <dialog> (640px) and on the HO / approval drill-downs,
   so it must sit happily in a narrow box and on a full-width page alike — hence
   auto-fit columns rather than a fixed count.

   Divs, never a <table>: the global `table { min-width:650px }` floor would force a
   horizontal scrollbar the dialog's ancestors cannot provide. TRIGGER 18.          */
.cv-panel { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface2); margin-bottom: 14px; overflow: hidden; }
.cv-hdr   { display: flex; align-items: center; gap: 7px; padding: 8px 12px; border-bottom: 1px solid var(--border); color: var(--primary-deep); }
.cv-hdr h4 { margin: 0; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; }
.cv-grid  { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px 16px; padding: 11px 12px; }
.cv-fld   { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cv-lbl   { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .4px; color: var(--text-muted); }
/* overflow-wrap, not nowrap: a long product name or a 16-digit account must wrap inside
   its own field rather than widen the grid track and push the panel out of the dialog. */
.cv-val   { font-size: 13.5px; color: var(--text); overflow-wrap: anywhere; }
.cv-strong { font-weight: 700; }
.cv-sub   { font-size: 11px; color: var(--text-muted); overflow-wrap: anywhere; }
.cv-warn  { color: var(--orange); }
