.custom-table > thead:first-child > tr:first-child > th{
    background-color: white !important;
    color: #534AB7 !important;
    border-color: #3C3489;
    border-top: 2px solid #3C3489;
    text-align: center;
}

.custom-table > tfoot > tr > th{
	text-align: center;
}

.custom-table > tbody > tr > td{
	text-align: center;
}

.custom-table > tbody > tr > td{
	text-align: center;
}

.table-condensed-custom > tbody > tr > td, .table-condensed-custom > tbody > tr > th, .table-condensed-custom > tfoot > tr > td, .table-condensed-custom > tfoot > tr > th, .table-condensed-custom > thead > tr > td, .table-condensed-custom > thead > tr > th {
    padding: 0px;
}

.box-header > .box-tools .dropdown-menu > li > a:hover {
    color: #534AB7 !important;
}

.dark-mode table .stripped tr:hover {
    color: #000000 !important;
}

.dark-mode table#ledgerentries_table tr:hover {
    color: #000000 !important;
}

.dark-mode table#ledgerstatement_table tr:hover {
    color: #000000 !important;
}

.dark-mode table#reconciliation_table tr:hover {
    color: #000000 !important;
}

.dark-mode table#trialbalance_table tr:hover {
    color: #000000 !important;
}


.dark-mode table#entries_table tr:hover {
    color: #000000 !important;
}

.dark-mode table#edit_entries_table tr:hover {
    color: #000000 !important;
}

.dark-mode table#add_entries_table tr:hover {
    color: #000000 !important;
}

.dark-mode table#view_entries_table tr:hover {
    color: #000000 !important;
}

.dark-mode table#ledgertable tr:hover {
    color: #000000 !important;
}

[class*="sidebar-dark-"] .nav-sidebar > .nav-item.menu-open > .nav-link:hover {
    background-color: rgba(255,255,255,.1) !important;
    color: #fff;
}

/*[class*="sidebar-dark-"] .nav-sidebar > .nav-item.menu-open > .nav-link {
    background-color: #343a40 !important;
    color: #fff;
}*/
/* Previously `position: absolute !important;` with no offsets - this took
   every DataTables toolbar out of normal flow app-wide, so it rendered
   floating over whatever content happened to sit at that spot (the search
   box, the table header row) instead of sitting inline above the table.
   The one place this was worked around (.coa-actions, below) already
   "cancels" it back to static - so static is the layout every page
   actually wants; setting it here fixes every other admin/settings page
   (Users, Companies, User Permissions, Tags, Entry Types) that has the
   same un-wrapped toolbar and never got its own override. */
div.dt-buttons {
    position: static !important;
}
[class*=sidebar-dark-] .nav-sidebar>.nav-item.menu-open>.nav-link, [class*=sidebar-dark-] .nav-sidebar>.nav-item:hover>.nav-link {
    color: #c2c7d0;
}

[class*=sidebar-dark-] .nav-sidebar>.nav-item>.nav-link:hover {
    background-color: rgba(255,255,255,.1);
    color: #fff;
}

[class*=sidebar-dark-] .nav-sidebar>.nav-item>.nav-link:focus {
    background-color: rgba(255,255,255,.1);
    color: #fff;
}

[class*=sidebar-dark-] .nav-sidebar>.nav-item>.nav-link.active, .sidebar-light .nav-sidebar>.nav-item>.nav-link.active {
    background-color: #085041;
    color: #fff;
}

/*[class*="sidebar-dark-"] .nav-sidebar > .nav-item.menu-open > .nav-link.active:hover {
  background-color: #212528 !important;
  color: #fff;
}*/

.dark-mode #dr-total {
    color: #000000 !important;
}

.dark-mode #cr-total {
    color: #000000 !important;
}

/*.dr-total {
    color: #ffffff !important;
}

.dr-total {
    color: #ffffff !important;
}
*/
table.stripped {
    width: 100%;
}

table.stripped tr td {
    border-bottom:1px solid #DDDDDD;
    border-top:1px solid #DDDDDD;
}

table.stripped tr:hover {
    background-color: #FFFF99;
}

table.stripped .tr-ledger {

}

table.stripped .tr-group {
    font-weight: bold;
}

table.stripped .tr-highlight {
    background-color: #F3F3F3;
}

.dark-mode table.stripped .tr-highlight {
    background-color: #5b636a;
}

table.stripped .tr-root-group {
    background-color: #F3F3F3;
    color: #754719;
}

.font-normal {
    font-weight: normal;
}

.help-block {
  display: block;
  margin-top: 5px;
  margin-bottom: 10px;
  color: #737373;
}

#section-to-print, #section-to-print * {
    visibility: visible;
}
#section-to-print {
    position: absolute;
    left: 55px;
    right: 55px;
    top: 40px;
    bottom: 40px;
}

.subtitle {
    color: #333333;
    font-size: 19px;
    margin-bottom: 10px;
}

.text-center {
  text-align: center !important;
}

.dark-mode .subtitle {
    color: #ffffff !important;
}

.table-top {
    vertical-align: top;
}

/*table tr td .width-50 {
    width: 40%;
}*/

.width-50 {
    width: 40%;
}

.width-70 {
    width: 70%;
}

.width-30 {
    width: 30%;
}

.bg-filled {
    background-color: #F3F3F3;
}

.bold-text {
    font-weight: bold;
}

.report-tb-pad {
    margin-top: 30px !important;
}

.summary {
    background-color: #FFFFCC;
    border: 1px solid #BBBBBB;
    border-collapse: collapse;
    text-align: left;
    width: 600px;
}

.error-text {
    font-weight: bold;
    color: #FF0000;
}

.ok-text {
    /*color: #006400;*/
}

.dc-error {
    background: #FFB2B2;
}

.dc-error {
    background: #FFB2B2;
}

.dc-ok {
    background: #4ec14e;
}

/*table td .dc-ok {
    background: #006400;
}*/

.dark-mode .summary {
    color: #000000 !important;
}

.summary td {
    border: 1px solid #BBBBBB;
}

.td-fixwidth-summary {
    width: 300px;
    vertical-align: text-top;
}

.dash_bank_cash {
    font-size: 1.1rem;
    font-weight: 400;
    margin: 0;
}

/* ==========================================================================
   Professional Dashboard Theme
   ========================================================================== */

:root {
    /* Nidaam brand palette (see brand implementation spec) */
    --db-primary: #534AB7;
    --db-primary-dark: #3C3489;
    --db-accent: #085041;
    --db-accent-bg: rgba(8, 80, 65, 0.09);
    --db-ink: #1c2733;
    --db-muted: #6b7684;
    --db-border: #e7ebf1;
    --db-income: #1e8e57;
    --db-income-bg: #e5f6ee;
    --db-expense: #d64545;
    --db-expense-bg: #fdeaea;
    --db-neutral: #c98a1f;
    --db-neutral-bg: #fbf1de;
    --db-radius: 12px;
    --db-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 3px rgba(16, 24, 40, 0.06);
    --db-shadow-md: 0 4px 14px rgba(16, 24, 40, 0.09);
    --db-sidebar-bg: #ffffff;
    --db-sidebar-border: var(--db-border);
    --db-sidebar-active-bg: var(--db-accent-bg);
    --db-sidebar-active-ink: var(--db-accent);
    --db-sidebar-icon-muted: #97a1b0;
    --db-topbar-bg: #ffffff;
    --db-page-bg: #f4f6f9;
    --db-card-bg: #ffffff;
    --db-input-bg: #ffffff;
}

.dark-mode {
    /* Nidaam brand palette - dark mode pairs */
    --db-primary: #AFA9EC;
    --db-primary-dark: #CECBF6;
    --db-accent: #5DCAA5;
    --db-accent-bg: rgba(93, 202, 165, 0.22);
    --db-ink: #eef1f5;
    --db-muted: #a9b3c1;
    --db-border: #3a4048;
    --db-neutral-bg: rgba(201, 138, 31, 0.16);
    --db-sidebar-bg: #1b222c;
    --db-sidebar-border: #2c343f;
    --db-sidebar-active-bg: var(--db-accent-bg);
    --db-sidebar-active-ink: var(--db-accent);
    --db-sidebar-icon-muted: #7c8797;
    --db-topbar-bg: #1b222c;
    /* Layered elevation for "modern" dark mode: page canvas is the darkest
       surface, card panels sit a shade lighter (visible depth instead of
       AdminLTE's stock flat #454d55/#343a40 pairing), inputs are recessed
       a shade darker than the card that holds them. Added Sept 8 2026 per
       user request to modernize dark mode across the app. */
    --db-page-bg: #10141b;
    --db-card-bg: #1c222c;
    --db-input-bg: #161b23;
}

/* -- Header band (Aug 25 2026 - greeting header, replaces the old gradient band) */

.dashboard-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 18px;
    flex-wrap: wrap;
    padding-bottom: 18px;
    margin-bottom: 20px;
    border-bottom: 1px solid var(--db-border);
}

.dashboard-header__body {
    min-width: 0;
}

.dashboard-header__title {
    font-size: 1.5rem;
    font-weight: 800;
    margin: 0 0 4px 0;
    line-height: 1.25;
    letter-spacing: -0.015em;
    color: var(--db-ink);
}

.dashboard-header__subtitle {
    margin: 0 0 10px 0;
    font-size: 0.9rem;
    color: var(--db-muted);
}

.dashboard-header__fy {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(83, 74, 183, 0.08);
    color: var(--db-primary-dark);
}

.dashboard-header__cta {
    flex-shrink: 0;
    display: inline-flex !important;
    align-items: center;
    gap: 8px;
    background: var(--db-primary);
    color: #ffffff !important;
    font-weight: 700;
    font-size: 0.85rem;
    padding: 11px 18px;
    border-radius: 10px;
    box-shadow: 0 4px 10px rgba(83, 74, 183, 0.35);
    text-decoration: none !important;
}

.dashboard-header__cta:hover {
    background: var(--db-primary-dark);
}

/* -- Cards --------------------------------------------------------------- */

.dashboard-card {
    background: var(--db-card-bg);
    border: 1px solid var(--db-border);
    border-radius: var(--db-radius);
    box-shadow: 0 1px 3px rgba(16, 24, 40, 0.06);
    transition: box-shadow 0.15s ease;
    overflow: hidden;
}

.dashboard-card:hover {
    box-shadow: 0 4px 14px rgba(16, 24, 40, 0.09);
}

/* Light-mode shadows read as near-invisible on a dark panel, so dark mode
   gets its own elevation recipe: a faint top highlight (the "light hits
   the top edge" cue modern dark UIs use) at rest, plus a real drop shadow
   on :hover only.
   A resting-state drop shadow on every card was tried first and caused a
   visible defect: this dashboard places two dashboard-cards side by side
   (Income vs Expenses / Bank & Cash Accounts) with a normal column gap
   between them, and having BOTH cast the same drop shadow at once let
   the shadows blur sideways into each other, showing up as a solid
   vertical gray bar running down the gap between the two cards instead
   of two visually separate panels (caught by zooming into a user
   screenshot - same underlying issue as the .stat-tile fix above, just
   vertical instead of horizontal). Dropping the resting shadow removes
   it; :hover is unaffected since only one card lifts at a time. */
.dark-mode .dashboard-card {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.dark-mode .dashboard-card:hover {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 8px 20px rgba(0, 0, 0, 0.4);
}

.dashboard-card > .card-header {
    background: transparent;
    border-bottom: 1px solid var(--db-border);
    padding: 14px 18px;
    display: flex;
    align-items: center;
}

/* AdminLTE ships a bare `.card-header::after { display:block; clear:both;
   content:""; }` clearfix rule for its original float-based header layout
   (title floated left, tools floated right). The moment a .card-header
   becomes display:flex (as every redesigned header with a right-aligned
   button does, via an inline `justify-content: space-between` style),
   that pseudo-element stops being a harmless clearfix and becomes a REAL
   THIRD flex item - invisible, but still counted by justify-content. With
   3 items instead of 2, space-between splits the free space into TWO gaps
   (title-to-button, then button-to-invisible-pseudo) instead of one, so
   the button visibly stops short of the true right edge by roughly a
   third of the available space - found Aug 25 2026 via the user reporting
   "these buttons move to the side" and confirmed in DevTools (the
   ::after literally shows up as a sibling flex box in the Elements tree).
   Since nothing in this app's card headers relies on floats anymore
   (everything here uses flex or plain block layout), disabling the
   pseudo-element outright is safe app-wide, not just for .dashboard-card. */
.card-header::after {
    content: none !important;
}

.dashboard-card__title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--db-ink);
    margin: 0;
}

.dashboard-card__title i {
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background: rgba(83, 74, 183, 0.1);
    color: var(--db-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
}

.dashboard-card > .card-body {
    padding: 18px;
}

/* -- Net worth / stat block ---------------------------------------------- */

.stat-networth {
    text-align: center;
}

.stat-networth__label {
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--db-muted);
    margin: 0 0 6px 0;
}

.stat-networth__value {
    font-size: 2.15rem;
    font-weight: 700;
    color: var(--db-ink);
    margin: 0;
}

.stat-networth hr {
    border-top: 1px solid var(--db-border);
    margin: 16px 0;
}

.stat-row-list {
    text-align: left;
}

.stat-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 9px 0;
    border-bottom: 1px solid var(--db-border);
}

.stat-row:last-child {
    border-bottom: none;
}

.stat-row__label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--db-muted);
}

.stat-row__icon {
    width: 22px;
    height: 22px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
}

.stat-row--income .stat-row__icon {
    background: var(--db-income-bg);
    color: var(--db-income);
}

.stat-row--expense .stat-row__icon {
    background: var(--db-expense-bg);
    color: var(--db-expense);
}

.stat-row__value {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--db-ink);
}

.stat-row--income .stat-row__value {
    color: var(--db-income);
}

.stat-row--expense .stat-row__value {
    color: var(--db-expense);
}

#bank_table td {
    vertical-align: middle;
}

/* -- Generic (non-dashboard) page header ---------------------------------- */

.page-header-bar {
    padding-bottom: 14px;
    margin-bottom: 12px;
    border-bottom: 3px solid var(--db-primary);
}

.page-header-bar h1 {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--db-ink);
    margin: 0;
}

/* -- DataTables toolbar buttons -------------------------------------------- */

.dt-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}

.dt-buttons .btn,
.dt-buttons .dt-button {
    background: #ffffff;
    border: 1px solid var(--db-border);
    color: var(--db-ink);
    font-weight: 600;
    font-size: 0.82rem;
    padding: 8px 14px;
    border-radius: 8px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.05);
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.dt-buttons .btn i,
.dt-buttons .dt-button i {
    margin-right: 6px;
}

.dt-buttons .btn:hover,
.dt-buttons .dt-button:hover {
    background: var(--db-primary);
    border-color: var(--db-primary);
    color: #ffffff;
}

.dt-buttons #CreateGroupButton,
.dt-buttons #CreateLedgerButton {
    background: var(--db-primary);
    border-color: var(--db-primary);
    color: #ffffff;
}

.dt-buttons #CreateGroupButton:hover,
.dt-buttons #CreateLedgerButton:hover {
    background: var(--db-primary-dark);
    border-color: var(--db-primary-dark);
}

/* -- Chart of accounts / ledger-style tables -------------------------------- */

table.stripped {
    width: 100%;
    border-collapse: collapse;
}

table.stripped thead th {
    background: #f7f9fc;
    color: var(--db-muted);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 12px 14px;
    border-bottom: 2px solid var(--db-border);
    text-align: left;
}

.dark-mode table.stripped thead th {
    background: rgba(255, 255, 255, 0.04);
}

table.stripped tr td {
    padding: 9px 14px;
    border-top: none;
    border-bottom: 1px solid var(--db-border);
    font-size: 0.87rem;
    color: var(--db-ink);
    vertical-align: middle;
}

table.stripped tr:hover {
    background-color: #f3f6fb;
}

.dark-mode table.stripped tr:hover {
    background-color: rgba(255, 255, 255, 0.04);
}

table.stripped .tr-group {
    font-weight: 700;
    background: #fafbfd;
}

.dark-mode table.stripped .tr-group {
    background: rgba(255, 255, 255, 0.02);
}

table.stripped .tr-root-group {
    background: rgba(83, 74, 183, 0.07);
    color: var(--db-primary-dark);
    font-weight: 700;
}

.dark-mode table.stripped .tr-root-group {
    background: rgba(83, 74, 183, 0.2);
    color: #a9c0f5;
}

table.stripped .tr-ledger a {
    color: var(--db-primary);
    font-weight: 500;
    text-decoration: none;
}

table.stripped .tr-ledger a:hover {
    text-decoration: underline;
}

.td-actions {
    white-space: nowrap;
}

.td-actions a.no-hover {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 6px;
    font-size: 0.78rem;
    font-weight: 600;
    text-decoration: none !important;
    color: var(--db-primary);
}

.td-actions a.no-hover i {
    margin-right: 6px;
}

.td-actions a.no-hover:hover {
    background: rgba(83, 74, 183, 0.08);
}

.td-actions a[href*="delete"] {
    color: var(--db-expense);
}

.td-actions a[href*="delete"]:hover {
    background: var(--db-expense-bg);
}

/* Delete/void/issue actions in these actions columns used to be plain
   <a href> links, reachable (and triggerable) by just visiting the URL.
   They're now small inline <form method="post"> submit buttons instead
   (see MY_Controller::require_post() for why) - these rules make the
   button read identically to the .no-hover <a> icons it sits next to. */
.td-actions form {
    display: inline;
}

.td-actions button.no-hover {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border: none;
    border-radius: 6px;
    background: none;
    font-size: 0.78rem;
    font-weight: 600;
    font-family: inherit;
    line-height: inherit;
    text-decoration: none !important;
    color: var(--db-primary);
    cursor: pointer;
}

.td-actions button.no-hover i {
    margin-right: 6px;
}

.td-actions button.no-hover:hover {
    background: rgba(83, 74, 183, 0.08);
}

.td-actions button.no-hover.delete-action {
    color: var(--db-expense);
}

.td-actions button.no-hover.delete-action:hover {
    background: var(--db-expense-bg);
}

.link-pad {
    display: inline-block;
    width: 8px;
}

/* Chart of Accounts (Phase 2 QuickBooks-style rework, Aug 2026) - depth-based
   indentation via CSS padding on an empty inline span, replacing the old
   manual &nbsp; chain; the raw account code is muted/monospaced so the
   account name reads as the primary label, matching how QuickBooks
   de-emphasizes account numbers in its Chart of Accounts list. */
.coa-indent {
    display: inline-block;
}

.coa-code {
    color: var(--db-muted);
    font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
    font-size: 0.8rem;
}

table.stripped .tr-group .coa-code,
table.stripped .tr-root-group .coa-code {
    color: inherit;
}

/* Chart of Accounts header (Phase 3, Aug 2026) - title-left/actions-right
   layout matching every other list page (Invoices, Customers, Quotations)
   instead of the old DataTables toolbar floating on its own above the
   table. The actual buttons are still rendered by DataTables (Excel export
   needs its real button API) and just relocated in here via JS. */
.coa-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
}

.coa-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Cancel out the app-wide `div.dt-buttons { position: absolute !important; }`
   rule once the toolbar is relocated into .coa-actions - it needs to sit
   inline in the flex row, not floating over the page. */
.coa-actions div.dt-buttons {
    position: static !important;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Danger-toned sibling of .attention-banner (e.g. the Chart of Accounts'
   opening-balance mismatch notice) - same soft-tinted treatment, just in
   the app's expense/red tone instead of the neutral amber one. */
.attention-banner--danger {
    background: var(--db-expense-bg);
    border-left-color: var(--db-expense);
}

.attention-banner--danger .attention-banner__title i {
    color: var(--db-expense);
}

/* ==========================================================================
   Sales & Customers modules
   ========================================================================== */

/* Phase 7 (Aug 25 2026) - status/type badges restyled as tinted pills,
   matching the Dashboard's .status-pill language, so every status shown
   across Sales/Purchases/Vendors/Items/Customers (list + view pages)
   reads consistently app-wide. Single CSS edit - no view markup touched,
   same "leverage point" pattern as the rest of this cascade. */
.badge {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: 800;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 3px 10px;
    border-radius: 999px;
}

.badge.bg-success,
.badge.bg-green {
    color: var(--db-income) !important;
    background: var(--db-income-bg) !important;
}

.badge.bg-danger,
.badge.bg-red {
    color: var(--db-expense) !important;
    background: var(--db-expense-bg) !important;
}

.badge.bg-info,
.badge.bg-primary {
    color: var(--db-primary-dark) !important;
    background: rgba(83, 74, 183, 0.1) !important;
}

.badge.bg-secondary {
    color: var(--db-muted) !important;
    background: #eef1f5 !important;
}

.dark-mode .badge.bg-secondary {
    background: rgba(255, 255, 255, 0.06) !important;
}

/* Chart of Accounts: collapse/expand chevron on every group row (root
   category or nested sub-group like Equity). Chevron direction itself
   communicates state (down = expanded, right = collapsed), matching the
   toggle already used on the Invoices page's uninvoiced-quotations panel -
   no separate CSS collapsed state needed here. */
.coa-toggle {
    cursor: pointer;
    width: 12px;
    display: inline-block;
    margin-right: 6px;
    font-size: 0.7rem;
    color: var(--db-muted);
}

/* "Hide zero-balance accounts" switch, right-aligned above the table - a
   view option scoped to this table, not a page-level action, so it lives
   in the card body rather than next to Add Group/Add Ledger. */
.coa-toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 10px;
}

.coa-zero-toggle {
    margin-bottom: 0;
}

.coa-zero-toggle .custom-control-label {
    color: var(--db-muted);
    font-size: 0.85rem;
    cursor: pointer;
}

.coa-zero-toggle .custom-control-input:checked ~ .custom-control-label::before {
    background-color: var(--db-primary);
    border-color: var(--db-primary);
}

.sales-tabs {
    display: flex;
    align-items: center;
    gap: 4px;
    border-bottom: 1px solid var(--db-border);
    margin-bottom: 16px;
    padding: 0 4px;
}

.sales-tab {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 10px 16px;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--db-muted);
    border-bottom: 3px solid transparent;
    text-decoration: none !important;
}

.sales-tab:hover {
    color: var(--db-primary);
}

.sales-tab.active {
    color: var(--db-primary);
    border-bottom-color: var(--db-primary);
}

#item-table th {
    background: #f7f9fc;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--db-muted);
    padding: 8px 10px;
}

#item-table td {
    padding: 6px 10px;
    vertical-align: middle;
}

#item-table tfoot td {
    border-top: 2px solid var(--db-border);
    padding-top: 10px;
}

.dark-mode #item-table th {
    background: rgba(255, 255, 255, 0.04);
}

