/*
 * app.css — layout + components for BaseSource.WebAppBill.
 * Consumes ONLY the variables in tokens.css. Vanilla CSS, no framework.
 */

/* ===================== Reset / base ===================== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
    margin: 0;
    font-family: 'Be Vietnam Pro', 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    font-size: 15px;
    line-height: 1.55;
    color: var(--text);
    background: var(--page-bg);
}
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { margin: 0 0 8px; font-weight: 700; color: var(--text); }
img, svg { vertical-align: middle; }
button { font-family: inherit; }

/* Visible keyboard focus everywhere. */
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }

/* Global [hidden] reset — components that set an explicit display (.bm-btn, .bm-modal-footer, grids)
   otherwise beat the UA [hidden] rule and leak hidden elements on pages without a local guard. This
   makes the attribute authoritative everywhere (the tx-detail drawer, KPI sections, 2FA modal, etc.).
   .bm-modal:not([hidden]){display:flex} still wins when the attribute is removed to open a modal. */
[hidden] { display: none !important; }

.bm-icon { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.bm-icon-sm { width: 16px; height: 16px; }

/* ===================== App shell ===================== */
.bm-app { min-height: 100vh; }

.bm-sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: var(--sidebar-width);
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
    border-right: 1px solid var(--sidebar-border);
    display: flex;
    flex-direction: column;
    z-index: 40;
    transition: transform 0.2s ease;
}
.bm-sidebar-brand {
    height: var(--topbar-height);
    display: flex;
    align-items: center;
    padding: 0 16px;
    border-bottom: 1px solid var(--sidebar-border);
}
.bm-brand-link { display: flex; align-items: center; gap: 10px; color: var(--sidebar-text); font-weight: 700; }
.bm-brand-link:hover { text-decoration: none; }
.bm-brand-logo { width: 28px; height: 28px; }
.bm-brand-text { font-size: 16px; }

.bm-sidebar-nav { flex: 1; overflow-y: auto; padding: 12px 8px; }
.bm-nav-list, .bm-nav-sublist { list-style: none; margin: 0; padding: 0; }

.bm-nav-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: var(--touch);
    padding: 8px 12px;
    margin: 2px 0;
    border: none;
    background: transparent;
    color: var(--sidebar-text);
    font-size: 14px;
    text-align: left;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.bm-nav-item:hover { background: var(--sidebar-active); text-decoration: none; color: var(--sidebar-text); }