/* ==========================================================================
   Site-wide professional theme (Phase 4)
   Every existing CRUD/report/settings page in this app wraps its main panel
   in the same AdminLTE class pattern: `card card-primary card-outline`, with
   `table.stripped` for data tables and standard Bootstrap4 form/button
   markup. Restyling those shared selectors here brings Entries, Ledgers,
   Groups, Reports, Account Settings, Search, Login and Admin in line with
   the Dashboard/Accounts/Customers/Sales look with no per-page HTML changes.
   ========================================================================== */

/* -- Card shell (replaces AdminLTE's default colored top bar) ------------ */

.card.card-primary.card-outline,
.card.card-outline.card-primary {
    background: var(--db-card-bg);
    border: 1px solid var(--db-border);
    border-top: 1px solid var(--db-border) !important;
    border-radius: var(--db-radius);
    box-shadow: 0 1px 3px rgba(16, 24, 40, 0.06);
    transition: box-shadow 0.15s ease;
}

.card.card-primary.card-outline:hover,
.card.card-outline.card-primary:hover {
    box-shadow: 0 4px 14px rgba(16, 24, 40, 0.09);
}

/* Same reasoning as .dashboard-card above: give dark mode its own visible
   elevation instead of the light-tuned shadow. This is the shell used by
   Admin Settings, Entries, Ledgers, Groups, Reports, Account Settings and
   most other CRUD pages, so fixing it here reaches all of them at once.
   Resting state carries no drop shadow, only :hover does - a persistent
   shadow on every card of this type caused visible bar-shaped artifacts
   wherever two of them end up side by side (confirmed on .dashboard-card
   and .stat-tile elsewhere in this file), and this class is used widely
   enough across the app that it isn't safe to assume no page ever pairs
   two side by side. */
.dark-mode .card.card-primary.card-outline,
.dark-mode .card.card-outline.card-primary {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.dark-mode .card.card-primary.card-outline:hover,
.dark-mode .card.card-outline.card-primary:hover {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 8px 20px rgba(0, 0, 0, 0.4);
}

.card.card-primary.card-outline > .card-header,
.card.card-outline.card-primary > .card-header {
    background: transparent;
    border-bottom: 1px solid var(--db-border);
    padding: 14px 18px;
}

.card.card-primary.card-outline > .card-header .card-title,
.card.card-outline.card-primary > .card-header .card-title {
    font-size: 1rem;
    font-weight: 600;
    color: var(--db-ink);
}

.card.card-primary.card-outline > .card-body,
.card.card-outline.card-primary > .card-body {
    padding: 18px;
}

.card.card-primary.card-outline > .card-footer,
.card.card-outline.card-primary > .card-footer {
    background: #f9fafb;
    border-top: 1px solid var(--db-border);
    padding: 14px 18px;
}

.dark-mode .card.card-primary.card-outline > .card-footer,
.dark-mode .card.card-outline.card-primary > .card-footer {
    background: rgba(255, 255, 255, 0.03);
}

/* -- Buttons --------------------------------------------------------------- */

.btn {
    border-radius: 8px;
    font-weight: 500;
    transition: box-shadow 0.15s ease, transform 0.05s ease;
}

.btn-primary {
    background: var(--db-primary);
    border-color: var(--db-primary);
}

.btn-primary:hover,
.btn-primary:focus {
    background: var(--db-primary-dark);
    border-color: var(--db-primary-dark);
    box-shadow: 0 2px 8px rgba(83, 74, 183, 0.35);
}

.btn-primary:active {
    transform: translateY(1px);
}

.btn-group .dropdown-toggle,
.btn-group .btn {
    border-radius: 8px;
}

.dropdown-menu {
    border: 1px solid var(--db-border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(16, 24, 40, 0.12);
    padding: 6px;
}

.dropdown-item {
    border-radius: 6px;
    padding: 8px 12px;
    font-size: 0.9rem;
}

.dropdown-item:hover,
.dropdown-item:focus {
    background: rgba(83, 74, 183, 0.08);
    color: var(--db-primary-dark);
}

/* -- Forms ------------------------------------------------------------------ */

.content-wrapper {
    background: var(--db-page-bg);
}

.form-group label {
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--db-ink);
}

.form-control,
.custom-select {
    background-color: var(--db-input-bg);
    color: var(--db-ink);
    border-radius: 8px;
    border-color: var(--db-border);
}

.form-control:focus,
.custom-select:focus {
    border-color: var(--db-primary);
    box-shadow: 0 0 0 3px rgba(83, 74, 183, 0.15);
}

/* The focus glow above is tuned to the light-mode purple; in dark mode
   --db-primary switches to a paler lavender, so the glow gets its own
   rgba tuned to that color instead of inheriting the light-mode one. */
.dark-mode .form-control:focus,
.dark-mode .custom-select:focus {
    box-shadow: 0 0 0 3px rgba(175, 169, 236, 0.25);
}

.input-group-text {
    background: #f7f9fc;
    border-color: var(--db-border);
    color: var(--db-muted);
}

.dark-mode .input-group-text {
    background: rgba(255, 255, 255, 0.04);
}

/* Plain (non-iCheck) checkboxes and radios appear all over the app's
   settings/CRUD forms as bare native inputs. accent-color re-tints the
   native control to the brand purple with no markup changes, so every
   existing checkbox picks this up automatically, light or dark mode. */
input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--db-primary);
    width: 15px;
    height: 15px;
    cursor: pointer;
}

/* Sub-section headings inside a card body (e.g. "Email Settings" on the
   Admin Settings page) render as oversized default <h2>s today. Style
   them as a quiet section label instead, consistent in both themes. */
.card-body > h2 {
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--db-muted);
    margin: 8px 0 16px;
    padding-top: 20px;
    border-top: 1px solid var(--db-border);
}

/* -- Alerts ------------------------------------------------------------------ */

.alert {
    border: none;
    border-left: 4px solid transparent;
    border-radius: 8px;
}

.alert-danger {
    border-left-color: var(--db-expense);
}

.alert-success {
    border-left-color: var(--db-income);
}

.alert-warning {
    border-left-color: #c98a1f;
}

.alert-info {
    border-left-color: var(--db-primary);
}

/* "Needs attention" banner - a soft-tinted heads-up card (e.g. "N
   quotations ready to invoice" on the Invoices list), styled like the
   rest of the app's muted/tinted language rather than Bootstrap's solid
   .alert-warning fill, which clashes with everything else here. */
.attention-banner {
    background: var(--db-neutral-bg);
    border-left: 4px solid var(--db-neutral);
    border-radius: 8px;
    padding: 14px 18px;
    margin-bottom: 20px;
}

.attention-banner__title {
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--db-ink);
}

.attention-banner__title i {
    color: var(--db-neutral);
    margin-right: 6px;
}

.attention-banner table {
    background: transparent;
    margin-top: 8px;
}

.attention-banner table td {
    background: transparent;
    border-top: none;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
    padding: 8px 4px;
    font-size: 0.87rem;
    color: var(--db-ink);
}

.attention-banner table tr:last-child td {
    border-bottom: none;
}

.dark-mode .attention-banner table td {
    border-bottom-color: rgba(255, 255, 255, 0.08);
}

/* Full-width "strip" variant of the same banner (e.g. the Invoices list's
   "ready to invoice" notice) - a slim, QuickBooks-style bar that sits above
   the table. Collapsed it's just a single title row; clicking it expands a
   row of compact quotation "chips" underneath. */
.attention-banner--strip .attention-banner__body {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 12px;
}

.attention-banner--strip.is-collapsed .attention-banner__title {
    margin-bottom: 0;
}

.attention-banner--strip.is-collapsed .attention-banner__body {
    display: none;
}

.attention-banner__title--toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    cursor: pointer;
    user-select: none;
}

.attention-banner__chevron {
    color: var(--db-neutral);
    font-size: 0.78rem;
    margin-left: 10px;
    flex-shrink: 0;
}

.attention-banner__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex: 1 1 240px;
    max-width: 320px;
    background: rgba(255, 255, 255, 0.55);
    border: 1px solid rgba(0, 0, 0, 0.06);
    border-radius: 8px;
    padding: 10px 12px;
}

.attention-banner__item-number {
    display: block;
    font-weight: 700;
    font-size: 0.88rem;
    color: var(--db-primary-dark);
}

.attention-banner__item-meta {
    font-size: 0.8rem;
    color: var(--db-muted);
    line-height: 1.4;
}

.attention-banner__item-btn {
    flex-shrink: 0;
    white-space: nowrap;
}

.dark-mode .attention-banner__item {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.08);
}

/* At-a-glance summary bar (e.g. atop the Customers list) - a row of bold
   figures with a thin colored strip under each one, the same idea as
   QuickBooks' invoice/customer summary bars. Text row and color row are
   both 5-column grids so each figure lines up with its own strip. */
.stat-bar {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    column-gap: 20px;
    background: #f4f7fb;
    border-radius: var(--db-radius, 8px) var(--db-radius, 8px) 0 0;
    padding: 18px 20px 0;
    margin-bottom: 20px;
    overflow: hidden;
}

.dark-mode .stat-bar {
    background: rgba(255, 255, 255, 0.03);
}

.stat-bar__item {
    padding: 6px 8px 16px;
    margin: -6px -8px 0;
    min-width: 0;
    border-radius: 6px;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.stat-bar__item:hover {
    background: rgba(0, 0, 0, 0.04);
}

.stat-bar__item.is-active {
    background: rgba(0, 0, 0, 0.06);
}

.dark-mode .stat-bar__item:hover {
    background: rgba(255, 255, 255, 0.05);
}

.dark-mode .stat-bar__item.is-active {
    background: rgba(255, 255, 255, 0.08);
}

.stat-bar__hint {
    font-size: 0.78rem;
    color: var(--db-muted);
    margin: -14px 0 16px 4px;
}

.stat-bar__value {
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--db-ink);
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.stat-bar__label {
    font-size: 0.82rem;
    color: var(--db-muted);
    margin-top: 2px;
}

.stat-bar__bar {
    height: 6px;
    border-radius: 0 0 3px 3px;
    transition: height 0.15s ease;
}

.stat-bar__bar.is-active {
    height: 9px;
}

.stat-bar__bar--customers { background: #38bdf8; }
.stat-bar__bar--outstanding { background: var(--db-neutral); }
.stat-bar__bar--overdue { background: var(--db-expense); }
.stat-bar__bar--credit { background: #8b5cf6; }
.stat-bar__bar--paid { background: var(--db-income); }
.stat-bar__bar--unbilled { background: #14b8a6; }
.stat-bar__bar--vendors { background: #38bdf8; }

/* Vendors list stat bar (Sept 2026 - "i want the idea of the customer in
   the vendors") has 5 tiles, not the Customers bar's 6 (no vendor-side
   equivalent of "Unbilled Transactions" - see Purchases_model::
   get_vendor_summary_stats()), so it gets its own column count rather
   than leaving an empty 6th slot in the shared .stat-bar grid. */
#vendorStatBar {
    grid-template-columns: repeat(5, 1fr);
}

/* -- Report filter panels (jQuery UI accordion) ----------------------------- */

.ui-accordion .ui-accordion-header {
    background: #f7f9fc !important;
    border: 1px solid var(--db-border) !important;
    border-radius: 8px !important;
    color: var(--db-ink) !important;
    font-weight: 600;
    font-size: 0.88rem;
    padding: 10px 14px !important;
    margin-bottom: 8px;
}

.ui-accordion .ui-accordion-header .ui-icon {
    background: none;
}

.ui-accordion .ui-accordion-header.ui-state-active {
    border-color: var(--db-primary) !important;
    color: var(--db-primary-dark) !important;
}

.ui-accordion .ui-accordion-content {
    border: 1px solid var(--db-border) !important;
    border-top: none !important;
    border-radius: 0 0 8px 8px !important;
    background: transparent !important;
    margin-top: -8px;
    margin-bottom: 12px;
    padding: 16px !important;
}

.dark-mode .ui-accordion .ui-accordion-header {
    background: rgba(255, 255, 255, 0.03) !important;
}

/* -- Login page --------------------------------------------------------------- */

.login-page {
    /* ICT-company look, per explicit request (2026-09-08) - a repeating
       circuit-trace/node pattern over the base gradient. Note: this is a
       deliberate one-screen override of the brand spec's "no circuit
       board / network graph iconography" rule; the noon mark stays the
       actual brand identity elsewhere. Kept to brand colors only. */
    background-color: var(--db-primary-dark);
    background-image:
        url('../img/circuit-pattern.svg'),
        radial-gradient(circle at 85% 8%, rgba(175, 169, 236, 0.35) 0%, rgba(175, 169, 236, 0) 34%),
        radial-gradient(circle at 8% 92%, rgba(93, 202, 165, 0.3) 0%, rgba(93, 202, 165, 0) 30%),
        linear-gradient(135deg, var(--db-primary) 0%, var(--db-primary-dark) 100%);
    background-size: 240px 240px, auto, auto, auto;
    background-repeat: repeat, no-repeat, no-repeat, no-repeat;
    background-attachment: fixed;
    min-height: 100vh;
}

.login-box .card {
    border-radius: var(--db-radius);
    box-shadow: 0 12px 32px rgba(16, 24, 40, 0.22);
    border: none;
    overflow: hidden;
}

.login-box .card-header {
    border-bottom: none;
    padding-top: 24px;
}

.login-box .card-header .h1 {
    color: var(--db-primary-dark);
    font-weight: 700;
    text-decoration: none;
}

.login-box-msg {
    color: var(--db-muted);
}

/* -- Login page split-panel redesign (Sept 6 2026) - supersedes the plain
   centered card above (left in place, harmless) with a two-panel layout:
   a branded left panel and the actual form on the right. ------------------ */

.login-box.login-box--split {
    width: 100%;
    max-width: 780px;
    margin: 4% auto;
}

@keyframes nidaam-card-in {
    from {
        opacity: 0;
        transform: translateY(28px) scale(0.97);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.login-card {
    border-radius: var(--db-radius);
    box-shadow: 0 20px 48px rgba(16, 24, 40, 0.28);
    border: none;
    overflow: hidden;
    animation: nidaam-card-in 1.4s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@media (prefers-reduced-motion: reduce) {
    .login-card {
        animation: none;
    }
}

.login-card__aside {
    background: linear-gradient(160deg, var(--db-primary) 0%, var(--db-primary-dark) 100%);
    color: #fff;
    display: flex;
    align-items: center;
    position: relative;
}

.login-card__aside-inner {
    padding: 44px 34px;
}

.login-card__home-link {
    position: absolute;
    left: 34px;
    bottom: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    color: rgba(255, 255, 255, 0.75);
    font-size: 1rem;
    transition: background-color 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.login-card__home-link:hover,
.login-card__home-link:focus {
    background-color: rgba(255, 255, 255, 0.16);
    color: #fff;
    transform: translateX(-3px);
}

.login-card__brand-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 68px;
    height: 68px;
    font-size: 1.2rem;
    margin-bottom: 18px;
}

.login-card__brand-name {
    font-size: 1.3rem;
    font-weight: 800;
    margin-bottom: 10px;
    letter-spacing: -0.01em;
}

.login-card__brand-tagline {
    font-size: 0.9rem;
    opacity: 0.9;
    line-height: 1.6;
    margin: 0;
}

.login-card__form {
    padding: 40px 36px;
}

.login-card__title {
    font-size: 1.4rem;
    font-weight: 800;
    color: var(--db-ink);
    margin-bottom: 4px;
}

.login-card__label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--db-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 6px;
}

.login-card__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 18px;
}

.login-card__forgot {
    font-size: 0.85rem;
    color: var(--db-primary);
    font-weight: 600;
}

.login-card__forgot:hover {
    color: var(--db-primary-dark);
    text-decoration: underline;
}

.login-card__submit {
    border-radius: 8px;
    font-weight: 700;
    padding: 10px;
}

@media (max-width: 767px) {
    .login-card__aside {
        display: none;
    }
    .login-box.login-box--split {
        max-width: 400px;
    }
}

/* -- DataTables controls ------------------------------------------------------ */

.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select {
    border-radius: 8px;
    border-color: var(--db-border);
}

.dataTables_wrapper .paginate_button {
    border-radius: 6px !important;
}

.dataTables_wrapper .paginate_button.current {
    background: var(--db-primary) !important;
    border-color: var(--db-primary) !important;
    color: #fff !important;
}

/* -- Admin dashboard small-box KPI tiles ------------------------------------- */

.small-box.bg-secondary {
    background: linear-gradient(135deg, var(--db-primary) 0%, var(--db-primary-dark) 100%) !important;
    border-radius: var(--db-radius);
    box-shadow: 0 1px 3px rgba(16, 24, 40, 0.06);
    overflow: hidden;
    transition: box-shadow 0.15s ease, transform 0.1s ease;
}

.small-box.bg-secondary:hover {
    box-shadow: 0 6px 18px rgba(16, 24, 40, 0.18);
    transform: translateY(-2px);
}

.small-box .icon {
    opacity: 0.25;
}

/* ==========================================================================
   Site shell (Phase 5, Aug 25 2026) - "Clean SaaS dashboard" sidebar + topbar
   Supersedes the old dark-navy sidebar-dark-primary skin below (lines ~70-104)
   via source order + equal-or-higher selector specificity - that legacy block
   is left in place untouched (harmless, just overridden) rather than removed,
   in case any other skin variant still relies on it.
   ========================================================================== */

.main-sidebar {
    background: var(--db-sidebar-bg) !important;
    border-right: 1px solid var(--db-sidebar-border);
    box-shadow: none !important;
}

.main-sidebar .brand-link {
    border-bottom: 1px solid var(--db-sidebar-border);
    padding: 14px 16px;
    /* Sept 2026 - "move the Nidaam logo to the center": the inline
       text-align:center on this <a> (navbar.php) only ever centered
       the .brand-text span - AdminLTE's own ".brand-link .brand-image"
       rule (adminlte.css) floats the company-logo image left with its
       own margins, which pulls it out of that centered inline flow and
       pins it to the left edge regardless. Flexing this container (and
       cancelling that float/margin below) centers the logo and the
       "Nidaam" text together as one group, on every company. */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.main-sidebar .brand-link .brand-image {
    float: none;
    margin: 0;
}

.main-sidebar .brand-text {
    color: var(--db-primary-dark) !important;
    font-weight: 700;
    font-size: 1.02rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}

.main-sidebar .brand-mark-icon {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

.main-sidebar .brand-image {
    box-shadow: none;
    /* The account logo is a wide rectangular banner (mark + company name),
       not a square icon - AdminLTE's default "img-circle" class on this
       element (see navbar.php) clips it into a squashed oval and cuts the
       text off. Override to a plain rounded rectangle instead, and give it
       a bit more room than the default 33px so a wide logo stays legible. */
    border-radius: 6px !important;
    max-height: 42px;
    max-width: 130px;
    width: auto;
    object-fit: contain;
}

.nav-sidebar .nav-header {
    color: var(--db-sidebar-icon-muted) !important;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 16px 14px 6px 14px !important;
    background: transparent !important;
}

/* Sept 6 2026 (follow-up): the min-width:0 on the label <p> below was NOT
   enough by itself - it only lets the <p> shrink within .nav-link, but
   .nav-link's own ancestors (<li class="nav-item">, which is itself a flex
   ITEM of the column-direction flex container <ul class="nav-sidebar
   flex-column">) default to min-width:auto, i.e. "never shrink narrower
   than my content wants". Since the content includes a white-space:nowrap
   label, that "content width" is the label's FULL unwrapped width - so the
   <li> (and therefore the whole row) refused to shrink at all, no matter
   what the <p> itself was told to do, and just got hard-clipped with no
   "..." by .sidebar's overflow-x:hidden the moment anything (a revealed
   scrollbar, a narrower window, an extra menu item pushing things around)
   left less room than the longest label needed. That hard clip-with-no-
   ellipsis, appearing right when the sidebar's content height/width shifts
   (e.g. landing on Commissions), is what was reported as the sidebar
   "looking wrong" / "bouncing". Fix: give every ancestor in that chain
   permission to shrink (min-width: 0) and cap it to its parent's box
   (max-width: 100%) so the space the <p> actually gets to work with is the
   real available width, not the label's natural width. */
.nav-sidebar,
.nav-sidebar > .nav-item,
.nav-sidebar .nav-treeview,
.nav-sidebar .nav-treeview > .nav-item {
    min-width: 0;
    max-width: 100%;
}

.nav-sidebar > .nav-item > .nav-link {
    color: var(--db-muted) !important;
    border-radius: 9px;
    margin: 2px 8px;
    padding: 9px 12px;
    font-size: 0.87rem;
    font-weight: 500;
    /* Flex row instead of AdminLTE's default inline icon+text flow (Sept 6
       2026) - a long label (Compare Companies, System Settings) used to
       hard-clip mid-word with no ellipsis once the sidebar's own vertical
       scrollbar (it gains one as soon as there are enough menu items to
       overflow the viewport height - e.g. after adding a new module like
       Commissions) ate into the available width. min-width: 0 on the <p>
       below is what actually lets a flex child shrink and truncate rather
       than force its content width on the row - see the min-width: 0 rule
       just above for why that alone wasn't sufficient. */
    display: flex !important;
    align-items: center;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
}

.nav-sidebar .nav-icon {
    color: var(--db-sidebar-icon-muted);
    font-size: 0.95rem;
    margin-right: 10px;
    opacity: 1;
    flex: 0 0 auto;
}

.nav-sidebar > .nav-item > .nav-link p,
.nav-sidebar .nav-treeview > .nav-item > .nav-link p {
    display: inline-block;
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
}

[class*=sidebar-dark-] .nav-sidebar > .nav-item > .nav-link:hover,
[class*=sidebar-dark-] .nav-sidebar > .nav-item > .nav-link:focus,
[class*=sidebar-dark-] .nav-sidebar > .nav-item:hover > .nav-link {
    background: rgba(83, 74, 183, 0.07) !important;
    color: var(--db-primary) !important;
}

[class*=sidebar-dark-] .nav-sidebar > .nav-item > .nav-link.active,
.nav-sidebar > .nav-item > .nav-link.active {
    background: var(--db-sidebar-active-bg) !important;
    color: var(--db-sidebar-active-ink) !important;
    font-weight: 700;
}

.nav-sidebar > .nav-item > .nav-link.active .nav-icon {
    color: var(--db-sidebar-active-ink) !important;
}

[class*=sidebar-dark-] .nav-sidebar > .nav-item.menu-open > .nav-link,
[class*=sidebar-dark-] .nav-sidebar > .nav-item.menu-open > .nav-link:hover {
    background: transparent !important;
    color: var(--db-ink) !important;
}

.nav-sidebar .nav-treeview {
    background: transparent !important;
}

.nav-sidebar .nav-treeview > .nav-item > .nav-link {
    color: var(--db-muted) !important;
    padding: 7px 12px 7px 40px;
    font-size: 0.83rem;
    margin: 1px 8px;
    border-radius: 8px;
    display: flex !important;
    align-items: center;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
}

.nav-sidebar .nav-treeview > .nav-item > .nav-link .nav-icon {
    font-size: 0.4rem;
    color: var(--db-sidebar-icon-muted);
    flex: 0 0 auto;
}

.nav-sidebar .nav-treeview > .nav-item > .nav-link.active {
    background: var(--db-sidebar-active-bg) !important;
    color: var(--db-sidebar-active-ink) !important;
    font-weight: 700;
}

/* AdminLTE hides the sidebar's own scrollbar at 0 width and only reveals it
   (adminlte.css: .sidebar:hover::-webkit-scrollbar { width: .5rem }) on
   mouse hover. Once the sidebar has enough items to need scrolling at all
   (true since Commissions was added), moving the mouse onto the sidebar to
   click a link makes that scrollbar pop in instantly, eating into the
   content width right as the row's label is trying to render/re-render -
   a likely contributor to the sidebar visibly "jumping" on click. Keeping
   the scrollbar width constant (shown thin at all times instead of
   0 -> .5rem on hover) removes that width change entirely, on top of the
   min-width/max-width fix above which keeps any remaining width change
   from ever hard-clipping a label. */
.sidebar {
    scrollbar-width: thin !important;
}

.sidebar::-webkit-scrollbar {
    width: 6px !important;
}

.sidebar:hover::-webkit-scrollbar {
    width: 6px !important;
}

.sidebar-footer-card {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 14px 12px 10px 12px;
    padding: 10px;
    border-radius: 10px;
    background: rgba(83, 74, 183, 0.05);
}

.dark-mode .sidebar-footer-card {
    background: rgba(255, 255, 255, 0.04);
}

.sidebar-footer-card__avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.sidebar-footer-card__body {
    min-width: 0;
}

.sidebar-footer-card__name {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--db-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-footer-card__role {
    font-size: 0.72rem;
    color: var(--db-muted);
}

/* -- Topbar ---------------------------------------------------------------- */

.main-header.navbar {
    background: var(--db-topbar-bg) !important;
    border-bottom: 1px solid var(--db-border);
    box-shadow: none;
}

.main-header .nav-link {
    color: var(--db-muted);
}

.main-header .nav-link:hover {
    color: var(--db-ink);
}

/* In dark mode the topbar's search icon, "Active Account" pill, username,
   and the icon buttons (bell, fullscreen, dark-mode toggle, etc.) all sit
   on the same --db-muted gray as everywhere else - readable, but low
   contrast against the dark topbar, and the icons in particular (which
   inherit this as currentColor with no fill/stroke of their own) end up
   looking dim rather than crisp. Sept 8 2026: user asked for these
   whited out. --db-ink is used instead of a literal #fff so it stays in
   step with the token system (it already resolves to a near-white
   #eef1f5 in dark mode - the same shade every other high-contrast label
   on the page uses). */
.dark-mode .main-header .nav-link,
.dark-mode .main-header .nav-link i,
.dark-mode .topbar-search,
.dark-mode .topbar-account-pill {
    color: var(--db-ink);
}

/* Nidaam platform brand mark, centered in the topbar (Sept 2026) -
   separate from the per-company logo, which stays in the sidebar's own
   ".main-sidebar .brand-link" (see the comment there). ".navbar" is
   already "position: relative" (Bootstrap's own base rule, adminlte.css),
   so this sits absolutely centered over the left/right <ul>s without
   needing a third flex zone or touching AdminLTE's own navbar layout.
   Hidden below the same breakpoint the search box already hides at
   (d-md-flex, above) - the topbar isn't wide enough below that for a
   floating center element not to collide with the search box or the
   account pill/icon buttons. */
.topbar-brand {
    display: none;
    align-items: center;
    gap: 8px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    color: var(--db-ink) !important;
    text-decoration: none !important;
    font-weight: 700;
    font-size: 1rem;
    letter-spacing: -0.01em;
}

.topbar-brand:hover {
    color: var(--db-primary) !important;
}

.topbar-brand__icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

@media (min-width: 768px) {
    .topbar-brand {
        display: inline-flex;
    }
}

.topbar-search {
    display: flex;
    align-items: center;
    gap: 9px;
    background: #f7f9fc;
    border: 1px solid var(--db-border);
    border-radius: 9px;
    padding: 7px 14px;
    width: 320px;
    margin-left: 10px;
    color: var(--db-muted);
    /* Sept 2026 - the centered ".topbar-brand" mark added alongside this
       box is position:absolute and can visually/pointer-wise overlap this
       box's right edge on narrower window widths (it's centered on the
       whole navbar, not the space left of it). Keep this box on top so a
       click or keystroke here always reaches the search input rather
       than the decorative brand link sitting over it. */
    position: relative;
    z-index: 2;
}

.dark-mode .topbar-search {
    background: rgba(255, 255, 255, 0.04);
}

.topbar-search i {
    font-size: 0.82rem;
}

.topbar-search__input {
    border: none;
    background: transparent;
    outline: none;
    font-size: 0.85rem;
    color: var(--db-ink);
    width: 100%;
}

/* Actual pill/chip visual treatment (Sept 2026 navbar redesign) - this
   class existed before but had no background/radius/padding of its own
   despite the name. The existing ".dark-mode .topbar-account-pill"
   color override further up this file has higher specificity (two
   classes vs. one) than the plain color set here, so dark mode still
   wins and keeps the "whited out" look that was asked for on Sept 8 -
   only the background needs its own dark-mode variant, added below. */
.topbar-account-pill {
    display: flex !important;
    align-items: center;
    gap: 4px;
    font-size: 0.8rem;
    padding: 6px 12px;
    border-radius: 999px;
    background: rgba(83, 74, 183, 0.08);
    color: var(--db-primary-dark);
    transition: background-color 0.15s ease;
}

.topbar-account-pill:hover {
    background: rgba(83, 74, 183, 0.14);
}

.dark-mode .topbar-account-pill {
    background: rgba(255, 255, 255, 0.08);
}

.dark-mode .topbar-account-pill:hover {
    background: rgba(255, 255, 255, 0.14);
}

.topbar-account-pill strong {
    margin-left: 4px;
}

/* Small dropdown under the "Active Account" pill (navbar.php) - replaces
   what used to be a full-page navigation to the company picker for the
   everyday case of just switching companies. Kept intentionally compact
   (a fixed, narrow width instead of the dropdown-menu default) since it's
   normally only listing 2-4 companies. */
.company-switcher {
    min-width: 230px;
    max-width: 280px;
    padding: 6px;
}

.company-switcher__header {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--db-muted);
    padding: 6px 12px 8px;
}

.company-switcher__item {
    display: flex !important;
    align-items: center;
    gap: 8px;
    font-size: 0.88rem;
}

.company-switcher__item--active {
    color: var(--db-income) !important;
    font-weight: 600;
}

/* Icon swap for the active row above - check mark at rest, "step out"
   arrow on hover, so a real link doesn't read as a dead-end checkmark.
   The generic ".dropdown-item:hover" background elsewhere in this file
   already gives the row its hover feedback. */
.company-switcher__item-icon--hover {
    display: none;
}

.company-switcher__item--active:hover .company-switcher__item-icon--default {
    display: none;
}

.company-switcher__item--active:hover .company-switcher__item-icon--hover {
    display: inline-block;
}

.company-switcher__manage {
    display: flex !important;
    align-items: center;
    gap: 8px;
    font-size: 0.82rem;
    color: var(--db-muted);
}

/* Circular hover chrome for the topbar icon buttons (bell, fullscreen,
   dark-mode toggle - navbar.php). Previously only the bell carried this
   class; Sept 2026 navbar redesign extends it to all three for visual
   consistency (matching the target mockup's rounded icon buttons) -
   .nav-link already has no horizontal padding here (see AdminLTE's
   ".navbar-nav .nav-link" override), so a fixed width/height centers
   cleanly without fighting inherited padding. */
.topbar-icon-btn {
    display: flex !important;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    margin: 0 1px;
    border-radius: 50%;
    transition: background-color 0.15s ease;
}

.topbar-icon-btn:hover {
    background: rgba(83, 74, 183, 0.08);
}

.dark-mode .topbar-icon-btn:hover {
    background: rgba(255, 255, 255, 0.08);
}

.main-header .user-image {
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--db-border);
}

/* Initials-circle avatar fallback (Sept 2026 - see
   FunctionsCore::userAvatarHtml()): shown instead of a broken <img>
   when the user has no uploaded photo. Most of the surrounding photo
   sizing (.user-image, .img-circle, .sidebar-footer-card__avatar) is
   already written as a plain class selector, so this <span> inherits
   it for free by carrying the same classes the <img> used to. The one
   exception is the dropdown-header avatar (".user-header img" below,
   in the "outrank AdminLTE" block) - that's element-scoped and can
   never match a <span>, so its 36px sizing/ring is repeated here. */
.avatar-initials {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    background: var(--db-primary);
    color: #ffffff;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1;
    user-select: none;
}

.main-header .user-image.avatar-initials {
    font-size: 0.72rem;
}

.sidebar-footer-card__avatar.avatar-initials {
    font-size: 0.72rem;
}

.user-menu .user-header .avatar-initials {
    width: 36px !important;
    height: 36px !important;
    border: none !important;
    box-shadow: 0 0 0 2px var(--db-primary);
    flex-shrink: 0;
    font-size: 0.85rem;
}

/* -- Non-dashboard page header ---------------------------------------------- */

.page-header-bar {
    padding-bottom: 12px;
    margin-bottom: 16px;
    border-bottom: 1px solid var(--db-border);
}

.page-header-bar h1 {
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--db-ink);
    margin: 0;
    letter-spacing: -0.01em;
}

/* -- Toastr restyle to match the token system -------------------------------- */

#toast-container > div {
    border-radius: 10px !important;
    box-shadow: var(--db-shadow-md) !important;
    opacity: 1 !important;
    padding: 14px 16px 14px 52px !important;
}

#toast-container > .toast-success {
    background-color: #ffffff !important;
    background-image: none !important;
    border-left: 4px solid var(--db-income) !important;
    color: var(--db-ink) !important;
}

#toast-container > .toast-error {
    background-color: #ffffff !important;
    background-image: none !important;
    border-left: 4px solid var(--db-expense) !important;
    color: var(--db-ink) !important;
}

#toast-container > .toast-warning {
    background-color: #ffffff !important;
    background-image: none !important;
    border-left: 4px solid var(--db-neutral) !important;
    color: var(--db-ink) !important;
}

#toast-container > .toast-info {
    background-color: #ffffff !important;
    background-image: none !important;
    border-left: 4px solid var(--db-primary) !important;
    color: var(--db-ink) !important;
}

#toast-container > div:before {
    position: absolute;
    left: 16px;
    top: 14px;
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 18px;
}

#toast-container > .toast-success:before { content: "\f058"; color: var(--db-income); }
#toast-container > .toast-error:before { content: "\f057"; color: var(--db-expense); }
#toast-container > .toast-warning:before { content: "\f06a"; color: var(--db-neutral); }
#toast-container > .toast-info:before { content: "\f05a"; color: var(--db-primary); }

#toast-container > div .toast-title {
    color: var(--db-ink) !important;
    font-weight: 700;
}

#toast-container > div .toast-message {
    color: var(--db-muted) !important;
}

/* -- Footer ------------------------------------------------------------------ */

.main-footer {
    background: var(--db-topbar-bg);
    border-top: 1px solid var(--db-border);
    color: var(--db-muted);
    font-size: 0.82rem;
}

/* ==========================================================================
   Dashboard rebuild (Phase 6, Aug 25 2026) - stat tiles, list rows, chart
   legend/toolbar cleanup. All data behind these is real (Dashboard.php),
   nothing here is decorative-only except the tile delta arrows' color coding.
   ========================================================================== */

.stat-tile-grid {
    display: grid;
    /* 4-up (Sept 2026 redesign - was 3-up): Cash & Bank moved out into its
       own hero card above this grid (see .hero-row), and AR/AP merged into
       one "Receivable / Payable" tile, so the remaining Income/Expense/Net
       Profit/Receivable-Payable set fits a 4-column row cleanly. */
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 18px;
    margin-bottom: 20px;
}

@media (max-width: 991px) {
    .stat-tile-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 575px) {
    .stat-tile-grid {
        grid-template-columns: 1fr;
    }
}

.stat-tile {
    position: relative;
    overflow: hidden;
    background: #ffffff;
    border: 1px solid var(--db-border);
    border-radius: var(--db-radius);
    box-shadow: var(--db-shadow-sm);
    padding: 18px 20px;
    display: block;
    text-decoration: none;
    color: inherit;
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}

/* Sept 2026 redesign: a colored top accent bar per tile, matching the
   "modern SaaS" treatment already used on the Admin System Dashboard's
   .admin-tile (see below) but in this page's own income/expense/primary/
   neutral tokens rather than that page's indigo/blue brand. Each modifier
   sets --tile-accent; .stat-tile itself falls back to plain primary so a
   tile with no modifier class still renders sensibly. */
.stat-tile::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: var(--tile-accent, var(--db-primary));
}

.stat-tile--income { --tile-accent: linear-gradient(90deg, #1e8e57, #34d399); }
.stat-tile--expense { --tile-accent: linear-gradient(90deg, #d64545, #fb7185); }
.stat-tile--neutral { --tile-accent: linear-gradient(90deg, #c98a1f, #fbbf24); }
.stat-tile--primary { --tile-accent: linear-gradient(90deg, #534AB7, #8f87e0); }

/* The one tile that isn't a link (Receivable / Payable combines two
   destinations - Customers and Vendors - so it doesn't pick one) skips
   the link-only hover lift below and just shows a default cursor. */
.stat-tile--static { cursor: default; }

/* Stat tiles are now links into the report/list backing their figure -
   a visible hover state is the only cue a plain-looking card is clickable. */
a.stat-tile:hover, a.stat-tile:focus {
    box-shadow: 0 4px 14px rgba(0,0,0,0.10);
    transform: translateY(-1px);
}

/* Previously "background: transparent" here, which is why dark mode
   read as flat/murky (Sept 8 2026 user feedback: "I'm not happy with
   the dark mode") - with no distinct panel behind them, all 6 dashboard
   stat tiles blended straight into the page background and lost their
   card boundaries entirely. Give them the same elevated surface as every
   other card on the page instead.
   No resting-state drop shadow here, unlike .dashboard-card - these 6
   tiles sit 3-up in a grid (.stat-tile-grid) with small gaps on every
   side, all visible and "elevated" at once. A first pass gave every tile
   the same drop shadow as the full-width cards; because adjacent tiles
   sit close together, their individual shadows blurred sideways into
   each other and merged into one continuous gray band running across
   the whole row instead of reading as separate cards (confirmed by
   zooming into a follow-up screenshot - shrinking the blur only made a
   smaller version of the same band, it didn't remove it). Definition
   comes from the background/border contrast alone at rest; the drop
   shadow only appears on :hover, where just one tile lifts at a time
   with nothing beside it to blend into. */
.dark-mode .stat-tile {
    background: var(--db-card-bg);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.dark-mode a.stat-tile:hover, .dark-mode a.stat-tile:focus {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 4px 12px rgba(0, 0, 0, 0.4);
}

.stat-tile__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
}

.stat-tile__label {
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--db-muted);
}

.stat-tile__icon {
    width: 34px;
    height: 34px;
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    flex-shrink: 0;
    /* Sept 2026 redesign: filled gradient badge with a white glyph (paired
       with the .stat-tile--* modifiers above), replacing the older tinted-
       background/colored-glyph treatment further below (.stat-tile__icon--*
       - left in place, unused now that every tile sets its variant on the
       tile itself, but harmless). */
    color: #ffffff;
    background: var(--tile-accent, var(--db-primary));
}

/* Superseded by the .stat-tile--income/--expense/--primary/--neutral
   modifiers above (Sept 2026 redesign) - no longer applied by
   user/dashboard.php's markup, left here unused rather than removed since
   nothing else in the app references .stat-tile__icon--* (confirmed: the
   class only ever appears on this one page). */
.stat-tile__icon--income { background: var(--db-income-bg); color: var(--db-income); }
.stat-tile__icon--expense { background: var(--db-expense-bg); color: var(--db-expense); }
.stat-tile__icon--primary { background: rgba(83, 74, 183, 0.1); color: var(--db-primary); }
.stat-tile__icon--neutral { background: var(--db-neutral-bg); color: var(--db-neutral); }

.stat-tile__value {
    /* 1.3rem, was 1.5rem - the grid went 3-up to 4-up (Sept 2026 redesign),
       and the combined "Receivable / Payable" tile's two currency values
       need the extra room to avoid wrapping awkwardly on a narrow tile. */
    font-size: 1.3rem;
    font-weight: 800;
    color: var(--db-ink);
    letter-spacing: -0.015em;
    margin-bottom: 4px;
}

/* Sept 2026 redesign: plain muted caption, replacing the colored pill
   treatment below (.stat-tile__note--income etc, left in place unused -
   same reasoning as .stat-tile__icon--* above) now that the tile's own
   top accent bar + icon already carry the color coding. */
.stat-tile__note {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--db-muted);
}

.stat-tile__note--income { color: var(--db-income); background: var(--db-income-bg); padding: 3px 8px; border-radius: 6px; }
.stat-tile__note--expense { color: var(--db-expense); background: var(--db-expense-bg); padding: 3px 8px; border-radius: 6px; }
.stat-tile__note--neutral { color: var(--db-neutral); background: var(--db-neutral-bg); padding: 3px 8px; border-radius: 6px; }

/* -- Dashboard "Needs your attention" panel + hero card (Sept 2026
   redesign) - the two cards that sit above .stat-tile-grid on the
   per-account dashboard. Grid, not Bootstrap .row/.col-*, matching how
   .stat-tile-grid just above is already built - see its own comment. */

.hero-row {
    display: grid;
    grid-template-columns: 1.3fr 1fr;
    gap: 18px;
    margin-bottom: 20px;
}

@media (max-width: 991px) {
    .hero-row {
        grid-template-columns: 1fr;
    }
}

.hero-card {
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, var(--db-primary) 0%, var(--db-primary-dark) 100%);
    border-radius: 16px;
    padding: 22px 24px;
    color: #ffffff;
    box-shadow: var(--db-shadow-md);
}

/* Purely decorative corner glow, same treatment on the gradient hero card
   whether the page is in light or dark mode - the card's own colors don't
   change with the theme, so no dark-mode override is needed here. */
.hero-card::after {
    content: "";
    position: absolute;
    right: -60px;
    top: -60px;
    width: 220px;
    height: 220px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.07);
}

.hero-card__label {
    font-size: 0.8rem;
    font-weight: 700;
    opacity: 0.85;
    display: flex;
    align-items: center;
    gap: 8px;
    position: relative;
}

.hero-card__value {
    font-size: 2.3rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    margin: 10px 0 6px;
    position: relative;
}

.hero-card__trend {
    font-size: 0.8rem;
    font-weight: 700;
    opacity: 0.92;
    display: flex;
    align-items: center;
    gap: 6px;
    position: relative;
}

.hero-card__trend .fa-arrow-up { color: #8ff0c0; }
.hero-card__trend .fa-arrow-down { color: #ffb4b4; }

.hero-card__spark {
    display: block;
    margin-top: 16px;
    width: 100%;
    height: 44px;
    position: relative;
}

.attention-card {
    background: var(--db-card-bg);
    border: 1px solid var(--db-border);
    border-radius: 16px;
    padding: 18px 20px;
    box-shadow: var(--db-shadow-sm);
    display: flex;
    flex-direction: column;
}

.attention-card__title {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--db-ink);
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}

.attention-card__title i { color: var(--db-neutral); }

.attention-empty {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--db-muted);
    font-size: 0.85rem;
    padding: 16px 0;
}

.attention-empty i { color: var(--db-income); }

.attention-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--db-border);
    text-decoration: none;
    color: inherit;
}

.attention-row:last-child { border-bottom: none; }

.attention-row__left {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.attention-row__icon {
    width: 32px;
    height: 32px;
    border-radius: 9px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    flex-shrink: 0;
}

.attention-row__icon--expense { background: var(--db-expense-bg); color: var(--db-expense); }
.attention-row__icon--neutral { background: var(--db-neutral-bg); color: var(--db-neutral); }

.attention-row__name {
    font-size: 0.83rem;
    font-weight: 700;
    color: var(--db-ink);
}

.attention-row__sub {
    font-size: 0.74rem;
    color: var(--db-muted);
    margin-top: 1px;
}

.attention-row__amount {
    font-size: 0.85rem;
    font-weight: 800;
    color: var(--db-ink);
    flex-shrink: 0;
}

.attention-row__amount--expense { color: var(--db-expense); }

/* Sept 28 2026 - sub-heading for "Unbilled, by customer" and the
   "+ N more" link under it. */
.attention-group {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--db-muted);
    padding: 12px 0 2px;
    border-top: 1px solid var(--db-border);
}
.attention-card > .attention-group:nth-child(2) { border-top: none; padding-top: 4px; }
.attention-more {
    display: block;
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--db-neutral);
    padding: 8px 0 2px;
    text-decoration: none;
}
.attention-more:hover { text-decoration: underline; }

/* -- Dashboard "Recent Activity" feed (Sept 2026 redesign) - replaces the
   old invoices-only .list-row usage on this page (still defined above,
   left unused - see that section's own note) with one merged feed across
   invoices, bills, and both directions of payment. */

.activity-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 11px 6px;
    border-radius: 10px;
    text-decoration: none;
    color: inherit;
}

.activity-row:hover { background: #f7f9fc; }
.dark-mode .activity-row:hover { background: rgba(255, 255, 255, 0.03); }

.activity-icon {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 13px;
    flex-shrink: 0;
}

.activity-icon--invoice { background: var(--db-accent-bg); color: var(--db-accent); }
.activity-icon--bill { background: var(--db-neutral-bg); color: var(--db-neutral); }
.activity-icon--payment { background: var(--db-income-bg); color: var(--db-income); }

.activity-main {
    flex: 1;
    min-width: 0;
}

.activity-name {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--db-ink);
}

.activity-sub {
    font-size: 0.75rem;
    color: var(--db-muted);
    margin-top: 1px;
}

.activity-amount {
    font-size: 0.85rem;
    font-weight: 800;
    color: var(--db-ink);
}

.activity-amount--income { color: var(--db-income); }
.activity-amount--expense { color: var(--db-expense); }

/* -- Admin "System Dashboard" (application/views/admin/dashboard.php) --
   Modern SaaS treatment (Stripe/Linear-style): gradient icon badges, a
   colored top accent bar per card, bold oversized numbers, soft-pill
   status badges. Originally written as a deliberately bolder look than
   the per-account Dashboard's own .stat-tile (Aug 29 2026: "modern SaaS
   dashboard ... like Stripe/Linear"); the Sept 2026 per-account redesign
   above (.hero-card, .stat-tile's own new top-accent-bar treatment) brings
   the same visual language there too, so the two pages now read as one
   consistent system rather than two different ones. */