.bm-nav-item .bm-nav-icon { width: 20px; height: 20px; flex: 0 0 20px; color: var(--sidebar-icon); fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.bm-nav-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bm-nav-item.is-active { background: var(--sidebar-active); color: #FFFFFF; font-weight: 600; }
.bm-nav-item.is-active .bm-nav-icon { color: var(--sidebar-icon); }

.bm-nav-item.is-disabled { opacity: 0.5; cursor: not-allowed; }
.bm-nav-soon {
    font-size: 11px;
    font-weight: 600;
    color: var(--sidebar-text-muted);
    background: rgba(148, 163, 184, 0.16);
    padding: 1px 6px;
    border-radius: 999px;
}

.bm-nav-caret { width: 16px; height: 16px; margin-left: auto; color: var(--sidebar-text-muted); transition: transform 0.15s ease; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.bm-nav-sublist { max-height: 0; overflow: hidden; transition: max-height 0.2s ease; padding-left: 14px; }
.bm-nav-group.is-open > .bm-nav-group-toggle .bm-nav-caret { transform: rotate(180deg); }
.bm-nav-group.is-open > .bm-nav-sublist { max-height: 600px; }
.bm-nav-subitem { font-size: 13.5px; }

.bm-sidebar-backdrop {
    position: fixed;
    inset: 0;
    background: var(--overlay);
    z-index: 39;
    border: none;
}

.bm-shell {
    margin-left: var(--sidebar-width);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* ===================== Topbar ===================== */
.bm-topbar {
    position: sticky;
    top: 0;
    height: var(--topbar-height);
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 16px;
    background: var(--topbar-bg);
    border-bottom: 1px solid var(--border);
    z-index: 30;
}
.bm-topbar-spacer { flex: 1; }
.bm-topbar-actions { display: flex; align-items: center; gap: 8px; }

.bm-icon-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--touch);
    height: var(--touch);
    border: none;
    background: transparent;
    color: var(--text);
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.bm-icon-btn:hover { background: var(--grid-line-soft); }
.bm-hamburger { display: none; }

.bm-badge-count {
    position: absolute;
    top: 6px; right: 6px;
    min-width: 16px; height: 16px;
    padding: 0 4px;
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    color: #FFFFFF;
    background: var(--danger);
    border-radius: 999px;
    text-align: center;
}

/* ===================== Dropdowns ===================== */
.bm-dropdown { position: relative; }
.bm-dropdown-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 220px;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 6px;
    display: none;
    z-index: 50;
}
.bm-dropdown.is-open > .bm-dropdown-menu { display: block; }
.bm-dropdown-menu-wide { min-width: 320px; }
.bm-dropdown-menu-right { right: 0; }

.bm-dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 40px;
    padding: 8px 10px;
    border: none;
    background: transparent;
    color: var(--text);
    font-size: 14px;
    text-align: left;
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.bm-dropdown-item:hover { background: var(--grid-line-soft); text-decoration: none; color: var(--text); }
.bm-dropdown-item-danger { color: var(--danger); }
.bm-dropdown-item-danger:hover { background: #FEF2F2; }
.bm-dropdown-divider { height: 1px; background: var(--border); margin: 6px 4px; }
.bm-logout-form { margin: 0; }

.bm-account-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: var(--touch);
    padding: 0 8px;
    border: none;
    background: transparent;
    color: var(--text);
    cursor: pointer;
    border-radius: var(--radius-sm);
}
.bm-account-btn:hover { background: var(--grid-line-soft); }
.bm-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px; height: 32px;
    background: var(--primary);
    color: #FFFFFF;
    font-weight: 700;
    border-radius: 999px;
}
.bm-account-name { font-size: 14px; font-weight: 600; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.bm-dropdown-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 10px;
    font-weight: 700;
    font-size: 13px;
    border-bottom: 1px solid var(--border);
}
.bm-dropdown-scroll { max-height: 360px; overflow-y: auto; padding: 4px; }
.bm-dropdown-empty { padding: 16px 10px; text-align: center; color: var(--text-muted); font-size: 13px; }

.bm-notif-item {
    display: block;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    color: var(--text);
}
.bm-notif-item:hover { background: var(--grid-line-soft); text-decoration: none; }
.bm-notif-item-unread { background: #EFF6FF; }
.bm-notif-title { font-weight: 600; font-size: 13.5px; }
.bm-notif-body { font-size: 12.5px; color: var(--text-muted); }

/* ===================== Content / page ===================== */
.bm-content { flex: 1; padding: 24px; }
.bm-page { max-width: 1280px; margin: 0 auto; }
.bm-page-header { margin-bottom: 16px; }
.bm-page-title { font-size: 22px; }
.bm-page-subtitle { color: var(--text-muted); margin: 0; }

.bm-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    padding: 20px;
}
.bm-help { font-size: 12.5px; color: var(--text-muted); margin: 6px 0 0; }

/* ===================== Buttons ===================== */
.bm-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: var(--touch);
    padding: 10px 16px;
    font-size: 15px;
    font-weight: 600;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    cursor: pointer;
    background: transparent;
    color: var(--text);
}
.bm-btn:hover { text-decoration: none; }
.bm-btn:disabled { opacity: 0.6; cursor: not-allowed; }
.bm-btn-block { width: 100%; }
.bm-btn-sm { padding: 6px 10px; font-size: 13px; min-height: 36px; }
/* Extra-small action button (drawer row actions, dense toolbars). Global source of truth — pages must NOT
   redefine this locally; every page loads app.css. */
.bm-btn-xs { padding: 3px 8px; font-size: 12px; min-height: 30px; }