.admin-tile {
    position: relative;
    display: flex;
    align-items: center;
    gap: 16px;
    height: 100%;
    background: #ffffff;
    border: 1px solid rgba(16, 24, 40, 0.04);
    border-radius: 16px;
    box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04), 0 8px 24px rgba(16, 24, 40, 0.06);
    padding: 22px;
    text-decoration: none;
    overflow: hidden;
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.admin-tile::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: var(--admin-tile-accent, linear-gradient(90deg, #6366f1, #3b82f6));
}

.admin-tile:hover,
.admin-tile:focus {
    box-shadow: 0 4px 8px rgba(16, 24, 40, 0.06), 0 16px 32px rgba(16, 24, 40, 0.12);
    transform: translateY(-3px);
    text-decoration: none;
}

.dark-mode .admin-tile {
    background: #232a35;
    border-color: rgba(255, 255, 255, 0.06);
}

.admin-tile__icon {
    width: 52px;
    height: 52px;
    border-radius: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.35rem;
    color: #ffffff;
    flex-shrink: 0;
    box-shadow: 0 6px 14px -4px rgba(0, 0, 0, 0.28);
}

.admin-tile--primary { --admin-tile-accent: linear-gradient(90deg, #6366f1, #3b82f6); }
.admin-tile--primary .admin-tile__icon { background: linear-gradient(135deg, #6366f1, #3b82f6); }

.admin-tile--income { --admin-tile-accent: linear-gradient(90deg, #10b981, #34d399); }
.admin-tile--income .admin-tile__icon { background: linear-gradient(135deg, #10b981, #34d399); }

.admin-tile--neutral { --admin-tile-accent: linear-gradient(90deg, #f59e0b, #fbbf24); }
.admin-tile--neutral .admin-tile__icon { background: linear-gradient(135deg, #f59e0b, #fbbf24); }

.admin-tile--expense { --admin-tile-accent: linear-gradient(90deg, #f43f5e, #fb7185); }
.admin-tile--expense .admin-tile__icon { background: linear-gradient(135deg, #f43f5e, #fb7185); }

.admin-tile__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.admin-tile__title {
    font-size: 1.85rem;
    font-weight: 800;
    color: var(--db-ink);
    letter-spacing: -0.02em;
    line-height: 1.1;
}

.admin-tile__desc {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--db-muted);
    margin-top: 5px;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    line-height: 1.35;
}

.admin-quicklinks {
    margin-bottom: 6px;
}

.admin-quicklinks > [class*="col-"] {
    display: flex;
}

/* Account list card - same gradient top-accent motif as the tiles above,
   so the whole dashboard reads as one system. */
.admin-account-card {
    position: relative;
    overflow: hidden;
}

.admin-account-card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, #6366f1, #3b82f6);
}

.admin-account-card > .card-header {
    padding-top: 20px;
}

.admin-account-card .dashboard-card__title {
    font-size: 1.1rem;
}

.admin-active-account {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--db-muted);
}

.admin-active-account strong {
    color: var(--db-ink);
    font-weight: 800;
}

.admin-accountlist-note {
    font-size: 0.85rem;
    margin-bottom: 14px;
}

/* Soft "pill" status badges - Stripe-style muted background + colored
   text, instead of AdminLTE's solid-fill .badge-*. Scoped to this table
   only so the change doesn't ripple into badges used elsewhere in the
   app. */
.admin-account-card .badge {
    font-size: 0.72rem;
    font-weight: 700;
    padding: 5px 10px;
    border-radius: 999px;
    letter-spacing: 0.01em;
}

.admin-account-card .badge-success { background: var(--db-income-bg); color: var(--db-income); }
.admin-account-card .badge-warning { background: var(--db-neutral-bg); color: var(--db-neutral); }
.admin-account-card .badge-danger { background: var(--db-expense-bg); color: var(--db-expense); }
.admin-account-card .badge-secondary { background: rgba(107, 118, 132, 0.12); color: var(--db-muted); }

.dark-mode .admin-account-card .badge-secondary { background: rgba(255, 255, 255, 0.08); }

/* -- Generic "modern SaaS" gradient top-accent card, reusable on any
   .dashboard-card (first used on Entries::index() per user request Aug 29
   2026 to extend the admin-dashboard restyle to the Entries section). */
.dashboard-card--accent {
    position: relative;
    overflow: hidden;
}

.dashboard-card--accent::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, #6366f1, #3b82f6);
}

.dashboard-card--accent > .card-header {
    padding-top: 20px;
}

/* -- Gradient action buttons - opt-in classes (added alongside, not
   replacing, Bootstrap's .btn-primary/.btn-info) so this stays scoped to
   the buttons that ask for it instead of re-theming every button app-wide. */
.btn-gradient {
    border: none;
    color: #ffffff;
    font-weight: 600;
    box-shadow: 0 4px 10px -2px rgba(0, 0, 0, 0.18);
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}

.btn-gradient:hover,
.btn-gradient:focus {
    color: #ffffff;
    transform: translateY(-1px);
    box-shadow: 0 8px 18px -4px rgba(0, 0, 0, 0.26);
    filter: brightness(1.05);
}

.btn-gradient:active {
    color: #ffffff;
    filter: brightness(0.97);
    transform: translateY(0);
}

.btn-gradient-primary { background: linear-gradient(135deg, #6366f1, #3b82f6); }
.btn-gradient-teal { background: linear-gradient(135deg, #10b981, #34d399); }
.btn-gradient-green { background: linear-gradient(135deg, #1e8e57, #34d399); }
.btn-gradient-red { background: linear-gradient(135deg, #c0392b, #d64545); }

/* -- "Add/Edit Journal Entry" screen (entries/add2.php, edit2.php) - Aug 29
   2026 per explicit user request: "make it exactly as quickbooks journal
   entry", reworked further Sept 5 2026 per explicit follow-up feedback
   ("not happy with this style" - the Aug 29 pass still made you pick
   Debit/Credit from a dropdown and click "+" to lock a line in before
   starting the next one, which isn't how QuickBooks actually works).
   Every row in #entryitems is still a live, simultaneously-editable grid
   line from the moment the page loads - type straight into Debit or
   Credit, whichever applies (see add2.php/edit2.php's dr-item/cr-item
   handling) - none of that JS-hooked behavior changed here.

   Sept 18 2026 - explicit follow-up: "totally don't like how the journal
   entry looks... keep the idea and change how it looks". First pass:
   columns/inputs/JS left untouched (still .qb-je-table / .je-* /
   .dr-item / .cr-item / .dc-hidden / .ledger-dropdown, exactly as
   add2.php/edit2.php render them) - only the visual language changed,
   brought in line with the app's own .item-table pattern already used
   on the Sales/Purchases line-item grids (see table.item-table further
   down this file) instead of the old bare-bones spreadsheet look: a
   bordered/rounded card frame around the table (.qb-je-wrap, wrapping
   the same .table-responsive div add2.php/edit2.php already render -
   see the matching HTML comment there), a cleaner uppercase header, a
   subtle brand-tinted row hover instead of the old bright-yellow
   table.stripped default, and a circular hover treatment on the delete
   icon matching .row-remove elsewhere. The Save button also moved off
   its QuickBooks-green identity onto the app's own --db-primary purple,
   per that same follow-up - .btn-qb-primary/.btn-qb-cancel keep their
   class names (edit2.php/add2.php markup unchanged) even though "qb" no
   longer describes the color.

   Same day, second pass - shown the first pass live, still "not happy",
   asked to "redesign all how it looks" (not one fixable spot). Went
   further on the same grid, same columns/JS, nothing structural:
   - The Dr/Cr/Narration cells were still borderless-until-focus (the
     Aug 29 QuickBooks "type directly into the cell" look) - read as an
     empty spreadsheet at rest. Now a light bordered box always, like
     every other input in the app (.form-control elsewhere), not just on
     focus.
   - The ledger picker (select2, AJAX-backed against entries/
     ledgerList/<type>) was re-themed here too, briefly - and reverted
     the same day after it broke the dropdown on the live app (see the
     comment further down, by table.qb-je-table .select2-selection__
     rendered's old location) - it's back to select2's stock look.
   - Added zebra striping for scannability, on top of the existing hover
     tint.
   - The Total/Difference rows moved off a background-fill band (which
     read as one merged bar, not two totals) onto a proper summary
     footer: a divider line, a neutral tinted background, and the
     balanced/unbalanced state shown by coloring the FIGURES themselves
     (green/red, via --db-income/--db-expense) instead of painting the
     cells - see the updated recalcTotals() in add2.php/edit2.php. */
.je-header-row {
    margin-bottom: 4px;
}

.je-grid-label {
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--db-muted);
    margin: 18px 0 8px;
}

/* Bordered/rounded card frame around the grid (wraps the same
   .table-responsive div the table already sat in - see add2.php/
   edit2.php) - matches .item-table-wrap's treatment of the Sales/
   Purchases line-item tables instead of the table drawing its own
   border (a <table> can't clip its own rounded corners cleanly once
   .table-responsive's overflow-x:auto is in the mix). */
.qb-je-wrap {
    border: 1px solid var(--db-border);
    border-radius: 10px;
    overflow: hidden;
}

table.qb-je-table {
    border: none;
    border-radius: 0;
    margin-bottom: 0;
}

table.qb-je-table thead .tr-root-group {
    background: #f8f9fc !important;
    color: var(--db-muted) !important;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.dark-mode table.qb-je-table thead .tr-root-group {
    background: rgba(255, 255, 255, 0.04) !important;
}

table.qb-je-table th,
table.qb-je-table td {
    padding: 8px 10px;
    font-size: 13px;
    vertical-align: middle;
}

table.qb-je-table tbody#entryitems tr {
    border-bottom: 1px solid var(--db-border);
    transition: background-color 0.12s;
}

/* Zebra striping for scannability across a grid that's otherwise all
   white rows. */
table.qb-je-table tbody#entryitems tr:nth-child(even) {
    background-color: #fafafc;
}

.dark-mode table.qb-je-table tbody#entryitems tr:nth-child(even) {
    background-color: rgba(255, 255, 255, 0.015);
}

/* Subtle brand-tinted hover instead of table.stripped's bright-yellow
   default (that default is still exactly right for a data-browsing
   table elsewhere in the app; it read as a "warning" flash on a
   data-entry grid like this one). Declared after the zebra rule so it
   wins on a striped row too (same selector specificity - source order
   decides). */
table.qb-je-table tbody#entryitems tr:hover {
    background-color: rgba(83, 74, 183, 0.045);
}

.dark-mode table.qb-je-table tbody#entryitems tr:hover {
    background-color: rgba(175, 169, 236, 0.07);
}

/* Dr/Cr/Narration cells - a light bordered box at rest (matching every
   other input in the app), not just on focus - the borderless
   "spreadsheet cell" look read as empty/unfinished at rest. */
table.qb-je-table tbody#entryitems .form-control {
    border: 1px solid var(--db-border);
    border-radius: 6px;
    background: var(--db-input-bg);
    box-shadow: none;
    padding: 5px 8px;
}

table.qb-je-table tbody#entryitems .form-control:hover {
    border-color: #c9cee0;
}

.dark-mode table.qb-je-table tbody#entryitems .form-control:hover {
    border-color: #4a525d;
}

table.qb-je-table tbody#entryitems .form-control:focus {
    border-color: var(--db-primary);
    background: #ffffff;
    box-shadow: 0 0 0 2px rgba(83, 74, 183, 0.12);
}

.dark-mode table.qb-je-table tbody#entryitems .form-control:focus {
    background: var(--db-input-bg);
    box-shadow: 0 0 0 2px rgba(175, 169, 236, 0.2);
}

/* Ledger picker (select2, AJAX-backed - see initLedgerDropdown() in
   add2.php/edit2.php) is deliberately left at select2's stock look here.
   A re-theme was tried the same day (Sept 18 2026) and reverted within
   the hour - overriding .select2-selection--single's layout broke
   select2's own absolute-positioned internals (the rendered/placeholder
   text and the results panel effectively stopped showing - "where are
   the accounts"), on the live production app. Restyling this control
   safely would need testing against a running page, not just reading
   the source - out of reach in this environment - so it stays
   unstyled/default rather than risk breaking ledger selection again. */

/* Total/Difference rows (the two trailing <tr class="bold-text"> rows,
   outside #entryitems) - a proper summary footer instead of a
   background-fill band across the total cells (which read as one
   merged bar, not two totals): a divider line, a neutral tinted
   background, larger tabular-nums figures. Balanced/unbalanced is now
   shown by the FIGURES' color (see recalcTotals() in add2.php/
   edit2.php), not a cell background. */
table.qb-je-table tr.bold-text {
    background: #f8f9fc;
}

.dark-mode table.qb-je-table tr.bold-text {
    background: rgba(255, 255, 255, 0.03);
}

table.qb-je-table tr.bold-text td {
    font-weight: 700;
    color: var(--db-ink);
}

table.qb-je-table tr.bold-text:first-of-type td {
    border-top: 2px solid var(--db-border);
    padding-top: 10px;
}

#dr-total, #cr-total, #dr-diff, #cr-diff {
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

/* Delete icon - same circular hover treatment as .row-remove on the
   Sales/Purchases item tables (further down this file), reusing the
   existing .deleterow markup/JS hook as-is. */
table.qb-je-table .deleterow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 7px;
    color: var(--db-muted);
    cursor: pointer;
    transition: background-color 0.12s, color 0.12s;
}

table.qb-je-table .deleterow:hover {
    background: var(--db-expense-bg);
    color: var(--db-expense);
}

/* "Add lines" / "Clear all lines" - QuickBooks always keeps a handful of
   blank rows ready to fill, so both stay available regardless of how
   many rows are already in the grid. "Add lines" now reads as the
   primary of the two (dashed pill button, same language as
   .add-line-btn on the Sales/Purchases item tables further down this
   file); "Clear all lines" stays a plain, lower-emphasis text link next
   to it - same #qb-add-lines/#qb-clear-lines ids/JS as before. */
.qb-je-actions {
    margin-top: 10px;
    display: flex;
    align-items: center;
    gap: 16px;
}

.qb-je-actions a {
    font-size: 12.5px;
    font-weight: 700;
}

.qb-je-actions #qb-add-lines {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px dashed var(--db-primary);
    color: var(--db-primary);
    background: rgba(83, 74, 183, 0.05);
    padding: 5px 12px;
    border-radius: 7px;
}

.qb-je-actions #qb-add-lines:hover,
.qb-je-actions #qb-add-lines:focus {
    background: rgba(83, 74, 183, 0.1);
    color: var(--db-primary);
    text-decoration: none;
}

.qb-je-actions #qb-clear-lines {
    color: var(--db-muted);
}

.qb-je-actions #qb-clear-lines:hover,
.qb-je-actions #qb-clear-lines:focus {
    color: var(--db-ink);
    text-decoration: underline;
}

/* Bottom action bar - Save now uses the app's own --db-primary purple
   (Sept 18 2026, explicit follow-up request to match the rest of the
   app instead of the earlier deliberate QuickBooks-green choice) with a
   plain text-link style Cancel beside it. Class names kept as
   .btn-qb-primary/.btn-qb-cancel - only the color changed, not the
   markup in add2.php/edit2.php. */
.btn-qb-primary {
    background: var(--db-primary);
    border: 1px solid var(--db-primary);
    color: #ffffff !important;
    font-weight: 600;
    padding: 8px 22px;
}

.btn-qb-primary:hover,
.btn-qb-primary:focus {
    background: var(--db-primary-dark);
    border-color: var(--db-primary-dark);
    color: #ffffff !important;
}

.btn-qb-cancel {
    background: transparent;
    border: none;
    color: var(--db-primary);
    font-weight: 600;
    padding: 8px 14px;
}

.btn-qb-cancel:hover,
.btn-qb-cancel:focus {
    background: transparent;
    color: var(--db-primary-dark);
    text-decoration: underline;
}

/* -- Entry type pill (Entries/Search results tables' "Type" column) -
   soft color-coded badge instead of plain text, colored by the entry
   type's fixed label (see FunctionsCore::entryTypeBadge()). */
.entrytype-badge {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 4px 10px;
    border-radius: 999px;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

.entrytype-badge--income { background: var(--db-income-bg); color: var(--db-income); }
.entrytype-badge--expense { background: var(--db-expense-bg); color: var(--db-expense); }
.entrytype-badge--primary { background: rgba(83, 74, 183, 0.12); color: var(--db-primary-dark); }
.entrytype-badge--neutral { background: var(--db-neutral-bg); color: var(--db-neutral); }

.dark-mode .entrytype-badge--primary { color: #a9c0f5; }

/* -- Entries "Add Entry" menu (application/views/entries/index.php).
   Started as a QuickBooks-style grouped "+New" menu with Sales/Expenses
   columns (Aug 29 2026), then trimmed back to a single simple list per
   user request the same day - those document types aren't functions
   this account uses, and Receipt/Payment/Contra were dropped too since
   the dedicated Transfer button already covers what they were mainly
   used for. What's left is just a plain, cleanly-styled dropdown list
   (Journal, plus any custom entry type added under Account Settings ->
   Entry Types). */
.qb-new-menu {
    min-width: 200px;
    padding: 6px;
}

.qb-new-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 12px;
    border-radius: 6px;
    font-size: 0.86rem;
    color: var(--db-ink);
}

.qb-new-menu .dropdown-item i {
    width: 16px;
    text-align: center;
    color: var(--db-primary);
    flex-shrink: 0;
}

.qb-new-menu .dropdown-item:hover,
.qb-new-menu .dropdown-item:focus {
    background: rgba(83, 74, 183, 0.08);
    color: var(--db-ink);
}

/* -- Two-column card list rows (Cash & Bank, Recent Invoices) -------------- */

.list-card-body {
    padding: 6px 8px 10px 8px !important;
}

.list-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 11px 12px;
    border-radius: 10px;
}

.list-row:hover {
    background: #f7f9fc;
}

.dark-mode .list-row:hover {
    background: rgba(255, 255, 255, 0.03);
}

.list-row__left {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.list-row__avatar {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: rgba(83, 74, 183, 0.1);
    color: var(--db-primary-dark);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.78rem;
    flex-shrink: 0;
}

.list-row__name {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--db-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.list-row__sub {
    font-size: 0.76rem;
    color: var(--db-muted);
    margin-top: 1px;
}

.list-row__right {
    text-align: right;
    flex-shrink: 0;
}

.list-row__amount {
    font-size: 0.85rem;
    font-weight: 800;
    color: var(--db-ink);
}

.list-row__empty {
    padding: 24px 16px;
    text-align: center;
    color: var(--db-muted);
    font-size: 0.85rem;
}

.status-pill {
    display: inline-block;
    font-size: 0.65rem;
    font-weight: 800;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: 999px;
    margin-top: 3px;
}

.status-pill--issued { color: var(--db-primary-dark); background: rgba(83, 74, 183, 0.1); }
.status-pill--draft { color: var(--db-muted); background: #eef1f5; }
.status-pill--void { color: var(--db-expense); background: var(--db-expense-bg); }

.dark-mode .status-pill--draft { background: rgba(255, 255, 255, 0.06); }

/* -- Chart card toolbar cleanup --------------------------------------------- */

.chart-card-legend {
    display: flex;
    gap: 16px;
    font-size: 0.78rem;
    color: var(--db-muted);
    font-weight: 600;
}

.chart-card-legend__dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 2px;
    margin-right: 6px;
}

/* -- Topbar account dropdown (Sept 2026, v7 - round profile-card layout) --
   v1 reused the Login page's gradient; v2 switched to a flat tinted band;
   v3/v4 tried to shrink it further; v5 (Aug 25 2026) fixed the real root
   cause - AdminLTE's own adminlte.css styles this exact panel via long,
   highly specific selectors (e.g. ".navbar-nav > .user-menu > .dropdown-menu
   > li.user-header > img" - 4 classes + 2 elements) that outrank the
   shorter ".user-menu .user-header img" selectors used in v1-v4, so
   AdminLTE's 90px avatar / 280px panel width / 175px fixed header height /
   17px name font-size were silently winning regardless of what was written
   here. Every rule below that competes with one of those AdminLTE
   selectors still carries !important so it wins on any future edit
   without re-deriving specificity by hand - keep the !important flags.
   v6 was a content-preserving reskin ("redesign that form", visual refresh
   only): a brand-color accent strip along the top of the card, a bigger
   ring-framed avatar, a bolder name, and pill-shaped footer buttons -
   still laid out as a left-aligned avatar+text row with two 50/50-width
   buttons. v7 ("make that round form and Name, Profile picture, Buttons
   Profile and Sign Out") keeps every one of those same elements but
   restacks them into a centered, rounder profile card: a bigger circular
   avatar centered on top, name/member-since centered underneath, a more
   pronounced card corner radius, and two compact round pills (Profile,
   Sign out) centered side by side below instead of stretched to fill the
   width. Footer keeps the existing Bootstrap row/col-md-6/float-left/
   float-right markup (only .btn-default is targeted by AdminLTE there,
   not our .btn-info/.btn-danger) - the flex/width overrides below just
   neutralize the grid's own float/padding so the two buttons center as
   compact pills with a gap between them, rather than filling their
   column's full width. */

.user-menu .dropdown-menu {
    padding: 0 !important;
    overflow: hidden;
    width: 250px !important;
    min-width: 250px !important;
    border-top: 3px solid var(--db-primary) !important;
    border-radius: 18px !important;
}

/* v7 (Sept 2026, "make that round form") - the header switches from a
   left-aligned avatar+text row to a centered, stacked profile-card
   layout: a bigger circular avatar on top, name and member-since
   centered underneath - same content as v6, just arranged like a round
   profile card instead of a list-item row. */
.user-menu .user-header {
    background: var(--db-topbar-bg) !important;
    border-bottom: 1px solid var(--db-border);
    height: auto !important;
    padding: 20px 16px 16px !important;
    display: flex !important;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    text-align: center !important;
}

.user-menu .user-header img {
    width: 64px !important;
    height: 64px !important;
    border: none !important;
    box-shadow: 0 0 0 3px var(--db-card-bg), 0 0 0 5px var(--db-primary);
    flex-shrink: 0;
}

.user-menu .user-header p {
    margin: 0 !important;
    color: var(--db-primary-dark);
    font-weight: 700;
    font-size: 0.85rem !important;
    text-align: center !important;
    line-height: 1.35;
}

.user-menu .user-header p small {
    display: block;
    color: var(--db-muted);
    font-weight: 400;
    font-size: 0.68rem !important;
    margin-top: 2px;
}

.user-menu .user-footer.row {
    margin-left: 0 !important;
    margin-right: 0 !important;
}

.user-menu .user-footer {
    background: var(--db-topbar-bg) !important;
    padding: 12px 14px 16px !important;
    margin: 0;
    display: flex !important;
    justify-content: center;
    gap: 8px;
}

.dark-mode .user-menu .user-footer {
    background: var(--db-sidebar-bg);
}

/* Round, compact pills centered side by side (Profile, Sign out) instead
   of the v6 pair stretched to fill 50/50 columns - flex: 0 0 auto lets
   each column shrink to its button's own content width. */
.user-menu .user-footer > div {
    flex: 0 0 auto;
    padding: 0 !important;
    max-width: none !important;
    width: auto !important;
}

.user-menu .user-footer .btn {
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.72rem;
    padding: 6px 16px;
    width: auto;
    float: none !important;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.user-menu .user-footer .btn-info {
    background: rgba(83, 74, 183, 0.1);
    border: 1px solid transparent;
    color: var(--db-primary-dark);
}

.user-menu .user-footer .btn-info:hover {
    background: var(--db-primary);
    color: #fff;
}

.user-menu .user-footer .btn-danger {
    background: transparent;
    border: 1px solid var(--db-border);
    color: var(--db-expense);
}

.user-menu .user-footer .btn-danger:hover {
    background: var(--db-expense);
    border-color: var(--db-expense);
    color: #fff;
}

/* ==========================================================================
   Reports redesign (Phase 8, Aug 25 2026) - visual-only reskin of the
   Reports module's filter/action layout to match a modern report-viewer
   look (requested by the user via a QuickBooks-style screenshot). Scope
   was explicitly agreed as VISUAL STYLE ONLY - no new report features
   (no Cash/Accrual toggle, Compare-to-Period, Save As, or "Insights" -
   those are real QuickBooks features this app doesn't have). Applies to
   all 6 Reports pages: Balance Sheet, Profit & Loss, Trial Balance,
   Ledger Statement, Ledger Entries, Reconciliation.

   Structure per page:
   1. .report-filter-bar  - sits ABOVE the white .card, directly on the
      page's own light background (no border/box of its own - this is
      what creates the two-tone "gray strip above white card" look
      without needing a new gray token).
   2. .report-toolbar      - a right-aligned row of small icon buttons
      (Print/Export) at the top of the card body, replacing the old
      colored Bootstrap .btn-info/.btn-secondary export buttons.
   3. .report-title-block  - centered company name / report name /
      period text, styled like a real printed report header.
   4. .report-meta-footer  - a thin top-bordered line showing when the
      report was generated (static PHP timestamp, not a stored feature).
   ========================================================================== */

.report-filter-bar {
    padding: 4px 4px 18px;
}

.report-filter-bar__fields {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px;
    margin-bottom: 12px;
}

.report-filter-bar__field {
    flex: 1 1 200px;
    min-width: 160px;
}

.report-filter-bar__field label {
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--db-muted);
    margin-bottom: 6px;
}

.report-filter-bar__field .form-control,
.report-filter-bar__field .select2-container {
    background: #fff;
}

.report-filter-bar__field-inline {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    padding-bottom: 8px;
}

.report-filter-bar__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

.dark-mode .report-filter-bar__field .form-control {
    background: var(--db-sidebar-bg);
}

.report-toolbar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
    margin-bottom: 6px;
}

.report-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 8px;
    border: 1px solid var(--db-border);
    background: #fff;
    color: var(--db-muted);
    font-size: 0.9rem;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.report-icon-btn:hover,
.report-icon-btn:focus {
    background: var(--db-sidebar-active-bg);
    border-color: var(--db-primary);
    color: var(--db-primary-dark);
    text-decoration: none;
}

.dark-mode .report-icon-btn {
    background: var(--db-sidebar-bg);
}

.report-toolbar-divider {
    border: none;
    border-top: 1px solid var(--db-border);
    margin: 0 0 20px;
}

.report-title-block {
    text-align: center;
    margin-bottom: 24px;
}

.report-title-block__company {
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--db-ink);
}

.report-title-block__name {
    font-size: 1rem;
    color: var(--db-ink);
    margin-top: 2px;
}

.report-title-block__period {
    font-size: 0.85rem;
    color: var(--db-muted);
    margin-top: 4px;
}

.report-meta-footer {
    border-top: 1px solid var(--db-border);
    margin-top: 24px;
    padding-top: 12px;
    font-size: 0.78rem;
    color: var(--db-muted);
    text-align: right;
}
/* ==========================================================================
   Reports: single-column "portrait" statement layout (Balance Sheet,
   Profit & Loss), QuickBooks-style. Sections stack top to bottom instead
   of side by side, at a capped reading width so it looks right both on
   screen and when printed on a portrait page - a two-table-wide layout
   was cramped once squeezed onto portrait paper.
   ========================================================================== */
.report-portrait-stack {
    max-width: 720px;
    margin: 0 auto;
}


@media print {
    .report-filter-bar,
    .report-toolbar {
        display: none !important;
    }
    /* Sept 24 2026, A/R Aging + A/P Aging + Customer/Vendor Balance
       reports (and the Customer/Vendor Statement date filter) - an
       "Actions" column of view/edit links makes sense on screen but is
       dead weight on a printed page, same idea as hiding the filter bar
       and toolbar above. Table-only (kept off .report-toolbar itself)
       so it doesn't collide with that class's own flex layout. */
    .report-table-actions-col {
        display: none !important;
    }
}

@page {
    size: A4 portrait;
    margin: 15mm;
}

/* ==========================================================================
   Reports: collapsible categories + hide dormant accounts (Phase 9, Aug 25
   2026). Requested by the user: on Balance Sheet, Profit & Loss and Trial
   Balance, accounts with no opening balance and no activity at all
   (untouched / no transactions) are no longer printed, and every account
   category (Assets, Current Assets, Liabilities, Income, Expense, etc.) is
   now a collapsible section - collapsed by default - instead of a flat
   always-expanded list. Uses Bootstrap's own collapse JS (already loaded
   app-wide via bootstrap.bundle.min.js), so no new JS file is needed.
   ========================================================================== */

.report-cat-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

.report-cat-toggle:hover,
.report-cat-toggle:focus {
    color: var(--db-primary-dark);
    text-decoration: none;
}

.report-cat-caret {
    font-size: 0.75rem;
    color: var(--db-muted);
    transition: transform 0.15s ease;
}

.report-cat-toggle:not(.collapsed) .report-cat-caret {
    transform: rotate(90deg);
}

.report-cat-row {
    cursor: pointer;
}

table.stripped tr.report-cat-body-row td {
    border: none;
    padding: 0;
}

table.stripped tr.report-cat-body-row:hover {
    background-color: transparent;
}

.report-cat-body-td {
    background: transparent;
}

.report-cat-inner-table {
    width: 100%;
}

/* ==========================================================================
   Sept 25 2026 ("make the reports look like QuickBooks Online reports") -
   .report-filter-bar/.report-toolbar/.report-title-block above already
   borrowed QuickBooks Online's report page layout (see that section's own
   comment). What still read as a plain admin-panel data table was the
   TABLE itself: a bright yellow row-hover, pale-yellow ".summary" boxes,
   and gray/brown-filled subtotal & total rows. QuickBooks Online's own
   report tables carry almost no color at all - a plain bottom-bordered
   header row, bold text (not a fill color) marking a subtotal, and a
   bold top-bordered line marking a grand total - so that's what this
   recreates.

   Scoped under .reports-qbo, added to the outer <section class="content">
   on all 10 Reports-tab pages (Balance Sheet, Profit & Loss, Trial
   Balance, Ledger Statement, Ledger Entries, Reconciliation, A/R Aging,
   A/P Aging, Customer Balance, Vendor Balance) - deliberately NOT
   redefining table.stripped/.tr-highlight/.tr-group/.tr-root-group/
   .summary directly, since those are shared, app-wide classes also used
   on invoice/bill/purchase-order/payment detail pages, the Customers/
   Vendors list and statement pages, and journal entry forms - none of
   which this request touches. Uses the same --db-ink/--db-muted/
   --db-border theme variables as the rest of this file (instead of new
   hardcoded colors) so this still reads correctly in dark mode.
   ========================================================================== */

.reports-qbo .card {
    box-shadow: none;
    border: 1px solid var(--db-border);
}

.reports-qbo .card-header {
    background: transparent;
    border-bottom: 1px solid var(--db-border);
}

.reports-qbo table.stripped thead th,
.reports-qbo table.stripped > thead > tr > th {
    background: transparent;
    border: none;
    border-bottom: 2px solid var(--db-ink);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--db-muted);
    padding: 8px 8px 10px;
    white-space: nowrap;
}

.reports-qbo table.stripped tr td,
.reports-qbo table.stripped > tbody > tr > td {
    border-top: none;
    border-bottom: 1px solid var(--db-border);
    padding: 9px 8px;
}

/* QuickBooks Online report rows don't react to hover beyond the pointer -
   this just removes the app-wide bright-yellow highlight within scope. */
.reports-qbo table.stripped tr:hover {
    background-color: transparent;
}

/* Subtotal / section-total rows (.tr-highlight/.tr-group/.tr-root-group -
   the app's existing "this row totals something" classes, already used
   for opening/closing balance, account-category totals, etc. across
   every report): bold text and a top+bottom border instead of a gray or
   brown fill. !important only overrides those same classes' own inline-
   specificity color/background, never anything outside this scope. */
.reports-qbo table.stripped .tr-highlight,
.reports-qbo table.stripped .tr-group,
.reports-qbo table.stripped .tr-root-group {
    background: transparent !important;
    color: inherit !important;
    font-weight: 700;
}

.reports-qbo table.stripped .tr-highlight td,
.reports-qbo table.stripped .tr-group td,
.reports-qbo table.stripped .tr-root-group td {
    border-top: 1px solid var(--db-ink);
    border-bottom: 1px solid var(--db-ink);
}

/* Grand total row (the <tfoot> on the 4 new reports' totals line) - a
   heavier double rule, the same way QuickBooks sets a final total apart
   from an ordinary subtotal. The 4 new reports' <tfoot> row also carries
   .tr-highlight (for its bold text), so this needs the second, more
   specific selector too - otherwise the plain .tr-highlight td border
   rule above (3 classes) would silently outrank this one (2 classes) and
   the grand total would never actually get its heavier double rule. */
.reports-qbo table.stripped tfoot tr td,
.reports-qbo table.stripped tfoot tr.tr-highlight td {
    border-top: 3px double var(--db-ink);
    border-bottom: none;
    font-weight: 700;
}

/* The pale-yellow 2-column "summary" boxes (Opening/Closing Balance,
   Reconciliation's difference box, etc.) - same white/bordered treatment
   as the rest of this scope instead of the old highlighter-yellow fill. */
.reports-qbo .summary {
    background: transparent;
    border: 1px solid var(--db-border);
}

.reports-qbo .summary td {
    border: 1px solid var(--db-border);
}

.reports-qbo .report-title-block__name {
    font-size: 1.3rem;
    font-weight: 700;
}

/* Sept 25 2026 follow-up: Balance Sheet, Profit & Loss and Trial Balance
   don't mark their subtotal/grand-total rows with .tr-highlight/.tr-group -
   they use the app's older, plain ".bold-text" (subtotal) and
   ".bold-text.bg-filled" (grand total, e.g. Total Assets = Total
   Liabilities + Equity, Total Income, Net Profit/Loss) convention instead
   (see account_st_short() in each view). Missed on the first pass, so
   those rows kept showing the old gray ".bg-filled" fill inside a page
   that was otherwise restyled - this brings them in line with the
   tr-highlight/tr-group treatment above using the same border approach.
   ":not(.dc-error)" deliberately leaves a real Dr/Cr-mismatch warning row
   (bold-text combined with dc-error, its own bright-red fill) untouched -
   that fill is a functional error flag, not decorative, and this rule
   must never suppress it. Text color (.error-text's red, .ok-text) is
   never touched here either, only background and border. */
.reports-qbo table.stripped tr.bold-text:not(.dc-error) {
    background: transparent !important;
}

.reports-qbo table.stripped tr.bold-text:not(.dc-error) td {
    border-top: 1px solid var(--db-ink);
    border-bottom: 1px solid var(--db-ink);
}

.reports-qbo table.stripped tr.bold-text.bg-filled:not(.dc-error) td {
    border-top: 3px double var(--db-ink);
    border-bottom: none;
}

/* ==========================================================================
   Sept 25 2026 ("make dashboard that show the reports instead of dropdown
   on reports tab") - the Reports landing page (application/views/reports/
   dashboard.php), a grid of clickable report cards grouped into three
   sections, replacing both the Restricted Viewer role's old sidebar
   dropdown and the in-page tab row (reports/_tabs.php, removed from every
   report page) as the way to move between reports. Reuses .dashboard-card
   for the card shell/shadow (same component the main Accounts Dashboard
   uses) - only the inner layout (icon + title + description + chevron,
   the whole card a link) is new, under its own .reports-dash-* names so
   it can't collide with anything else that also builds on .dashboard-card.
   ========================================================================== */

.reports-dash-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 20px;
}

.reports-dash-header__title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--db-ink);
    margin: 0;
}

.reports-dash-header__title i {
    color: var(--db-primary);
    font-size: 1.15rem;
}

.reports-dash-section {
    margin-bottom: 28px;
}

.reports-dash-section__title {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--db-muted);
    margin: 0 0 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--db-border);
}

.reports-dash-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 14px;
}

/* The whole tile is the <a> - .dashboard-card already gives it the
   card background/border/radius/hover-shadow, this just lays out its
   contents as icon + text + trailing chevron and strips the link's
   own color/underline so it reads as a plain card, not a hyperlink. */
.reports-dash-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px;
    color: inherit !important;
    text-decoration: none !important;
}

.reports-dash-card__icon {
    flex: 0 0 auto;
    width: 42px;
    height: 42px;
    border-radius: 10px;
    background: rgba(83, 74, 183, 0.1);
    color: var(--db-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
}

.reports-dash-card__body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.reports-dash-card__title {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--db-ink);
}

.reports-dash-card__desc {
    font-size: 0.8rem;
    color: var(--db-muted);
    line-height: 1.35;
}

.reports-dash-card__arrow {
    flex: 0 0 auto;
    color: var(--db-border);
    font-size: 0.8rem;
    transition: transform 0.15s ease, color 0.15s ease;
}

.reports-dash-card:hover .reports-dash-card__arrow {
    color: var(--db-primary);
    transform: translateX(2px);
}

/* ==========================================================================
   List-page row actions collapsed into a single "..." menu (Phase 10, Aug
   25 2026). Requested by the user via a QuickBooks screenshot ("collapse
   in one click like quickbook") - every list table's Actions column
   (Customers, Vendors, Items, Quotations, Invoices, Bills, Purchase
   Orders, Payments, Vendor Payments, Quick Expenses) now shows one small
   icon button per row instead of a wide row of spelled-out links; clicking
   it opens a dropdown with the same actions (same hrefs, same delete
   confirm dialogs) as before. Uses Bootstrap's own dropdown JS (already
   loaded app-wide via bootstrap.bundle.min.js) - see the matching
   table-responsive overflow fix added to foot.php, needed because these
   dropdowns live inside a horizontally-scrolling .table-responsive
   wrapper, which would otherwise clip them.
   ========================================================================== */

.row-actions-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: none;
    border-radius: 999px;
    background: transparent;
    color: var(--db-muted);
    font-size: 0.9rem;
    line-height: 1;
    cursor: pointer;
}

.row-actions-toggle::after {
    display: none;
}

.row-actions-toggle:hover,
.row-actions-toggle:focus,
.row-actions-toggle[aria-expanded="true"] {
    background: var(--db-neutral-bg);
    color: var(--db-ink);
    outline: none;
    box-shadow: none;
}

.row-actions-menu {
    min-width: 200px;
    padding: 6px;
    border: 1px solid var(--db-border);
    border-radius: 10px;
    box-shadow: var(--db-shadow-md);
}

.row-actions-menu .dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: 6px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--db-ink);
}

.row-actions-menu .dropdown-item i {
    width: 16px;
    text-align: center;
    color: var(--db-muted);
}

.row-actions-menu .dropdown-item:hover,
.row-actions-menu .dropdown-item:focus {
    background: var(--db-neutral-bg);
    color: var(--db-ink);
}

.row-actions-menu .dropdown-item.text-danger,
.row-actions-menu .dropdown-item.text-danger i {
    color: var(--db-expense);
}

.row-actions-menu .dropdown-item.text-danger:hover,
.row-actions-menu .dropdown-item.text-danger:focus {
    background: var(--db-expense-bg);
    color: var(--db-expense);
}

/* ==========================================================================
   Document Template swatches (Sales -> Templates, Phase 5, redesigned). A
   clickable gallery of the 6 layouts defined in
   sales/pdf/layouts/template_N.php - each card is a native radio input
   hidden behind a mini CSS mock-up that mirrors that template's actual
   structure (see the .tsw-* helpers below), so picking one needs no JS.
   Radios carry class="skip" so the app's global iCheck skinning (see
   _base/foot.php) leaves them alone; selection state is shown with the
   CSS :checked sibling rules below instead. */

.template-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    gap: 16px;
    margin-bottom: 8px;
}

.template-swatch {
    position: relative;
    display: block;
    cursor: pointer;
    margin: 0;
}

.template-swatch input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.template-swatch__preview {
    border: 2px solid var(--db-border);
    border-radius: 6px;
    padding: 10px;
    background: #ffffff;
    transition: box-shadow 0.15s, border-color 0.15s;
}

.template-swatch input[type="radio"]:checked + .template-swatch__preview {
    border-color: var(--db-primary);
    box-shadow: 0 0 0 3px rgba(83, 74, 183, 0.18);
}

.template-swatch__company {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 3px;
}

.template-swatch__title {
    font-size: 0.86rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    margin-bottom: 8px;
}

.template-swatch__row {
    height: 7px;
    border-radius: 2px;
    margin-bottom: 4px;
}

.template-swatch__name {
    text-align: center;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--db-ink);
    margin-top: 8px;
}

.template-swatch input[type="radio"]:checked ~ .template-swatch__name {
    color: var(--db-primary);
}

/* Structural mini-mockup helpers for the 6 redesigned templates (used by
   sales/templates.php) - each hints at that template's real layout
   (split header, boxed card, full-width band, sidebar) rather than just
   swapping colors on one shared shape. */
.tsw-split {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 6px;
}

.tsw-hr {
    border-bottom: 2px solid;
    margin-bottom: 8px;
}

.tsw-card {
    border: 1px solid;
    border-radius: 4px;
    padding: 6px 8px;
}

.tsw-band {
    padding: 8px 10px;
}

.tsw-band-body {
    padding: 8px 10px 2px 10px;
}

.tsw-sidebar-wrap {
    display: flex;
    align-items: stretch;
    min-height: 66px;
}

.tsw-sidebar {
    width: 30%;
    padding: 8px 6px;
}

.tsw-sidebar-main {
    flex: 1;
    padding: 8px 10px;
}

/* Template 7 (Corporate Navy & Amber) swatch mock-up: title left, small
   logo placeholder box right, thick accent rule underneath - see
   sales/templates.php's 'banner' layout branch. */
.tsw-logo-box {
    font-size: 0.55rem;
    font-weight: 700;
    border: 1px solid;
    border-radius: 3px;
    padding: 3px 6px;
    align-self: flex-start;
    white-space: nowrap;
}

.cf-docs-check {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-right: 14px;
    font-weight: 400;
    font-size: 0.85rem;
    color: var(--db-muted);
}

/* ==========================================================================
   Sidebar "stuck open" on narrow browser windows (Sept 5 2026)

   AdminLTE only auto-hides the sidebar off-canvas below 767.98px - see
   adminlte.css: `@media (max-width: 767.98px) { .main-sidebar { margin-left:
   -250px; } }`, shown again only via the JS-added `.sidebar-open` class.
   Between roughly 768px-991.98px (a resized desktop window, or a tablet in
   portrait), AdminLTE's own rules zero out .content-wrapper/.main-header's
   margin-left but leave .main-sidebar sitting open at its full fixed 250px
   width - so the topbar and page content get squeezed to margin-left:0
   *underneath* the fixed sidebar instead of being hidden behind it, and
   every menu label past the visible ~250px gets clipped by the viewport
   edge (reported by the user: "Compare Co[mpanies]", "System Setti[ngs]"
   etc. cut off, with a horizontal scrollbar to see the rest).

   Fix: extend the same hide-by-default/show-via-hamburger behavior AdminLTE
   already uses below 767.98px up through 991.98px, closing that gap so a
   narrow window always gets a clean, fully off-canvas sidebar instead of a
   half-open one. Above 991.98px nothing here applies - the normal desktop
   sidebar is untouched.
   ========================================================================== */
@media (max-width: 991.98px) {
    .main-sidebar,
    .main-sidebar::before {
        margin-left: -250px !important;
    }
    .sidebar-open .main-sidebar,
    .sidebar-open .main-sidebar::before {
        margin-left: 0 !important;
    }
    .content-wrapper,
    .main-header,
    .main-footer {
        margin-left: 0 !important;
    }
}

/* ==========================================================================
   Home / landing page (Sept 6 2026) - public page shown at the site root
   before sign-in, replacing the old behavior of landing straight on Login.
   Restyled (Sept 6 2026) to a sharper, tighter "modern SaaS" look - kept
   the app's own brand color and content, changed the visual language:
   Inter/Inter Tight type, tighter corner radii, an eyebrow "kicker" label,
   inline highlight chips, a "why" section and a closing CTA band.
   ========================================================================== */

.home-page {
    background: #ffffff;
}

.home-page-wrap {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.home-page-wrap h1,
.home-page-wrap h2,
.home-page-wrap h3 {
    font-family: 'Inter Tight', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.home-nav {
    border-bottom: 1px solid var(--db-border);
    background: #ffffff;
}

.home-nav__inner {
    max-width: 1140px;
    margin: 0 auto;
    padding: 16px 24px;
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.home-nav__brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--db-ink);
    text-decoration: none;
    letter-spacing: -0.01em;
}

.home-nav__brand:hover {
    color: var(--db-ink);
    text-decoration: none;
}

.home-nav__brand-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
}

.home-nav__cta {
    border-radius: 6px;
    font-weight: 600;
    padding: 8px 20px;
    background: var(--db-primary);
    border-color: var(--db-primary);
}

.home-nav__cta:hover {
    background: var(--db-primary-dark);
    border-color: var(--db-primary-dark);
}

.home-hero {
    background: #ffffff;
    color: var(--db-ink);
    padding: 96px 24px 64px;
    text-align: center;
}

.home-hero__inner {
    max-width: 760px;
    margin: 0 auto;
}

.home-kicker {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--db-primary-dark);
    background: rgba(83, 74, 183, 0.09);
    border-radius: 999px;
    padding: 6px 16px;
    margin-bottom: 20px;
}

.home-hero__title {
    font-size: 2.7rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    margin-bottom: 18px;
    line-height: 1.14;
    color: var(--db-ink);
}

.home-hero__subtitle {
    font-size: 1.08rem;
    color: var(--db-muted);
    margin-bottom: 32px;
    line-height: 1.65;
}

.home-hero__actions {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 36px;
}