.bm-btn-primary { background: var(--primary); color: var(--primary-contrast); border-color: var(--primary); }
.bm-btn-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); color: #FFFFFF; }

.bm-btn-ghost { background: transparent; color: var(--text); border-color: var(--border); }
.bm-btn-ghost:hover { background: var(--grid-line-soft); color: var(--text); }

.bm-btn-outline { background: transparent; color: var(--primary); border-color: var(--primary); }
.bm-btn-outline:hover { background: #EFF6FF; }

.bm-btn-danger { background: var(--danger); color: #FFFFFF; border-color: var(--danger); }
.bm-btn-danger:hover { background: #B91C1C; color: #FFFFFF; }

.bm-btn-google { background: #FFFFFF; color: var(--text); border-color: var(--border); }
.bm-btn-google:hover { background: var(--grid-line-soft); color: var(--text); }
.bm-google-icon { flex: 0 0 18px; }

/* Tint buttons: soft semantic fill + strong text/icon (icon inherits currentColor), so copy/export/action
   buttons read at a glance without a heavy solid fill. Palette matches .badge-* / .bm-alert-* (both themes
   are light, so the fixed hexes stay legible on navy and sheet). Consumed by P2 (copy) + P3 (toolbar). */
.bm-btn-tint-info    { background: #DBEAFE; color: #1E40AF; border-color: #BFDBFE; }
.bm-btn-tint-info:hover    { background: #BFDBFE; color: #1E40AF; }
.bm-btn-tint-warn    { background: #FEF3C7; color: #92400E; border-color: #FDE68A; }
.bm-btn-tint-warn:hover    { background: #FDE68A; color: #92400E; }
.bm-btn-tint-success { background: #DCFCE7; color: #166534; border-color: #BBF7D0; }
.bm-btn-tint-success:hover { background: #BBF7D0; color: #166534; }
.bm-btn-tint-danger  { background: #FEE2E2; color: #991B1B; border-color: #FECACA; }
.bm-btn-tint-danger:hover  { background: #FECACA; color: #991B1B; }

/* Loading spinner utility. */
.bm-spinner {
    width: 16px; height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.4);
    border-top-color: #FFFFFF;
    border-radius: 50%;
    animation: bm-spin 0.7s linear infinite;
}
@keyframes bm-spin { to { transform: rotate(360deg); } }

/* ===================== Forms ===================== */
.bm-field { margin-bottom: 16px; }
.bm-label { display: block; margin-bottom: 6px; font-size: 13.5px; font-weight: 600; }
.bm-input, .bm-select, .bm-textarea {
    display: block;
    width: 100%;
    min-height: var(--touch);
    padding: 10px 12px;
    /* 16px minimum prevents iOS auto-zoom on focus. */
    font-size: 16px;
    color: var(--text);
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}
.bm-input:focus, .bm-select:focus, .bm-textarea:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15); }
.bm-input.is-invalid { border-color: var(--danger); }
.bm-field-error, .field-validation-error { display: block; margin-top: 6px; font-size: 12.5px; color: var(--danger); }
/* Quick-pick chips under a field (a row of .bm-btn-outline preset buttons). Was duplicated in
   pages/transactions.css with two different margin-top values (6px / 8px); 8px is the one that was
   actually winning the cascade (later rule, equal specificity) — kept here to stay visually identical. */
.bm-quick-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }

.bm-alert { padding: 10px 14px; border-radius: var(--radius-sm); font-size: 13.5px; margin-bottom: 16px; }
.bm-alert:empty { display: none; }
.bm-alert-danger { background: #FEE2E2; color: #991B1B; border: 1px solid #FECACA; }
.bm-alert-success { background: #DCFCE7; color: #166534; border: 1px solid #BBF7D0; }
.bm-alert-warning { background: #FEF3C7; color: #92400E; border: 1px solid #FDE68A; }
/* asp-validation-summary renders a <ul>; hide bullets, keep spacing. */
.bm-alert ul { margin: 0; padding-left: 18px; }
/* Hide the summary box entirely when the form is valid (it still renders an empty <ul>). */
.validation-summary-valid { display: none; }
.field-validation-valid { display: none; }

/* ===================== Auth pages ===================== */
.bm-auth { background: var(--page-bg); }
.bm-auth-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px 16px;
}
.bm-auth-card {
    width: 100%;
    max-width: 420px;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 28px 24px;
}
.bm-auth-brand { text-align: center; margin-bottom: 20px; }
.bm-auth-logo { width: 48px; height: 48px; margin-bottom: 8px; }
.bm-auth-title { font-size: 22px; margin-bottom: 4px; }
.bm-auth-subtitle { color: var(--text-muted); margin: 0; font-size: 14px; }
.bm-auth-form { margin: 0; }
.bm-auth-divider { display: flex; align-items: center; text-align: center; color: var(--text-muted); margin: 16px 0; font-size: 13px; }
.bm-auth-divider::before, .bm-auth-divider::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.bm-auth-divider span { padding: 0 12px; }
.bm-auth-footer { margin-top: 20px; text-align: center; font-size: 13.5px; color: var(--text-muted); }
.bm-auth-footer p { margin: 6px 0; }

.bm-noaccess-text { color: var(--text); line-height: 1.7; }
.bm-noaccess-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }

/* ===================== Modal (settings + shared dialogs) ===================== */
.bm-modal {
    position: fixed;
    inset: 0;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 16px;
    z-index: 1050;
}
.bm-modal:not([hidden]) { display: flex; }
.bm-modal-backdrop { position: absolute; inset: 0; background: var(--overlay); border: none; }
.bm-modal-dialog {
    position: relative;
    width: 100%;
    max-width: 560px;
    max-height: calc(100vh - 32px);
    display: flex;
    flex-direction: column;
    background: var(--card-bg);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
.bm-modal-sm { max-width: 440px; }
/* Form-wrapped modals: a <form> wraps the body+footer, so it must be the flex column the dialog expects.
   Without this the form sizes to its content and the footer clips below the viewport (e.g. the invoice
   modal once several mốc rows are added). One rule fixes every form-wrapped modal; markup unchanged. */
.bm-modal-dialog > form { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; overflow: hidden; }
.bm-modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border);
}
.bm-modal-title { font-size: 17px; margin: 0; }
.bm-modal-body { padding: 20px; overflow-y: auto; flex: 1 1 auto; min-height: 0; }
.bm-modal-footer {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    padding: 14px 20px;
    border-top: 1px solid var(--border);
}
.bm-settings-section { margin-bottom: 20px; }
.bm-settings-section:last-child { margin-bottom: 0; }
.bm-settings-heading { font-size: 14px; margin-bottom: 10px; padding-bottom: 6px; border-bottom: 1px solid var(--grid-line-soft); }
.bm-settings-placeholder { color: var(--text-muted); font-size: 13.5px; margin: 0; }

/* ===================== Drawer + shared layer backdrop (bmDrawer) ===================== */
.bm-layer-backdrop { position: fixed; inset: 0; background: var(--overlay); z-index: 1040; }
.bm-scroll-lock { overflow: hidden; }
.bm-drawer {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(480px, 100%);
    background: var(--card-bg);
    box-shadow: var(--shadow-lg);
    z-index: 1050;
    display: flex;
    flex-direction: column;
    transform: translateX(0);
}

/* ===================== Toast ===================== */
.bm-toast-wrap {
    position: fixed;
    top: 16px; right: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    z-index: 1100;
    max-width: min(360px, calc(100vw - 32px));
}
.bm-toast {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-left: 4px solid var(--text-muted);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow);
    padding: 12px 14px;
    animation: bm-toast-in 0.2s ease;
}
@keyframes bm-toast-in { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.bm-toast-title { font-weight: 700; font-size: 13.5px; margin-bottom: 2px; }
.bm-toast-msg { font-size: 13px; color: var(--text); }
.bm-toast-success { border-left-color: var(--success); }
.bm-toast-error { border-left-color: var(--danger); }
.bm-toast-warning { border-left-color: var(--warn); }
.bm-toast-info { border-left-color: var(--primary); }

/* ===================== Table (sheet) ===================== */
.bm-table-wrap { overflow-x: auto; border: 1px solid var(--grid-line); border-radius: var(--radius); background: var(--card-bg); }
.bm-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.bm-table th, .bm-table td { padding: 8px 12px; border: 1px solid var(--grid-line); text-align: left; height: 40px; }
.bm-table thead th { position: sticky; top: 0; background: var(--page-bg); font-weight: 700; z-index: 1; }
.bm-table tbody tr:hover { background: var(--row-hover); }
.bm-table tbody tr.is-selected { background: var(--row-selected); }
.bm-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.bm-table.is-compact th, .bm-table.is-compact td { height: 34px; padding: 6px 10px; }
.money-pos { color: var(--money-pos); }
.money-neg { color: var(--money-neg); }

/* ===================== Skeleton + empty-state ===================== */
/* ===================== Pager ===================== */
.bm-pager { display: inline-flex; align-items: center; gap: 6px; }
.bm-pager-btn {
    min-width: var(--touch);
    height: var(--touch);
    padding: 0 12px;
    border: 1px solid var(--border);
    background: var(--card-bg);
    color: var(--text);
    border-radius: var(--radius-sm);
    cursor: pointer;
}
.bm-pager-btn:hover:not(:disabled) { background: var(--grid-line-soft); }
.bm-pager-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.bm-pager-info { font-size: 13.5px; color: var(--text-muted); padding: 0 6px; }

.bm-skeleton {
    display: block;
    height: 14px;
    border-radius: 6px;
    background: linear-gradient(90deg, #EEF2F7 25%, #E2E8F0 37%, #EEF2F7 63%);
    background-size: 400% 100%;
    animation: bm-shimmer 1.2s ease-in-out infinite;
}
@keyframes bm-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }
.bm-empty { padding: 40px 16px; text-align: center; color: var(--text-muted); }

/* ===================== Responsive: off-canvas sidebar under 992px ===================== */
@media (max-width: 991.98px) {
    .bm-sidebar { transform: translateX(-100%); box-shadow: var(--shadow-lg); }
    body.bm-sidebar-open .bm-sidebar { transform: translateX(0); }
    .bm-shell { margin-left: 0; }
    .bm-hamburger { display: inline-flex; }
    .bm-content { padding: 16px; }
    .bm-account-name { display: none; }
    .bm-dropdown-menu-wide { min-width: min(320px, calc(100vw - 24px)); }
}

@media (min-width: 992px) {
    /* Backdrop only meaningful for the mobile off-canvas. */
    .bm-sidebar-backdrop { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}

/* ===================== Phase 8 layout add-ons ===================== */
/* Account dropdown: Số dư + Ví summary (parity item 27). */
.bm-account-summary { padding: 10px 14px 4px; }
.bm-account-summary-row { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 3px 0; }
.bm-account-summary-row span:first-child { color: var(--text-muted); }
.bm-account-summary-row span:last-child { font-weight: 600; }
.bm-account-topup { display: inline-block; margin-top: 6px; font-size: 12.5px; font-weight: 600; }
.tabular-nums { font-variant-numeric: tabular-nums; }

/* Passive Trial-Balance banner — mounted site-wide (partner-only). */
.bm-trial-banner {
    background: #FEF2F2; border: 1px solid #FECACA; color: #991B1B;
    padding: 10px 14px; border-radius: var(--radius-sm); font-size: 13.5px; margin-bottom: 16px;
}
.bm-trial-banner a { color: #991B1B; font-weight: 700; text-decoration: underline; }

/* Xác thực hai lớp modal — self-hosted QR host. */
.bm-2fa-qr { display: flex; justify-content: center; margin: 4px 0 16px; }
.bm-2fa-qr img { border: 6px solid #fff; border-radius: 8px; box-shadow: var(--shadow-sm); }

/* Mobile: ≥16px inputs so iOS Safari does not zoom on focus. */
@media (max-width: 640px) {
    .bm-input, .bm-select, .bm-textarea { font-size: 16px; }
}