.home-hero__cta {
    border-radius: 6px;
    font-weight: 700;
    padding: 12px 26px;
    color: #fff;
    background: var(--db-primary);
    border: 1px solid var(--db-primary);
}

.home-hero__cta:hover {
    background: var(--db-primary-dark);
    border-color: var(--db-primary-dark);
    color: #fff;
}

.home-hero__cta-secondary {
    border-radius: 6px;
    font-weight: 700;
    padding: 12px 26px;
    color: var(--db-ink);
    background: transparent;
    border: 1px solid var(--db-border);
}

.home-hero__cta-secondary:hover {
    background: #f9fafb;
    color: var(--db-ink);
    border-color: var(--db-border);
}

.home-hero__highlights {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 22px;
    flex-wrap: wrap;
}

.home-hero__highlight {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--db-muted);
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.home-hero__highlight i {
    color: var(--db-income);
    font-size: 0.78rem;
}

.home-features {
    padding: 64px 24px;
    background: #f9fafb;
    border-top: 1px solid var(--db-border);
}

.home-features__inner {
    max-width: 1140px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 20px;
}

.home-feature-card {
    background: #fff;
    border: 1px solid var(--db-border);
    border-radius: 10px;
    padding: 26px 24px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.home-feature-card:hover {
    border-color: var(--db-primary);
    box-shadow: var(--db-shadow-sm);
}

.home-feature-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    border-radius: 8px;
    background: rgba(83, 74, 183, 0.1);
    color: var(--db-primary);
    font-size: 1.05rem;
    margin-bottom: 16px;
}

.home-feature-card h3 {
    font-size: 1.02rem;
    font-weight: 700;
    color: var(--db-ink);
    margin-bottom: 8px;
}

.home-feature-card p {
    font-size: 0.88rem;
    color: var(--db-muted);
    margin: 0;
    line-height: 1.55;
}

.home-why {
    flex: 1;
    padding: 72px 24px;
    background: #ffffff;
}

.home-why__inner {
    max-width: 1140px;
    margin: 0 auto;
}

.home-why__title {
    text-align: center;
    font-size: 1.9rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--db-ink);
    margin-bottom: 40px;
}

.home-why__grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 24px;
}

.home-why__item {
    text-align: center;
}

.home-why__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 8px;
    background: rgba(83, 74, 183, 0.09);
    color: var(--db-primary);
    font-size: 1.15rem;
    margin-bottom: 16px;
}

.home-why__item h3 {
    font-size: 0.98rem;
    font-weight: 700;
    color: var(--db-ink);
    margin-bottom: 8px;
}

.home-why__item p {
    font-size: 0.86rem;
    color: var(--db-muted);
    margin: 0;
    line-height: 1.55;
}

.home-cta {
    background: var(--db-ink);
    color: #fff;
    padding: 64px 24px;
    text-align: center;
}

.home-cta__inner {
    max-width: 640px;
    margin: 0 auto;
}

.home-cta__title {
    font-size: 1.9rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    margin-bottom: 10px;
}

.home-cta__subtitle {
    font-size: 1rem;
    opacity: 0.8;
    margin-bottom: 28px;
}

.home-cta__button {
    border-radius: 6px;
    font-weight: 700;
    padding: 12px 28px;
    color: var(--db-ink);
    background: #fff;
    border: none;
}

.home-cta__button:hover {
    background: #f4f6fb;
    color: var(--db-ink);
}

.home-footer {
    padding: 22px 24px;
    text-align: center;
    font-size: 0.82rem;
    color: var(--db-muted);
    border-top: 1px solid var(--db-border);
    background: #fff;
}

@media (max-width: 900px) {
    .home-features__inner {
        grid-template-columns: repeat(2, 1fr);
    }
    .home-why__grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 600px) {
    .home-features__inner {
        grid-template-columns: 1fr;
    }
    .home-why__grid {
        grid-template-columns: 1fr;
    }
    .home-hero {
        padding: 64px 20px 48px;
    }
    .home-hero__title {
        font-size: 1.9rem;
    }
    .home-hero__actions {
        flex-direction: column;
        align-items: stretch;
    }
    .home-hero__actions .btn {
        width: 100%;
    }
}

/* ==========================================================================
   Nidaam brand — app-wide typography
   Inter/Inter Tight were previously loaded and applied to the public
   landing page only (.home-page-wrap); the brand spec calls for the same
   clean sans-serif across the whole product, so it's applied to body
   here too. Headings keep the slightly tighter Inter Tight cut used on
   the landing page for a consistent "voice" across marketing and app.
   ========================================================================== */
html {
    /* Covers the same white-sliver case as body below, one layer further
       out (e.g. elastic overscroll at the very top of the page, which
       paints through html rather than body on some browsers). */
    background: var(--db-page-bg);
}

body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    /* Bootstrap hardcodes body{background-color:#fff} with nothing here to
       override it for dark mode - .content-wrapper/.main-header/.sidebar
       are each painted with their own dark token, but they don't
       necessarily cover literally every pixel of the viewport (e.g. any
       rounding/overscroll at the very top edge), so the plain white body
       showed through as a thin white sliver above the top navbar (Sept 8
       2026 user screenshot, circled in green). Painting the body itself
       with the page token removes that gap regardless of cause. */
    background: var(--db-page-bg);
}
h1, h2, h3, .dashboard-card__title, .brand-text {
    font-family: 'Inter Tight', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* ==========================================================================
   Nidaam brand — Bootstrap/AdminLTE primary color overrides
   Retints every stock Bootstrap/AdminLTE "primary" control (buttons,
   badges, checkboxes/radios, pagination, form focus rings) from the
   default Bootstrap blue to the Nidaam brand primary purple, using the
   --db-primary/--db-primary-dark tokens above so light/dark mode both
   stay correct automatically. Emerald (--db-accent) is intentionally
   NOT used here - per the brand spec it's a sparing highlight color for
   active/selected nav states only, not a blanket control color.
   ========================================================================== */
.btn-primary,
.badge-primary,
.bg-primary {
    background-color: var(--db-primary) !important;
    border-color: var(--db-primary) !important;
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-primary.active,
.show > .btn-primary.dropdown-toggle {
    background-color: var(--db-primary-dark) !important;
    border-color: var(--db-primary-dark) !important;
}
.btn-primary:focus,
.btn-primary.focus,
.btn-primary:not(:disabled):not(.disabled):active:focus {
    box-shadow: 0 0 0 0.2rem rgba(83, 74, 183, 0.5) !important;
}
.btn-outline-primary {
    color: var(--db-primary) !important;
    border-color: var(--db-primary) !important;
}
.btn-outline-primary:hover,
.btn-outline-primary:active {
    background-color: var(--db-primary) !important;
    border-color: var(--db-primary) !important;
    color: #fff !important;
}
.text-primary {
    color: var(--db-primary) !important;
}
.border-primary {
    border-color: var(--db-primary) !important;
}
a:not(.btn) {
    color: var(--db-primary);
}
.page-item.active .page-link {
    background-color: var(--db-primary) !important;
    border-color: var(--db-primary) !important;
}
.page-link {
    color: var(--db-primary);
}
.custom-control-input:checked ~ .custom-control-label::before {
    background-color: var(--db-primary) !important;
    border-color: var(--db-primary) !important;
}
.custom-control-input:focus ~ .custom-control-label::before {
    box-shadow: 0 0 0 0.2rem rgba(83, 74, 183, 0.25) !important;
}
.form-control:focus {
    border-color: var(--db-primary) !important;
    box-shadow: 0 0 0 0.2rem rgba(83, 74, 183, 0.25) !important;
}
.icheck-primary > input:first-child:checked + input[type="hidden"] + label::before,
.icheck-primary > input:first-child:checked + label::before {
    background-color: var(--db-primary) !important;
    border-color: var(--db-primary) !important;
}
.icheck-primary > input:first-child:not(:checked):not(:disabled):hover + input[type="hidden"] + label::before,
.icheck-primary > input:first-child:not(:checked):not(:disabled):hover + label::before,
.icheck-primary > input:first-child:not(:checked):not(:disabled):focus + input[type="hidden"] + label::before,
.icheck-primary > input:first-child:not(:checked):not(:disabled):focus + label::before {
    border-color: var(--db-primary) !important;
}
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
    background-color: var(--db-primary) !important;
}
.progress-bar {
    background-color: var(--db-primary);
}

/* Hide the native up/down spinner on every number input, app-wide (Sept
   2026 request, after a Qty/Unit Price box's spinner arrow on the Invoice
   form was mistaken for something else and clicking it silently
   decremented the value by 1). Money/quantity fields have no business
   being steppable by 1 anyway - Amount, Unit Price, Qty, tax %, etc. are
   typed or calculated, never incremented one at a time - so this is
   removed everywhere rather than only on the one form that was reported,
   consistent with how a shared CSS/JS fix in this codebase always applies
   to every company/page at once. The scroll-wheel half of the same
   accidental-change risk (Chrome changes a focused number input's value
   when the page is scrolled with the mouse over it) isn't a CSS concern -
   see myjs.js for that part. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
input[type="number"] {
    -moz-appearance: textfield;
}

/* -- Sectioned form cards + combo picker (Sept 2026 - "all forms" redesign,
   extends the same accent-bar/gradient language already on the per-account
   Dashboard - see .hero-card/.stat-tile above - to the app's add/edit
   forms). Confirmed direction: a long form (Quotation/Invoice/Bill) splits
   into a few small cards instead of one flat block, and the raw
   "-- Select customer --"/"-- Free text --" native <select> placeholder
   rows are replaced by a small searchable combobox. Rolling out form by
   form starting with Quotation; this block is shared so every form reuses
   the exact same classes once converted. All colors are CSS vars, so both
   of these blocks already work in dark mode without a duplicate ruleset -
   only the two focus-glow rgba()s below need their own dark-mode value,
   same reason .form-control:focus does above. */

.form-card {
    background: var(--db-card-bg);
    border: 1px solid var(--db-border);
    border-radius: var(--db-radius);
    box-shadow: var(--db-shadow-sm);
    margin-bottom: 14px;
    overflow: visible;
}
.form-card__head {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--db-border);
    border-radius: var(--db-radius) var(--db-radius) 0 0;
    overflow: hidden;
}
.form-card__head::before {
    content: "";
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 3px;
}
/* One accent per section, matching the section's own icon tint just below -
   details/primary (purple), items/accent (teal-green), totals/neutral
   (amber) - same three-color vocabulary .stat-tile-grid already uses. */
.form-card--details .form-card__head::before { background: linear-gradient(180deg, #534AB7, #8f87e0); }
.form-card--items .form-card__head::before   { background: linear-gradient(180deg, #085041, #16916f); }
.form-card--totals .form-card__head::before  { background: linear-gradient(180deg, #c98a1f, #fbbf24); }
.form-card__icon {
    width: 24px; height: 24px;
    border-radius: 7px;
    display: flex; align-items: center; justify-content: center;
    font-size: 11px;
    flex-shrink: 0;
}
.form-card--details .form-card__icon { background: rgba(83, 74, 183, 0.1); color: var(--db-primary); }
.form-card--items .form-card__icon   { background: var(--db-accent-bg); color: var(--db-accent); }
.form-card--totals .form-card__icon  { background: var(--db-neutral-bg); color: var(--db-neutral); }
.form-card__title { font-weight: 700; font-size: 13.5px; color: var(--db-ink); line-height: 1.3; }
.form-card__sub { font-size: 11px; color: var(--db-muted); font-weight: 500; margin-top: 0; line-height: 1.3; }
.form-card__body { padding: 14px 16px; }
.form-card__body .row:last-child { margin-bottom: 0; }

/* Field label used inside a .form-card - deliberately its own class rather
   than restyling <label> app-wide (that would ripple into every form not
   yet converted to this layout). */
.field-label {
    display: block;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--db-ink);
    margin-bottom: 4px;
}
.field-label .opt { color: var(--db-muted); font-weight: 500; }
.field-addr { font-size: 11px; color: var(--db-muted); margin-top: 3px; }
.field-hint { font-size: 11px; color: var(--db-muted); margin-top: 3px; }

.input-prefix {
    display: flex;
    border: 1px solid var(--db-border);
    border-radius: 8px;
    overflow: hidden;
    background: var(--db-input-bg);
}
.input-prefix:focus-within { border-color: var(--db-primary); box-shadow: 0 0 0 3px rgba(83, 74, 183, 0.12); }
.dark-mode .input-prefix:focus-within { box-shadow: 0 0 0 3px rgba(175, 169, 236, 0.25); }
.input-prefix span {
    background: #f6f7fa;
    color: var(--db-muted);
    font-size: 12px;
    font-weight: 700;
    padding: 6px 9px;
    border-right: 1px solid var(--db-border);
}
.dark-mode .input-prefix span { background: rgba(255, 255, 255, 0.03); }
.input-prefix input { border: none; flex: 1; padding: 6px 10px; font-size: 12.5px; font-family: inherit; background: transparent; color: var(--db-ink); }
.input-prefix input:focus { outline: none; }

.total-readout {
    text-align: right;
    min-width: 140px;
    background: var(--db-accent-bg);
    border-radius: 8px;
    padding: 8px 12px;
}
.total-readout .field-label { color: var(--db-accent); margin-bottom: 1px; }
.total-readout .grand-value { font-family: 'Inter Tight', 'Inter', sans-serif; font-size: 20px; font-weight: 800; color: var(--db-accent); }

/* Marks where a card's tax/total/notes section starts, right under its
   line-item table - a plain divider instead of a second .form-card__head,
   so "Line Items" and "Totals & Notes" read as one card/one topic (Sept
   2026 request - merged from two separate cards on Quotation/Invoice/
   Bill). Reusable wherever that same merge applies. */
.totals-strip { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--db-border); }

/* -- Combo picker: progressive-enhancement UI over a native <select>,
   built/positioned by assets/dist/js/combo-select.js (NidaamCombo). The
   underlying <select> stays in the DOM and keeps its name/id/value/options
   - the widget below is purely a styled proxy over it, so every existing
   change-handler, validation, and dynamically-added <option> keeps working
   untouched. See combo-select.js for how the two stay in sync. */
.combo-select-wrap { position: relative; }
.combo-select-wrap > select { position: absolute; opacity: 0; height: 1px; width: 1px; overflow: hidden; pointer-events: none; }
.combo {
    display: flex;
    align-items: center;
    gap: 8px;
    border: 1px solid var(--db-border);
    border-radius: 8px;
    background: var(--db-input-bg);
    padding: 6px 10px;
    cursor: pointer;
    user-select: none;
}
.combo:hover { border-color: #c9cee0; }
.dark-mode .combo:hover { border-color: #4a525d; }
.combo.is-open,
.combo:focus { outline: none; border-color: var(--db-primary); box-shadow: 0 0 0 3px rgba(83, 74, 183, 0.12); }
.dark-mode .combo.is-open,
.dark-mode .combo:focus { box-shadow: 0 0 0 3px rgba(175, 169, 236, 0.25); }
.combo.has-error { border-color: var(--db-expense); }
.combo i.fa-search { color: var(--db-muted); font-size: 11px; flex-shrink: 0; }
/* flex: 1; min-width: 0 (Sept 2026 fix) - a flex item's default min-width
   is its content's natural width, not 0, so without this the
   overflow/text-overflow/white-space truncation below never actually
   kicks in - a long placeholder or selected value just pushes the combo
   wider or wraps instead of ellipsizing, which is exactly what was
   happening to the "Bill To" picker's placeholder text in a narrow
   160px table column. Both spans get the same treatment since either
   one can be the long text showing at any given time. */
.combo .combo-placeholder {
    color: var(--db-muted); font-size: 12.5px; opacity: .8;
    flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.combo .combo-value {
    display: flex; align-items: center; gap: 7px;
    font-size: 12.5px; font-weight: 600; color: var(--db-ink);
    flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.combo .avatar-chip {
    width: 18px; height: 18px; border-radius: 50%;
    background: var(--db-primary); color: #fff;
    font-size: 9px; font-weight: 700;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.combo .fa-chevron-down { margin-left: auto; color: var(--db-muted); font-size: 9px; flex-shrink: 0; transition: transform .12s ease; }
.combo.is-open .fa-chevron-down { transform: rotate(180deg); }
.combo-error-msg { font-size: 11px; color: var(--db-expense); margin-top: 3px; }

.combo-panel {
    position: absolute;
    top: calc(100% + 5px);
    left: 0; right: 0;
    min-width: 220px;
    background: var(--db-card-bg);
    border: 1px solid var(--db-border);
    border-radius: 9px;
    box-shadow: var(--db-shadow-md);
    z-index: 1050;
    overflow: hidden;
}
.combo-panel__search { display: flex; align-items: center; gap: 7px; padding: 7px 10px; border-bottom: 1px solid var(--db-border); }
.combo-panel__search i { color: var(--db-muted); font-size: 11px; flex-shrink: 0; }
.combo-panel__search input { border: none; outline: none; font-size: 12.5px; font-family: inherit; flex: 1; background: transparent; color: var(--db-ink); }
.combo-panel__list { max-height: 230px; overflow-y: auto; }
.combo-panel__group { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; color: var(--db-muted); padding: 6px 10px 3px; }
.combo-panel__item {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 10px; font-size: 12.5px; color: var(--db-ink); cursor: pointer;
}
.combo-panel__item:hover,
.combo-panel__item.is-focused { background: var(--db-page-bg); }
.combo-panel__item.is-selected { background: rgba(83, 74, 183, 0.07); color: var(--db-primary); font-weight: 600; }
.dark-mode .combo-panel__item.is-selected { background: rgba(175, 169, 236, 0.14); }
.combo-panel__item .avatar-chip { width: 18px; height: 18px; font-size: 9px; }
.combo-panel__item--add { color: var(--db-primary); font-weight: 600; border-top: 1px solid var(--db-border); }
.combo-panel__empty { padding: 14px 12px; font-size: 12.5px; color: var(--db-muted); text-align: center; }

/* Compact sizing when a combo sits inside an item-table cell (Quotation/
   Invoice/Bill line rows) - same widget, smaller footprint. */
table .combo { padding: 5px 8px; }
table .combo .combo-placeholder, table .combo .combo-value { font-size: 12px; }

/* -- Item table (Quotation/Invoice/Bill line rows) - this got missed on
   the first pass (Sept 2026): the table's OWN box + its "+ Add Line" /
   Subtotal footer bar were never actually styled, so that footer just
   fell back to two stacked block-level elements instead of the
   space-between row it was designed as. Filling that in now. Note the
   line-row markup deliberately does NOT carry the old id="item-table"
   hook any more (see #item-table th/td/tfoot further up this file) -
   those are legacy ID-selector rules that, being higher specificity than
   anything below, would otherwise silently win over this block's own
   padding/background on every property they both set. */
.item-table-wrap { border: 1px solid var(--db-border); border-radius: 9px; overflow: visible; }
table.item-table { width: 100%; border-collapse: collapse; font-size: 12.5px; margin-bottom: 0; }
table.item-table thead th {
    background: #f8f9fc;
    text-align: left;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .3px;
    color: var(--db-muted);
    padding: 7px 10px;
    border-bottom: 1px solid var(--db-border);
    border-top: none;
}
table.item-table thead th:first-child { border-top-left-radius: 9px; }
table.item-table thead th:last-child { border-top-right-radius: 9px; }
table.item-table td {
    padding: 5px 8px;
    border-bottom: 1px solid var(--db-border);
    border-top: none;
    vertical-align: top;
    position: relative;
}
table.item-table tbody tr:last-child td { border-bottom: none; }
.dark-mode table.item-table thead th { background: rgba(255, 255, 255, 0.03); }

.amount-cell { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; padding-top: 11px !important; }

.row-remove {
    width: 22px; height: 22px;
    border-radius: 6px;
    border: none;
    background: var(--db-expense-bg);
    color: var(--db-expense);
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    font-size: 11px;
    margin-top: 4px;
    text-decoration: none;
}
.row-remove:hover, .row-remove:focus { background: var(--db-expense); color: #fff; text-decoration: none; }

/* The bar under the table - "+ Add Line" pinned left, Subtotal pinned
   right, the two actually spread across the FULL width of the card via
   flex + space-between (this is the part that was missing). */
.item-table-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 7px 10px;
    background: #f8f9fc;
    border-top: 1px solid var(--db-border);
    border-radius: 0 0 9px 9px;
}
.dark-mode .item-table-foot { background: rgba(255, 255, 255, 0.03); }
.add-line-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px dashed var(--db-primary);
    color: var(--db-primary);
    background: rgba(83, 74, 183, 0.05);
    font-size: 11.5px;
    font-weight: 700;
    padding: 5px 10px;
    border-radius: 7px;
    cursor: pointer;
    text-decoration: none;
}
.add-line-btn:hover, .add-line-btn:focus { background: rgba(83, 74, 183, 0.1); color: var(--db-primary); text-decoration: none; }
.subtotal-readout { font-size: 12px; font-weight: 700; color: var(--db-ink); white-space: nowrap; }
.subtotal-readout span { color: var(--db-muted); font-weight: 600; margin-right: 5px; }

/* -- Custom date field (Sept 2026) - swaps the native <input type="date">
   for a plain text input + the daterangepicker plugin already loaded
   app-wide (assets/plugins/daterangepicker - see _base/foot.php), run in
   singleDatePicker mode. Direct response to feedback that the native
   browser calendar popup and its "mm/dd/yyyy" placeholder don't match
   the rest of the redesigned form - a native date input's own popup
   calendar has no CSS hook in any browser, so restyling it really does
   require swapping to a JS-rendered one; this reuses a dependency the
   app already ships rather than adding a new one. The submitted value
   format (YYYY-MM-DD) is unchanged - see the locale.format option where
   this is wired up in quotation_add.php - so nothing server-side needs
   to change. */
.date-field {
    display: flex;
    align-items: center;
    gap: 7px;
    border: 1px solid var(--db-border);
    border-radius: 8px;
    background: var(--db-input-bg);
    padding: 6px 10px;
    cursor: pointer;
}
.date-field:hover { border-color: #c9cee0; }
.dark-mode .date-field:hover { border-color: #4a525d; }
.date-field:focus-within { border-color: var(--db-primary); box-shadow: 0 0 0 3px rgba(83, 74, 183, 0.12); }
.dark-mode .date-field:focus-within { box-shadow: 0 0 0 3px rgba(175, 169, 236, 0.25); }
.date-field i { color: var(--db-muted); font-size: 12px; flex-shrink: 0; }
.date-field-input {
    border: none;
    outline: none;
    background: transparent;
    flex: 1;
    min-width: 0;
    font-size: 12.5px;
    font-family: inherit;
    color: var(--db-ink);
    cursor: pointer;
}
.date-field-input::placeholder { color: var(--db-muted); opacity: .8; }

/* daterangepicker's own dropdown - real DOM, so (unlike the native
   calendar it replaces) it can actually be themed to the Nidaam palette.
   Only visual properties are touched here; layout/structure classes are
   the plugin's own and left alone. */
.daterangepicker {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    border: 1px solid var(--db-border);
    border-radius: 10px;
    box-shadow: var(--db-shadow-md);
    background: var(--db-card-bg);
    color: var(--db-ink);
}
.daterangepicker:before, .daterangepicker:after { display: none; }
.daterangepicker .calendar-table { background: var(--db-card-bg); border: none; }
.daterangepicker th, .daterangepicker td { color: var(--db-ink); }
.daterangepicker th.month { font-weight: 700; }
.daterangepicker th.next span, .daterangepicker th.prev span { border-color: var(--db-muted); }
.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date { color: var(--db-muted); opacity: .5; background: transparent; }
.daterangepicker td.available:hover, .daterangepicker th.available:hover { background: var(--db-accent-bg); }
.dark-mode .daterangepicker td.available:hover, .dark-mode .daterangepicker th.available:hover { background: rgba(175, 169, 236, 0.14); }
.daterangepicker td.active, .daterangepicker td.active:hover { background: var(--db-primary); border-color: var(--db-primary); color: #fff; }
.daterangepicker td.today { font-weight: 700; }
.daterangepicker select.monthselect, .daterangepicker select.yearselect {
    background: var(--db-input-bg); color: var(--db-ink); border: 1px solid var(--db-border); border-radius: 6px;
}
.daterangepicker .drp-buttons { border-top: 1px solid var(--db-border); }
.daterangepicker .drp-buttons .btn { border-radius: 7px; font-size: 12.5px; font-weight: 700; padding: 5px 12px; }
.daterangepicker .applyBtn { background: var(--db-primary); border-color: var(--db-primary); }
.daterangepicker .applyBtn:hover { background: var(--db-primary-dark); border-color: var(--db-primary-dark); }
.daterangepicker .cancelBtn { background: transparent; color: var(--db-muted); border: 1px solid var(--db-border); }

/* -- Form action buttons (Sept 2026) - this got missed the same way the
   item-table footer did: the markup (.form-actions/.btn-save/.btn-cancel
   in quotation_add.php) shipped without its CSS, so both buttons fell
   back to unstyled inline text sitting on the left instead of colored,
   right-aligned buttons. Deliberately scoped to .btn-save/.btn-cancel
   only, NOT a bare .btn rule - Bootstrap's own .btn (already used
   app-wide) already supplies the base button shape/padding, and
   redefining .btn itself here would silently reskin every button in the
   app, not just these two. */
.form-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    margin: 2px 0 16px;
}
.form-actions .btn-save,
.form-actions .btn-cancel {
    padding: 7px 16px;
    font-size: 12.5px;
}
.form-actions .btn-save {
    background: linear-gradient(135deg, var(--db-primary), var(--db-primary-dark));
    border: none;
    color: #fff;
    font-weight: 700;
    box-shadow: var(--db-shadow-sm);
}
.form-actions .btn-save:hover,
.form-actions .btn-save:focus {
    filter: brightness(1.05);
    color: #fff;
    box-shadow: var(--db-shadow-md);
}
.form-actions .btn-cancel {
    background: var(--db-card-bg);
    border: 1px solid var(--db-border);
    color: var(--db-muted);
    font-weight: 700;
}
.form-actions .btn-cancel:hover,
.form-actions .btn-cancel:focus {
    background: var(--db-page-bg);
    color: var(--db-ink);
    border-color: #c9cee0;
}
.dark-mode .form-actions .btn-cancel:hover,
.dark-mode .form-actions .btn-cancel:focus { border-color: #4a525d; }

/* ==========================================================================
   Discounts (Sept 25 2026) - the number + %/$ pair used on quotation,
   invoice and bill lines and for the whole-document discount. Kept as a
   plain flex pair (not Bootstrap's .input-group) so it sits cleanly
   inside the item tables' own cell padding.
   ========================================================================== */
.discount-input-group {
    display: flex;
    align-items: stretch;
    gap: 4px;
}
.discount-input-group input.form-control {
    flex: 1 1 auto;
    min-width: 0;
}
.discount-input-group select.form-control {
    flex: 0 0 58px;
    width: 58px;
    padding-left: 6px;
    padding-right: 4px;
}
.discount-readout {
    margin-top: 4px;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--db-expense, #c0392b);
    min-height: 1em;
}

/* =========================================================================
   Apply payments to invoices / bills (Sept 2026) - see
   views/_partials/_apply_payment.php and the ".js-apply-docs" block in
   myjs.js. Uses the same card tokens as .form-card so dark mode follows.
   ========================================================================= */
.apply-docs__table { margin-bottom: 6px; }
.apply-docs__empty { font-size: 13px; margin-bottom: 6px; }
.apply-docs__table th {
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--db-muted);
    border-top: none;
    white-space: nowrap;
}
.apply-docs__table td { vertical-align: middle; }
.apply-docs__table td .badge { margin-left: 4px; font-size: 10px; }
.apply-docs__table input.apply-amt { text-align: right; max-width: 150px; margin-left: auto; }
.apply-docs__table input.apply-amt.is-invalid { border-color: #dc3545; }
.apply-docs__bar {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    padding-top: 6px;
    border-top: 1px solid var(--db-border);
}
.apply-docs__tools a { margin-right: 14px; font-size: 12.5px; font-weight: 600; }
.apply-docs__tools a i { margin-right: 4px; }
.apply-docs__summary { font-size: 13px; }
.apply-docs__error, .apply-docs__note { margin-top: 8px; font-size: 12.5px; }
.apply-docs .form-actions { margin: 12px 0 0; }

/* Paid / Partly paid / Overdue badges on invoice & bill lists. */
.pay-status { font-size: 11px; }
.pay-status--paid    { background: #28a745; color: #fff; }
.pay-status--partial { background: #17a2b8; color: #fff; }
.pay-status--unpaid  { background: #6c757d; color: #fff; }
.pay-status--overdue { background: #dc3545; color: #fff; }
.applied-list { width: 100%; margin: 8px 0 12px; }
.applied-list th { font-size: 11.5px; text-transform: uppercase; letter-spacing: .03em; color: var(--db-muted); }
.applied-list td form { display: inline; }

/* Credit Note / Supplier Credit form (Sept 2026) - views/credits/form.php */
.credit-lines th { font-size: 11.5px; text-transform: uppercase; letter-spacing: .03em; color: var(--db-muted); border-top: none; white-space: nowrap; }
.credit-lines th .opt { text-transform: none; letter-spacing: 0; font-weight: 400; }
.credit-lines td { vertical-align: middle; padding: 6px 6px; }
.credit-lines input.js-cl-restock { width: 16px; height: 16px; cursor: pointer; }
.credit-totals { margin: 14px 0 0 auto; max-width: 420px; }
.credit-totals__row { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 5px 0; font-size: 13px; }
.credit-totals__row input.credit-tax-pct { display: inline-block; width: 70px; margin: 0 4px; }
.credit-totals__row input.credit-tax-amt { display: inline-block; width: 100px; margin-left: 4px; }
.credit-totals__row--total { border-top: 1px solid var(--db-border); font-size: 14.5px; padding-top: 8px; }
.refund-card .form-card__body .row { margin-bottom: 10px; }

/* ==========================================================================
   Section home pages + "← Sales / Invoices" line (Sept 26 2026 - "Not happy
   with these tabs, create as page and make them cards ... make all like
   this"). The tab rows on Sales, Purchases and Settings pages were
   replaced by a home page of cards per section (_partials/hub.php, same
   .reports-dash-* cards as the Reports page) and this small back line
   (_partials/crumb.php) at the top of each page in the section.
   ========================================================================== */

.hub-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px 16px;
    margin-bottom: 22px;
}

.hub-top__intro {
    margin: 0;
    color: var(--db-muted);
    font-size: 0.92rem;
}

.hub-top__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.hub-top__actions .btn i {
    margin-right: 4px;
}

.nd-crumb {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 14px;
    font-size: 0.88rem;
}

.nd-crumb__back {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 12px 5px 10px;
    border: 1px solid var(--db-border);
    border-radius: 999px;
    background: var(--db-card-bg);
    color: var(--db-ink) !important;
    font-weight: 600;
    text-decoration: none !important;
    transition: border-color 0.15s ease, color 0.15s ease;
}

.nd-crumb__back i {
    font-size: 0.75rem;
    color: var(--db-muted);
    transition: transform 0.15s ease, color 0.15s ease;
}

.nd-crumb__back:hover {
    border-color: var(--db-primary);
    color: var(--db-primary) !important;
}

.nd-crumb__back:hover i {
    color: var(--db-primary);
    transform: translateX(-2px);
}

.nd-crumb__sep {
    color: var(--db-border);
}

.nd-crumb__current {
    color: var(--db-muted);
    font-weight: 500;
}

.dark-mode .nd-crumb__back {
    background: #343a40;
    border-color: #454d55;
    color: #e9ecef !important;
}

/* ==========================================================================
   Books Health Check (Sept 26 2026) - reports/health_check.php
   ========================================================================== */

.health-summary {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px 18px;
    padding: 18px 20px;
    margin-bottom: 26px;
    border-radius: var(--db-radius);
    border: 1px solid var(--db-border);
    background: var(--db-card-bg);
    box-shadow: var(--db-shadow-sm);
}
.health-summary__icon {
    width: 46px; height: 46px; border-radius: 12px; flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center; font-size: 22px;
}
.health-summary--ok .health-summary__icon { background: var(--db-income-bg); color: var(--db-income); }
.health-summary--warning .health-summary__icon { background: var(--db-neutral-bg); color: var(--db-neutral); }
.health-summary--problem .health-summary__icon { background: var(--db-expense-bg); color: var(--db-expense); }
.health-summary__body { flex: 1 1 280px; min-width: 0; }
.health-summary__title { font-size: 1.1rem; font-weight: 700; color: var(--db-ink); }
.health-summary__text { font-size: 0.88rem; color: var(--db-muted); margin-top: 2px; }
.health-summary__side { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.health-summary__time { font-size: 0.8rem; color: var(--db-muted); }
.health-summary__side .btn i { margin-right: 4px; }

.health-section__title { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; }
.health-section__title i { font-size: 0.85rem; }
.health-section__title--problem i { color: var(--db-expense); }
.health-section__title--warning i { color: var(--db-neutral); }
.health-section__title--info i { color: var(--db-primary); }
.health-section__sub { font-weight: 400; text-transform: none; letter-spacing: 0; font-size: 0.82rem; }

.health-item { padding: 16px 18px; margin-bottom: 12px; border-left: 4px solid var(--db-border); }
.health-item--problem { border-left-color: var(--db-expense); }
.health-item--warning { border-left-color: var(--db-neutral); }
.health-item--info { border-left-color: var(--db-primary); }
.health-item__head { display: flex; gap: 12px; align-items: flex-start; }
.health-item__icon { margin-top: 3px; font-size: 16px; flex: 0 0 auto; }
.health-item--problem .health-item__icon { color: var(--db-expense); }
.health-item--warning .health-item__icon { color: var(--db-neutral); }
.health-item--info .health-item__icon { color: var(--db-primary); }
.health-item__title { font-weight: 700; color: var(--db-ink); font-size: 0.98rem; }
.health-item__why { color: var(--db-muted); font-size: 0.86rem; line-height: 1.5; margin-top: 3px; max-width: 900px; }
.health-item__rows { margin: 12px 0 0 28px; border-top: 1px solid var(--db-border); }
.health-row {
    display: flex; align-items: center; gap: 12px;
    padding: 8px 0; border-bottom: 1px solid var(--db-border); font-size: 0.88rem;
}
.health-row__label { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.health-row__label a { font-weight: 600; }
.health-row__note { color: var(--db-muted); margin-left: 8px; font-size: 0.82rem; }
.health-row__amount { flex: 0 0 auto; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--db-ink); }
.health-row__go { flex: 0 0 auto; color: var(--db-border) !important; font-size: 0.75rem; }
.health-row:hover .health-row__go { color: var(--db-primary) !important; }
.health-row--more { color: var(--db-muted); font-size: 0.82rem; border-bottom: 0; }
@media (max-width: 575px) {
    .health-item__rows { margin-left: 0; }
    .health-row__note { display: block; margin-left: 0; }
}
.report-dc-note {
    display: flex; gap: 10px; align-items: flex-start;
    margin: 0 0 14px; padding: 10px 14px;
    background: #fffaf0; border: 1px solid #f1dfb6; border-radius: 10px;
    font-size: 0.85rem; color: var(--db-ink);
}
.report-dc-note i { color: var(--db-neutral); margin-top: 3px; }
@media print { .report-dc-note { display: none !important; } }
.health-item__action { margin: 10px 0 0 28px; }
.health-item__action .btn i { margin-right: 4px; }

/* ==========================================================================
   Move from QuickBooks (Sept 27 2026) - settings/quickbooks.php
   ========================================================================== */
.qb-card { padding: 4px 6px; margin-bottom: 8px; }
.qb-table { font-size: 0.86rem; }
.qb-table th { font-size: 0.74rem; text-transform: uppercase; letter-spacing: .03em; color: var(--db-muted); font-weight: 600; border-top: 0; }
.qb-table td { vertical-align: top; }
.qb-num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.qb-muted { color: var(--db-muted); font-size: 0.82rem; overflow-wrap: anywhere; }
.qb-sub td { background: var(--db-page-bg, #f7f8fa); font-weight: 600; }
.qb-new, .qb-tag {
    display: inline-block; padding: 0 6px; margin-left: 4px; border-radius: 8px;
    font-size: 0.7rem; font-weight: 600; line-height: 1.6; vertical-align: 1px;
}
.qb-new { background: var(--db-income-bg); color: var(--db-income); }
.qb-tag { background: var(--db-neutral-bg); color: var(--db-neutral); }
.qb-ok { color: var(--db-income); }
.qb-bad { color: var(--db-expense); }
.qb-go { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 26px; }
.qb-go .btn i { margin-right: 4px; }
.qb-summary { cursor: pointer; padding: 8px 6px; font-size: 0.86rem; font-weight: 600; color: var(--db-primary); }
.qb-msgs { margin-left: 0; border-top: 0; }
.qb-steps { padding-left: 20px; }
.qb-steps li { margin-bottom: 6px; }
.qb-stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.qb-stat { padding: 14px 16px; display: flex; flex-direction: column; gap: 2px; }
.qb-stat__n { font-size: 1.5rem; font-weight: 700; color: var(--db-ink); line-height: 1.1; }
.qb-stat__l { font-size: 0.82rem; color: var(--db-muted); }
.dark-mode .qb-sub td { background: #343a40; }

/* ==========================================================================
   QuickBooks-style reports (Sept 27 2026) - reports/balancesheet.php,
   profitloss.php, trialbalance.php, ledgerstatement.php, general_journal
   .php (libraries/Qb_report.php). Plain rows, headings, "Total" lines
   with a rule above, grand totals double-underlined, amounts right-aligned.
   ========================================================================== */
.qbr-filter .report-filter-bar__field .date-field { min-width: 150px; }
.qbr-filter .qbr-preset { min-width: 190px; }
.qbr-filter .btn i { margin-right: 4px; }
.report-toolbar .qbr-toolbar-right { margin-left: auto; display: inline-flex; gap: 6px; }
.report-toolbar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.qbr-note { text-align: center; font-size: 0.85rem; color: var(--db-muted); margin: -6px 0 14px; }

table.qbr-table { width: 100%; max-width: 860px; margin: 0 auto; border-collapse: collapse; font-size: 0.9rem; color: var(--db-ink); }
table.qbr-table.qbr-wide { max-width: none; }
table.qbr-table thead th { font-size: 0.74rem; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--db-muted); border-bottom: 2px solid var(--db-ink); padding: 6px 8px; white-space: nowrap; }
table.qbr-table td { padding: 5px 8px; border: 0; vertical-align: top; }
table.qbr-table .qbr-amt { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; width: 150px; }
table.qbr-table.qbr-tb .qbr-amt { width: 170px; }
table.qbr-table tr.qbr-line:hover td { background: var(--db-page-bg, #f4f6f9); }
table.qbr-table tr.qbr-line td.qbr-label a { color: inherit; }
table.qbr-table tr.qbr-line td.qbr-label a:hover { color: var(--db-primary); text-decoration: underline; }
table.qbr-table tr.qbr-sec td { font-weight: 800; letter-spacing: .02em; padding-top: 12px; }
table.qbr-table tr.qbr-subsec td { font-weight: 700; padding-top: 8px; }
table.qbr-table tr.qbr-group td { font-weight: 700; }
table.qbr-table tr.qbr-toggle { cursor: pointer; }
table.qbr-table tr.qbr-toggle .qbr-caret { width: 14px; margin-right: 4px; color: var(--db-muted); transition: transform .15s; }
table.qbr-table tr.qbr-toggle.qbr-is-collapsed .qbr-caret { transform: rotate(-90deg); }
table.qbr-table tr.qbr-group .qbr-collapsed-amt { display: none; }
table.qbr-table tr.qbr-group.qbr-is-collapsed .qbr-collapsed-amt { display: inline; }
table.qbr-table tr.qbr-total td { font-weight: 700; }
table.qbr-table tr.qbr-total td.qbr-amt { border-top: 1px solid var(--db-ink); }
table.qbr-table tr.qbr-grand td { font-weight: 800; }
table.qbr-table tr.qbr-grand td.qbr-amt { border-top: 1px solid var(--db-ink); border-bottom: 3px double var(--db-ink); }
table.qbr-table tr.qbr-grand.qbr-mid td.qbr-amt { border-bottom: 1px solid var(--db-ink); }
table.qbr-table tr.qbr-gap td { height: 14px; padding: 0; }
table.qbr-table tr.dc-error td { color: #c0392b; }
table.qbr-table tr.dc-error td a { color: #c0392b; }
table.qbr-table tr.qbr-band td { background: var(--db-page-bg, #f4f6f9); font-weight: 700; }
table.qbr-table .qbr-muted { color: var(--db-muted); }
table.qbr-table .qbr-memo { max-width: 260px; overflow-wrap: anywhere; }
table.qbr-table.qbr-register td { font-size: 0.86rem; }
table.qbr-table.qbr-register .qbr-amt { width: 115px; }
.qbr-summary { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin: 0 0 16px; }
.qbr-summary__box { border: 1px solid var(--db-border); border-radius: 10px; padding: 8px 14px; min-width: 150px; text-align: center; }
.qbr-summary__label { font-size: 0.75rem; color: var(--db-muted); text-transform: uppercase; letter-spacing: .03em; }
.qbr-summary__value { font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.dark-mode table.qbr-table tr.dc-error td, .dark-mode table.qbr-table tr.dc-error td a { color: #ff8a80; }
@media (max-width: 575px) {
    table.qbr-table { font-size: 0.82rem; }
    table.qbr-table .qbr-amt { width: auto; }
}
@media print {
    .qbr-filter, .report-toolbar, .report-toolbar-divider { display: none !important; }
    table.qbr-table tr.qbr-group .qbr-caret { display: none; }
}
.qbr-filter .report-filter-bar__fields { justify-content: flex-start; }
.qbr-filter .report-filter-bar__field { flex: 0 1 230px; }
.qbr-filter .report-filter-bar__field.qbr-field-wide { flex: 1 1 320px; max-width: 420px; }
table.qbr-table tr.qbr-neg-bal td.qbr-amt:last-child { color: #c0392b; }
table.qbr-table.qbr-journal tr.qbr-jfirst td { border-top: 1px solid var(--db-border); }

/* Printing the QuickBooks-style reports (Sept 27 2026): a row could be
   cut off at a page break (seen on a printed Journal - the first line of
   an invoice went missing between pages). Let the table flow over the
   pages instead of clipping inside its scroll box, and never split a row. */
@media print {
    .qbr-page .table-responsive { overflow: visible !important; }
    table.qbr-table tr { break-inside: avoid; page-break-inside: avoid; }
    table.qbr-table thead { display: table-header-group; }
}

/* Hide/Show button on a form section's heading (Sept 28 2026) - shared by
   the Bill (Item Details / Account Details) and Quick Expense (By Item /
   By Account); bill_add.php still carries its own identical copy. */
.section-fold-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex-shrink: 0;
    border: 1px solid var(--db-border);
    color: var(--db-muted);
    background: var(--db-input-bg);
    font-size: 11px;
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 7px;
    cursor: pointer;
    text-decoration: none;
}
.section-fold-btn:hover, .section-fold-btn:focus {
    border-color: var(--db-primary);
    color: var(--db-primary);
    background: rgba(83, 74, 183, 0.05);
    text-decoration: none;
}

/* Dashboard period filter (Sept 29 2026) - This month / Last month /
   quarters / fiscal years / custom, in place of the fixed FY chip. */
.dash-period {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    font-size: 0.8rem;
    font-weight: 600;
    padding: 4px 6px 4px 12px;
    border-radius: 999px;
    background: rgba(83, 74, 183, 0.08);
    color: var(--db-primary-dark);
    max-width: 100%;
}
.dash-period__select {
    border: 1px solid transparent;
    background: var(--db-card-bg);
    color: var(--db-ink);
    font: inherit;
    font-weight: 700;
    border-radius: 999px;
    padding: 3px 26px 3px 10px;
    cursor: pointer;
}
.dash-period__select:focus-visible, .dash-period__custom input:focus-visible, .dash-period__go:focus-visible {
    outline: 2px solid var(--db-primary);
    outline-offset: 1px;
}
.dash-period__custom { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.dash-period__custom[hidden] { display: none !important; }
.dash-period__custom input {
    font: inherit;
    font-weight: 600;
    border: 1px solid var(--db-border);
    border-radius: 8px;
    padding: 2px 6px;
    background: var(--db-card-bg);
    color: var(--db-ink);
}
.dash-period__go {
    font: inherit;
    font-weight: 700;
    border: 0;
    border-radius: 999px;
    padding: 4px 12px;
    background: var(--db-primary);
    color: #fff;
    cursor: pointer;
}
.dash-period__range { color: var(--db-muted); font-weight: 600; padding-right: 6px; }

/* System Dashboard - "All companies" overview (Sept 29 2026). One card per
   company; figures filled in by admin/company_card. */
.co-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 8px 16px; margin: 8px 0 14px; }
.co-head__title { font-size: 1.15rem; font-weight: 800; margin: 0; color: var(--db-ink); display: flex; align-items: center; gap: 8px; }
.co-head__title i { color: var(--db-primary); }
.co-head__sub { margin: 2px 0 0; font-size: 0.85rem; color: var(--db-muted); }
.co-head__link { font-size: 0.85rem; font-weight: 700; color: var(--db-primary); text-decoration: none; }
.co-head__link:hover { text-decoration: underline; }
.co-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 14px; }
@media (max-width: 420px) { .co-grid { grid-template-columns: 1fr; } }
.co-card { background: var(--db-card-bg); border: 1px solid var(--db-border); border-radius: 14px; padding: 16px 18px; display: flex; flex-direction: column; gap: 12px; min-width: 0; box-shadow: var(--db-shadow-sm); }
.co-card--active { border-color: var(--db-primary); box-shadow: 0 0 0 1px var(--db-primary) inset, var(--db-shadow-sm); }
.co-card__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.co-card__name { display: flex; flex-direction: column; min-width: 0; }
.co-card__name strong { font-size: 1rem; color: var(--db-ink); overflow-wrap: anywhere; }
.co-card__name span { font-size: 0.75rem; color: var(--db-muted); }
.co-card__badges { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
.co-badge { font-size: 0.68rem; font-weight: 700; border-radius: 999px; padding: 3px 9px; white-space: nowrap; }
.co-badge--here { background: rgba(83, 74, 183, 0.12); color: var(--db-primary); }
.co-badge--locked { background: rgba(201, 138, 31, 0.15); color: #9a5b00; }
.co-card__figs { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.co-card__figs div { background: rgba(83, 74, 183, 0.06); border-radius: 9px; padding: 8px 10px; min-width: 0; }
.co-card__figs span { display: block; font-size: 0.66rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--db-muted); }
.co-card__figs b { display: block; font-size: 0.98rem; font-weight: 800; color: var(--db-ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.co-card__figs b.is-neg { color: var(--db-expense, #d64545); }
.co-card__attn { font-size: 0.8rem; font-weight: 600; color: #9a5b00; display: flex; gap: 6px; align-items: baseline; }
.co-card__attn.is-clear { color: var(--db-income, #1e8e57); }
.co-card__foot { display: flex; justify-content: space-between; align-items: center; gap: 10px; border-top: 1px solid var(--db-border); padding-top: 10px; margin-top: auto; }
.co-card__last { font-size: 0.75rem; color: var(--db-muted); }
.co-card__last em { font-style: normal; }
.co-card__last.is-stale { color: #b3261e; font-weight: 600; }
.co-card__actions { display: flex; align-items: center; gap: 6px; }
.co-note { font-size: 0.78rem; margin-top: 12px; }

/* Dashboard: clickable Cash & Bank card and split Receivable / Payable
   tile (Sept 29 2026). */
.hero-card__label--link { color: inherit !important; text-decoration: none !important; display: inline-flex; align-items: center; gap: 6px; position: relative; z-index: 1; }
.hero-card__label--link:hover, .hero-card__label--link:focus-visible { text-decoration: underline !important; }
.hero-card__chev { font-size: 0.65rem; opacity: .7; }
.hero-accounts { position: relative; z-index: 1; margin-top: 14px; display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px; }
.hero-account { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 8px 12px; border-radius: 10px; background: rgba(255, 255, 255, 0.10); color: #fff !important; text-decoration: none !important; font-size: 0.82rem; transition: background .15s ease; min-width: 0; }
.hero-account span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: .9; }
.hero-account b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.hero-account:hover, .hero-account:focus-visible { background: rgba(255, 255, 255, 0.20); outline: none; }
.hero-account--more { justify-content: center; opacity: .85; font-weight: 600; }
.stat-tile--split .split-halves { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 6px; }
.split-half { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: 10px; border: 1px solid var(--db-border); text-decoration: none !important; color: inherit !important; min-width: 0; transition: border-color .15s ease, background .15s ease; }
.split-half:hover, .split-half:focus-visible { border-color: var(--db-primary); background: rgba(83, 74, 183, 0.05); outline: none; }
.split-half__label { font-size: 0.7rem; font-weight: 700; color: var(--db-muted); text-transform: uppercase; letter-spacing: .03em; }
.split-half__value { font-size: 1.05rem; font-weight: 800; color: var(--db-ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.split-half__note { font-size: 0.72rem; color: var(--db-muted); }
@media (max-width: 420px) { .stat-tile--split .split-halves { grid-template-columns: 1fr; } }

/* ==========================================================================
   Customer Viewer on a phone (Sept 29 2026, Deva request "mobile view
   customer viewers only"). Everything below is scoped to body.customer-viewer
   (set in MY_Controller::render()), so no other user's screens change.
   ========================================================================== */

.customer-viewer .unbilled-card { display: none; }

@media (max-width: 767px) {
    .customer-viewer .content-wrapper > .content,
    .customer-viewer section.content { padding-left: 8px; padding-right: 8px; }
    .customer-viewer .card-body { padding: 12px; }
    .customer-viewer .card-header { padding: 12px; }
    .customer-viewer .dashboard-card__title { font-size: 1.1rem; }
    .customer-viewer .content-header h1 { font-size: 1.25rem; }

    /* summary bar: 2 tiles a row, no colour strips */
    .customer-viewer .stat-bar {
        grid-template-columns: 1fr 1fr;
        gap: 8px;
        padding: 8px;
        border-radius: var(--db-radius, 8px);
        margin-bottom: 12px;
    }
    .customer-viewer .stat-bar__bar,
    .customer-viewer .stat-bar__hint,
    .customer-viewer .stat-bar__item[data-filter="unbilled"] { display: none; }
    .customer-viewer .stat-bar__item {
        margin: 0;
        padding: 10px;
        background: #fff;
        border: 1px solid var(--db-border, #e5e9f0);
        border-radius: 8px;
    }
    .customer-viewer .stat-bar__item.is-active { border-color: var(--db-primary, #2563eb); background: #eef4ff; }
    .customer-viewer.dark-mode .stat-bar__item { background: rgba(255, 255, 255, 0.04); }
    .customer-viewer .stat-bar__value { font-size: 1.05rem; }
    .customer-viewer .stat-bar__label { font-size: 0.75rem; }

    /* customers list: search on its own line, one card per customer */
    .customer-viewer .card-header .input-group { max-width: none !important; width: 100%; }
    .customer-viewer .card-header > div { width: 100%; }
    .customer-viewer #customersTable,
    .customer-viewer #customersTable tbody { display: block; width: 100%; }
    .customer-viewer #customersTable thead { display: none; }
    .customer-viewer #customersTable tbody tr {
        display: grid;
        grid-template-columns: 1fr auto;
        column-gap: 12px;
        align-items: center;
        padding: 10px 4px;
        border-bottom: 1px solid var(--db-border, #e5e9f0);
    }
    .customer-viewer #customersTable tbody tr[style*="display: none"] { display: none; }
    .customer-viewer #customersTable td { display: block; border: 0; padding: 0; background: none; }
    .customer-viewer #customersTable td:nth-child(2),
    .customer-viewer #customersTable td:nth-child(5),
    .customer-viewer #customersTable td:nth-child(6) { display: none; }
    .customer-viewer #customersTable td:nth-child(1) { grid-column: 1; grid-row: 1; min-width: 0; overflow-wrap: anywhere; }
    .customer-viewer #customersTable td:nth-child(4) { grid-column: 2; grid-row: 1 / span 2; text-align: right !important; font-weight: 700; white-space: nowrap; }
    .customer-viewer #customersTable td:nth-child(3) { grid-column: 1; grid-row: 2; font-size: 0.8rem; color: var(--db-muted, #6b7280); overflow-wrap: anywhere; }
    .customer-viewer #customersTable td[colspan] { grid-column: 1 / -1; grid-row: auto; text-align: center; }

    /* customer page: header buttons wrap, summary full width */
    .customer-viewer .card-header .btn { margin-top: 4px; }
    .customer-viewer .customer-summary-col { text-align: left !important; margin-top: 12px; }
    .customer-viewer .customer-summary-col table.summary { width: 100%; margin-left: 0 !important; }
    .customer-viewer .customer-summary-col table.summary td:last-child { text-align: right; white-space: nowrap; }
    /* Start / End Date side by side, buttons under them */
    .customer-viewer .report-filter-bar { padding: 0 0 10px; }
    .customer-viewer .report-filter-bar__fields { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 8px; }
    .customer-viewer .report-filter-bar__field { min-width: 0; }
    .customer-viewer .report-filter-bar__field .input-group-append { display: none; }
    .customer-viewer .report-filter-bar__field .form-control { border-radius: 6px !important; }
    .customer-viewer .report-filter-bar__actions .btn { flex: 1; }

    /* statement: one card per line - date + reference, then the amounts */
    .customer-viewer table.customer-statement,
    .customer-viewer table.customer-statement tbody { display: block; width: 100%; }
    .customer-viewer table.customer-statement thead { display: none; }
    .customer-viewer table.customer-statement tbody tr {
        display: block;
        padding: 10px 4px;
        border-bottom: 1px solid var(--db-border, #e5e9f0);
    }
    .customer-viewer table.customer-statement td { display: block; border: 0; padding: 0; background: none; }
    .customer-viewer table.customer-statement td:first-child { font-size: 0.78rem; color: var(--db-muted, #6b7280); }
    .customer-viewer table.customer-statement td:nth-child(2) { font-weight: 600; margin-bottom: 4px; overflow-wrap: anywhere; }
    .customer-viewer table.customer-statement td[data-label] {
        display: flex;
        justify-content: space-between;
        text-align: right !important;
        font-size: 0.9rem;
    }
    .customer-viewer table.customer-statement td[data-label]::before {
        content: attr(data-label);
        color: var(--db-muted, #6b7280);
        font-weight: 400;
        text-align: left;
    }
    .customer-viewer table.customer-statement td[data-label="Balance"] { font-weight: 700; }
    .customer-viewer table.customer-statement td.cs-empty { display: none; }
    .customer-viewer table.customer-statement td[colspan] { text-align: center; }

    /* invoice / payment / credit note pages: wide tables scroll sideways
       inside their card instead of stretching the page */
    .customer-viewer table.table:not(.customer-statement):not(#customersTable) {
        display: block;
        width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .customer-viewer table.table:not(.customer-statement):not(#customersTable) td,
    .customer-viewer table.table:not(.customer-statement):not(#customersTable) th { white-space: nowrap; }
    .customer-viewer .row > [class*="col-"] { margin-bottom: 8px; }
}

/* ==========================================================================
   Construction - Projects (Sept 29 2026, Safe Construction)
   ========================================================================== */
.prj-filter { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.prj-filter a { padding: 5px 12px; border-radius: 999px; border: 1px solid var(--db-border); font-size: 0.82rem; color: var(--db-ink); text-decoration: none; background: #fff; }
.prj-filter a span { color: var(--db-muted); margin-left: 4px; font-weight: 600; }
.prj-filter a.is-active { background: var(--db-primary); border-color: var(--db-primary); color: #fff; }
.prj-filter a.is-active span { color: rgba(255, 255, 255, 0.8); }
.prj-status { display: inline-block; font-size: 0.66rem; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase; padding: 3px 9px; border-radius: 999px; }
.prj-status--active { color: var(--db-income); background: var(--db-income-bg); }
.prj-status--on_hold { color: var(--db-neutral); background: var(--db-neutral-bg); }
.prj-status--completed { color: var(--db-primary-dark); background: rgba(83, 74, 183, 0.1); }
.prj-status--cancelled { color: var(--db-muted); background: #eef1f5; }
.prj-bar { height: 7px; border-radius: 4px; background: #eef1f5; overflow: hidden; }
.prj-bar span { display: block; height: 100%; background: var(--db-income); border-radius: 4px; }
.prj-bar--warn span { background: var(--db-neutral); }
.prj-bar--over span { background: var(--db-expense); }
.prj-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 18px; }
@media (max-width: 991px) { .prj-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .prj-tiles { grid-template-columns: 1fr; } }
.prj-budget-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 767px) { .prj-budget-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.prj-budget-total { margin-top: 10px; font-size: 0.88rem; color: var(--db-muted); }
.prj-budget-total strong { color: var(--db-ink); }
.prj-var-grid { display: grid; grid-template-columns: 130px 1fr 120px auto; gap: 6px; align-items: center; margin-top: 8px; }
@media (max-width: 575px) { .prj-var-grid { grid-template-columns: 1fr 1fr; } }
.prj-pick { min-width: 170px; }
.project-tag { display: inline-block; font-size: 0.75rem; color: var(--db-primary-dark); background: rgba(83, 74, 183, 0.08); border-radius: 6px; padding: 1px 7px; }
@media print {
    .prj-filter, .prj-var-form { display: none !important; }
}
.prj-pick--je { margin-top: 4px; height: 30px; padding: 2px 6px; font-size: 0.8rem; color: var(--db-muted); }
.prj-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 14px; border-bottom: 1px solid var(--db-border); }
.prj-tabs a { padding: 8px 14px; font-size: 0.88rem; font-weight: 600; color: var(--db-muted); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.prj-tabs a i { margin-right: 5px; }
.prj-tabs a.is-active { color: var(--db-primary); border-bottom-color: var(--db-primary); }
.prj-claim-preview { background: #f7f9fc; border: 1px solid var(--db-border); border-radius: 8px; padding: 10px 12px; font-size: 0.86rem; margin-top: 8px; }
.prj-claim-preview table { width: 100%; }
.prj-claim-preview td { padding: 2px 0; }
.prj-claim-preview td:last-child { text-align: right; white-space: nowrap; }
.prj-mini-form { display: grid; grid-template-columns: 140px 1fr 1fr auto; gap: 6px; align-items: end; }
@media (max-width: 575px) { .prj-mini-form { grid-template-columns: 1fr 1fr; } }
.prj-mini-form label { font-size: 0.72rem; font-weight: 700; color: var(--db-muted); text-transform: uppercase; margin: 0 0 3px; display: block; }
.wage-table input, .wage-table select { min-width: 70px; }

/* ==========================================================================
   Fixed top bar + Save bar (Sept 29 2026). body has layout-navbar-fixed now
   (MY_Controller), so the top bar stays in place like the sidebar. Long
   forms keep their Save / Cancel row (.form-actions) in view at the bottom
   of the window, just above the fixed footer - --nd-footer-h is measured
   by foot.php. Only the main row of a form sticks (a direct child of the
   form), not small action rows inside cards.
   ========================================================================== */
.layout-navbar-fixed .wrapper .main-header { z-index: 1034; }
form > .form-actions {
    position: sticky;
    bottom: var(--nd-footer-h, 56px);
    z-index: 20;
    background: var(--db-page-bg);
    margin: 0 -8px 12px;
    padding: 10px 8px;
    border-top: 1px solid var(--db-border);
}
.card-body form > .form-actions { background: var(--db-card-bg); }
@media print {
    form > .form-actions { position: static; border: 0; }
    .layout-navbar-fixed .wrapper .main-header { position: static; }
}

/* ==========================================================================
   Notification bell + Tasks (Sept 29 2026) - navbar.php, tasks-bell.js,
   views/tasks/*.
   ========================================================================== */
.nd-bell > .nav-link { position: relative; }
.nd-bell__badge {
    position: absolute; top: 1px; right: -2px;
    min-width: 17px; height: 17px; padding: 0 4px;
    border-radius: 999px; background: var(--db-expense); color: #fff;
    font-size: 10px; font-weight: 800; line-height: 17px; text-align: center;
    box-shadow: 0 0 0 2px var(--db-topbar-bg);
}
.nd-bell__badge[hidden] { display: none; }
.nd-bell--ring > .nav-link > .fa-bell { animation: nd-bell-ring 0.9s ease-in-out 1; transform-origin: 50% 0; }
@keyframes nd-bell-ring {
    0%, 100% { transform: rotate(0); }
    15% { transform: rotate(14deg); } 30% { transform: rotate(-12deg); }
    45% { transform: rotate(9deg); } 60% { transform: rotate(-6deg); } 75% { transform: rotate(3deg); }
}
@media (prefers-reduced-motion: reduce) { .nd-bell--ring > .nav-link > .fa-bell { animation: none; } }
.nd-bell__menu {
    width: 360px; max-width: calc(100vw - 16px); padding: 0; overflow: hidden;
    border: 1px solid var(--db-border); border-radius: 12px; box-shadow: var(--db-shadow-md);
    background: var(--db-card-bg);
}
.nd-bell__head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px 8px; color: var(--db-ink); }
.nd-bell__readall { border: 0; background: none; padding: 0; color: var(--db-primary); font-size: 0.78rem; font-weight: 600; cursor: pointer; }
.nd-bell__readall[hidden] { display: none; }
.nd-bell__summary { display: block; margin: 0 10px 6px; padding: 8px 10px; border-radius: 8px; background: var(--db-page-bg); color: var(--db-ink) !important; font-size: 0.82rem; text-decoration: none !important; }
.nd-bell__summary i { color: var(--db-primary); margin-right: 6px; }
.nd-bell__list { max-height: 340px; overflow-y: auto; }
.nd-bell__item { display: flex; gap: 10px; padding: 9px 14px; color: var(--db-ink) !important; text-decoration: none !important; border-top: 1px solid var(--db-border); font-size: 0.84rem; line-height: 1.35; }
.nd-bell__item:hover { background: var(--db-page-bg); }
.nd-bell__item small { display: block; color: var(--db-muted); font-size: 0.72rem; margin-top: 2px; }
.nd-bell__dot { flex: 0 0 8px; height: 8px; margin-top: 6px; border-radius: 50%; background: transparent; }
.nd-bell__item.is-unread { font-weight: 600; }
.nd-bell__item.is-unread .nd-bell__dot { background: var(--db-primary); }
.nd-bell__empty { padding: 22px 14px; text-align: center; color: var(--db-muted); font-size: 0.84rem; border-top: 1px solid var(--db-border); }
.nd-bell__empty i { font-size: 1.4rem; display: block; margin-bottom: 6px; opacity: 0.6; }
.nd-bell__others { display: none; border-top: 1px solid var(--db-border); }
.nd-bell__others a { display: flex; align-items: center; gap: 8px; padding: 8px 14px; font-size: 0.8rem; color: var(--db-ink) !important; text-decoration: none !important; background: var(--db-neutral-bg); }
.nd-bell__others a span { margin-left: auto; color: var(--db-primary); font-weight: 700; }
.nd-bell__foot { display: flex; justify-content: space-between; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--db-border); font-size: 0.82rem; }
.nd-bell__foot a { color: var(--db-primary); font-weight: 600; }

.task-status { display: inline-block; font-size: 0.66rem; font-weight: 800; letter-spacing: 0.03em; text-transform: uppercase; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.task-status--not_started { color: var(--db-muted); background: #eef1f5; }
.task-status--in_progress { color: var(--db-neutral); background: var(--db-neutral-bg); }
.task-status--done { color: var(--db-income); background: var(--db-income-bg); }
.task-status--overdue { color: var(--db-expense); background: var(--db-expense-bg); }
.dark-mode .task-status--not_started { background: rgba(255, 255, 255, 0.08); }
.task-table td { vertical-align: top; }
.task-snippet { font-size: 0.8rem; margin-top: 2px; }
.task-link-inline { font-size: 0.78rem; margin-top: 3px; }
.task-link-inline i { color: var(--db-muted); margin-right: 3px; }
.task-row--overdue td:first-child { box-shadow: inset 3px 0 0 var(--db-expense); }
.task-row--done strong { color: var(--db-muted); text-decoration: line-through; font-weight: 600; }
.task-overdue-note { align-self: center; margin-left: 6px; color: var(--db-expense); font-size: 0.82rem; font-weight: 700; }
.task-empty { text-align: center; padding: 34px 10px; color: var(--db-muted); }
.task-empty > i { font-size: 2rem; opacity: 0.5; display: block; margin-bottom: 8px; }
.task-meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin-bottom: 16px; }
.task-meta span { display: block; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; color: var(--db-muted); letter-spacing: 0.03em; }
.task-meta strong { color: var(--db-ink); }
.task-details { padding: 12px 14px; border-radius: 10px; background: var(--db-page-bg); color: var(--db-ink); margin-bottom: 14px; white-space: normal; }
.task-link-box { display: flex; align-items: center; gap: 12px; padding: 10px 12px; margin-bottom: 14px; border: 1px dashed var(--db-border); border-radius: 10px; }
.task-link-box > i:first-child { color: var(--db-primary); }
.task-link-box > div { flex: 1 1 auto; min-width: 0; }
.task-link-box--view { color: var(--db-ink) !important; text-decoration: none !important; }
.task-link-box--view:hover { border-color: var(--db-primary); }
.task-status-panel { border-top: 1px solid var(--db-border); padding-top: 14px; }
.task-status-choices { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 10px; }
.task-choice { display: inline-flex; align-items: center; gap: 7px; margin: 0; padding: 8px 14px; border: 1px solid var(--db-border); border-radius: 999px; cursor: pointer; font-weight: 600; font-size: 0.86rem; color: var(--db-muted); background: var(--db-card-bg); }
.task-choice input { position: absolute; opacity: 0; pointer-events: none; }
.task-choice:focus-within { outline: 2px solid var(--db-primary); outline-offset: 2px; }
.task-choice.is-current.task-choice--not_started { color: var(--db-ink); border-color: var(--db-muted); background: #eef1f5; }
.task-choice.is-current.task-choice--in_progress { color: var(--db-neutral); border-color: var(--db-neutral); background: var(--db-neutral-bg); }
.task-choice.is-current.task-choice--done { color: var(--db-income); border-color: var(--db-income); background: var(--db-income-bg); }
.dark-mode .task-choice.is-current.task-choice--not_started { background: rgba(255, 255, 255, 0.08); }
.task-reopen { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--db-border); }
.task-timeline { list-style: none; margin: 0; padding: 0; }
.task-timeline__item { position: relative; padding: 0 0 14px 18px; border-left: 2px solid var(--db-border); margin-left: 5px; }
.task-timeline__item:last-child { border-left-color: transparent; padding-bottom: 0; }
.task-timeline__item::before { content: ''; position: absolute; left: -6px; top: 3px; width: 10px; height: 10px; border-radius: 50%; background: var(--db-card-bg); border: 2px solid var(--db-muted); }
.task-timeline__item--status::before { border-color: var(--db-primary); }
.task-timeline__item--reopened::before { border-color: var(--db-expense); }
.task-timeline__head { font-size: 0.84rem; color: var(--db-ink); }
.task-timeline__note { margin-top: 4px; padding: 7px 10px; border-radius: 8px; background: var(--db-page-bg); font-size: 0.84rem; color: var(--db-ink); }
.task-timeline__when { font-size: 0.72rem; color: var(--db-muted); margin-top: 3px; }
.task-help h3 { font-size: 0.95rem; font-weight: 700; margin-bottom: 10px; }
.task-help p { font-size: 0.85rem; color: var(--db-muted); margin-bottom: 8px; }
@media (max-width: 575.98px) {
    .task-table thead { display: none; }
    .task-table, .task-table tbody, .task-table tr, .task-table td { display: block; width: 100%; }
    .task-table tr { padding: 10px 2px; border-bottom: 1px solid var(--db-border); }
    .task-table td { border: 0 !important; padding: 2px 6px !important; text-align: left !important; }
    .task-table td:last-child { padding-top: 6px !important; }
    .task-row--overdue td:first-child { box-shadow: none; }
    .task-row--overdue { box-shadow: inset 3px 0 0 var(--db-expense); }
}
